I'm writing the application and I want to send information to server in every 10 second. Firstly I was using the Timer and TimerTask, but it wasn't good choice because when I asleeped the device I wasn't work good. So now I want to try using AlarmManager but I have a problem when I want to set repeat
void startRepeatingSend() {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MainReceiver.class); // odbiornik
intent.setAction("com.example.marcin.sbdintheroom.CYCLE");
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, 5000, alarmIntent);
}
I set the intervalMillis on 5 seconds, but my receiver receive broadcast only one time per minute
You can delay you application with Thread.sleep(miliseconds);
try {
Thread.sleep(1000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt(); // interupt thread when error
// handle error
}
Related
In my application I have a button that sets a determined time to run the AlarmManager, and I need to show how much time is left for the alarm in one TextView, how can I do that?
NOTE: My app need to work in API 15.
Button that starts the AlarmManager:
// Alarm manager
Intent intent = new Intent(getActivity().getApplicationContext(), AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity().getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
buttonsTimer.get(0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+42000000, pendingIntent);
}
});
Use a variable to store the start time:
long startTime = SystemClock.elapsedRealtime()+42000000;
Then to find the time remaining on the alarm, just subtract the current time from the start time:
long timeRemaining= startTime - System.currentTimeMillis();
This will make timeRemaining contain the time left before the alarm goes off, in milliseconds. Then just set that to a TextView with setText().
I'm trying to write a service that will check every midnight for new data from the server and will download it.
But when i start the app the mainActivity screen reloads after few seconds.
I'v checed it and it happens because of this service,
Why is this happening?
Her are the files:
MainActivity: i'v created an AlarmManager object to set pendingIntent:
//Set alarm
/* Retrieve a PendingIntent that will perform a broadcast */
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReciever.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 1000 * 24 * 60 * 60;
/* Set the alarm to start at 10:30 AM */
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 00);
calendar.set(Calendar.MINUTE, 00);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
AlarmReciever:
public class AlarmReciever extends BroadcastReceiver {
private Data newData = null;
public SharedPreferences settings;
ConnectivityManager cm = null;
NetworkInfo netInfo = null;
#Override
public void onReceive(Context context, Intent intent) {
newData = new Data(context);
// TODO Auto-generated method stub
newData.cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
newData.netInfo = newData.cm.getActiveNetworkInfo();
newData.settings = PreferenceManager.getDefaultSharedPreferences(context);
// System.out.print("-----------------" + newData.netInfo);
newData.checkOnline();
}
}
Data.java:
public void checkOnline(){
if (isOnline()){
System.out.print("**************** YES Internet");
firstAsyncTask task = new firstAsyncTask(this);
try {
Object dobj = task.execute("par1", "par 2", "par 3").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}else{
System.out.print("**************** NO Internet");
}
}
The data.java file is to big to post in here, but it seems that the "checkOnline" method in in causing the app to reload the MainActivity page, should i send the service differently?
Thanx for reading & answering.
Looks like you have written this line by mistake
pendingIntent = PendingIntent.getService(getApplicationContext(), 0, alarmIntent, 0);
It should be like this
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
Because you are using BroadcastReciever.
Causes the following line network access?
Object dobj = task.execute("par1", "par 2", "par 3").get();
If so then the system might kill your process (ether for networking on main thread or for event loop timeout aka. ANR). And eventually restart it again if its a service.
In your Activity you do this:
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
This causes the BroadcastReceiver to be triggered immediately, since you have specified System.currentTimeMillis() as the time to trigger the first time.
You probably mean to use calendar.getTimeInMillis() as the first time to trigger the alarm. But even if you change it to that, it will still trigger immediately because you've set the time in your calendar to 00:00 of the current day, which has already passed! You need to either use calendar.getTimeInMillis() + interval (which would be 00:00 of the following day, or you can add 1 day to your calendar before using calendar.getTimeInMillis().
I have no idea on where to start but I have made the GUI for my app and need to make things happen based upon the variables I have stored in a SharedPreferences that are based on the Day of the week and time, I would just like to know some of the best ways I can make things happen in the background based on date and time, thank you.
To run things in background, you need a Service
public class MyService extends Service {
#Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
// parse the intent and run your things
return START_NOT_STICKY;
}
}
To to things automatically on specific time, you need AlarmManager
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context
.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, BlockchainService.class);
// customize your intent
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
alarmIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, your_specific_time, pendingIntent);
Start service and prevent sleep
Related answer AlarmManager not working in sleep mode
I'm trying out alarms and have hit a wall. I don't think my alarm is setting up properly because I never get a confirmation after the alarm is supposed to go off. Here's how I call on the alarm manager:
long alarmtime=new GregorianCalendar().getTimeInMillis()+10*1000;//run after 10 seconds
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
AlarmManager alarmman = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmman.cancel(pi); // cancel any existing alarms
alarmman.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
alarmtime, 10 * 1000, pi);//run every 10 seconds
And here's my AlarmReceiver.java:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "TEST", Toast.LENGTH_LONG).show();
}
}
However, the TEST text does not appear, and I can't figure out why.
Since you are using the AlarmManager.ELAPSED_REALTIME_WAKEUP argument, your initial alarm-time should be base on the elapsed real time of the device:
long alarmtime = SystemClock.elapsedRealtime() + 10 * 1000;
alarmman.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmtime, 10 * 1000, pi);
(see this link).
For a BroadcastReceiver it's probably PendingIntent.getBroadcast() instead of PendingIntent.getService(). You are also cancelling the alarm, just update your PendingIntent like this and try not cancelling before:
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Read the documentation thoroughly for further information.
Make sure that the BroadcastReceiver is being called by doing a System.out.println("TEST"); instead of Toast. If you are able to see that in your logcat, then the problem probably is that you need to run the Toast in UI thread.
I followed the instructions in this thread to create a daily alarm that starts a service at 12:30 each day which shows a notification. The problem I'm having is that setting the alarm also triggers the service (=> and the notification) every time the app starts.
Since I figured that the alarm will run only at the specified time (12:30) then I have no problem setting it when the app starts.
I realize that setting the alarm from scratch every time the app is launched is a bit ineffective since it only needs to be set once (I made it set on device boot as well), but it seemed like the easiest way.
So what's the best way to fix this? is there a way to set the alarm for the specified time without running the intent when setting?
Here's the code if you are interested (this function is called every time when launching the app):
public static void setAlarm(Context context)
{
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("com.Rani.app.SET_NOTIFICATION_ALARM");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar dailyCheckTime = Calendar.getInstance();
dailyCheckTime.setTimeZone(TimeZone.getTimeZone("GMT"));
dailyCheckTime.set(Calendar.HOUR_OF_DAY, 12);
dailyCheckTime.set(Calendar.MINUTE, 30);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, dailyCheckTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
thanks in advance.
After trying several things, I used the information in this thread to preform a check if an alarm already exists, and setting one only if there isn't one already.
code:
public static void setAlarm(Context context)
{
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("com.Rani.app.SET_NOTIFICATION_ALARM");
boolean alarmUp = (PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_NO_CREATE) != null);
// check if an alarm already exists
if (alarmUp == false)
{
// set an alarm in case there isnt one already set
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar dailyCheckTime = Calendar.getInstance();
dailyCheckTime.set(Calendar.HOUR_OF_DAY, 12);
dailyCheckTime.set(Calendar.MINUTE, 30);
if (dailyCheckTime.getTimeInMillis() < Calendar.getInstance()
.getTimeInMillis()) {
dailyCheckTime.set(Calendar.DATE,
dailyCheckTime.get(Calendar.DATE) + 1);
}
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
dailyCheckTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
}