I am developing and android app. This app has several activities. I need the application, regardless of which activity it displays, to execute a query on the server at 2 a.m. every day. I am currently using Timer and TimerTask, as follows:
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
makePostToServer()
}
};
timer.scheduleAtFixedRate(timerTask, getDate(), 1000 * 60 * 60 * 24); // 24 h
private Date getDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, 2);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
return cal.getTime();
}
Is there a chance that for some reason a Timer launched at the start of the application will stop working?
Because the server logs do not always contain information about the executed query. It's as if it didn't happen.
Maybe there is a better way to call functions every day at 2.
Best regards
Instead of this use work manager for your need which is very efficient. In this case you can use periodic work manager.
Check out this for reference.
https://developer.android.com/topic/libraries/architecture/workmanager
Happy Coding!!
There are several APIs available to schedule tasks in Android:
Alarm Manager
Job Scheduler
GCM Network Manager
Firebase Job Dispatcher
Sync Adapter
You can find a lot of sample easily.
Related
if i am doing something like 10 * 1000, then this code is working but not with calendar.getTimeInMillis(), i need to generate PN in future based on calendar time and Alam Manger is not looking good (Checked on Android P and its not working ) as per new Android updation on background services.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 10); JobInfo info = new
JobInfo.Builder(1231, componentName).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).setOverrideDeadline(calendar.getTimeInMillis()).setMinimumLatency(calendar.getTimeInMillis()).setRequiresCharging(false).setBackoffCriteria(10 * 1000, JobInfo.BACKOFF_POLICY_LINEAR).setExtras(persistableBundle).build();
I am trying to run job scheduler a/c calendar time, but looks like its not working.
I want to show a notification every 15 minutes only between 8:00 and 16:00. Here is the code:
Calendar calendar = Calendar.getInstance();
Calendar calendarStartOfTheDay = Calendar.getInstance();
Calendar calendarEndOfTheDay = Calendar.getInstance();
calendarStartOfTheDay.set(Calendar.HOUR_OF_DAY, 8);
calendarStartOfTheDay.set(Calendar.MINUTE, 0);
calendarStartOfTheDay.set(Calendar.SECOND, 0);
calendarEndOfTheDay.set(Calendar.HOUR_OF_DAY, 16);
calendarEndOfTheDay.set(Calendar.MINUTE, 0);
calendarEndOfTheDay.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
if (alarmManager != null && calendar.getTimeInMillis() > calendarStartOfTheDay.getTimeInMillis() && calendar.getTimeInMillis() < calendarEndOfTheDay.getTimeInMillis()) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() + 15 * 60 * 1000, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
}
Is there a solution except checking the current time before notificationManager.notify()
If this is the only solution, wouldn't it drain your battery too much during the night?
This can be done by job scheduler in android. As alarm manager is outdated and
no longer used. Job scheduler also provide you with the flexibility of scheduling the task to run under specific conditions,
such as:
Device is charging
Device is connected to an unmetered network
Device is idle
Start before a certain deadline
Start within a predefined time window, e.g., within the next hour
Start after a minimal delay, e.g., wait a minimum of 10 minutes
you can follow this link to implement this
https://medium.com/google-developers/scheduling-jobs-like-a-pro-with-jobscheduler-286ef8510129
i have to download json response from web server on every night,previously i have used AlarmManager for scheduling tasks but i think for this kind of situation JobDispatcher is great because it auto perform task if network available so i don't have to manage this kind of stuf.But i have found many examples of JobDispatcher and JobScheduler in all of them a simple job is scheduled or scheduled for some time delay but there is nothing relevant to my requirements,
if anyone have idea of this please help or provide any link related to this, it will be very helpful.
UPDATE
1. How to make this to work every night,because currently it is only set alarm to midnight for once , how to make it repeted for every night at same time ?
This is how you need to schedule time-based jobs
FirebaseJobDispatcher jobDispatcher = new FirebaseJobDispatcher(
new GooglePlayDriver(this));
Calendar now = Calendar.getInstance();
Calendar midNight = Calendar.getInstance();
midNight.set(Calendar.HOUR, 12);
midNight.set(Calendar.MINUTE, 0);
midNight.set(Calendar.SECOND, 0);
midNight.set(Calendar.MILLISECOND, 0);
midNight.set(Calendar.AM_PM, Calendar.AM);
long diff = now.getTimeInMillis() - midNight.getTimeInMillis();
if (diff < 0) {
midNight.add(Calendar.DAY_OF_MONTH, 1);
diff = midNight.getTimeInMillis() - now.getTimeInMillis();
}
int startSeconds = (int) (diff / 1000); // tell the start seconds
int endSencods = startSeconds + 300; // within Five minutes
Job networkJob = jobDispatcher.newJobBuilder()
.setService(NetworkJob.class)
.setTag(NetworkJob.ID_TAG)
.setRecurring(true)
.setTrigger(Trigger.executionWindow(startSeconds, endSencods))
.setLifetime(Lifetime.FOREVER)
.setReplaceCurrent(true)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build();
jobDispatcher.schedule(networkJob);
I suggest you set your JobDispatcher to start at the next midnight, ie set the start time as the difference between now and the next midnight. Once it starts you can let it start a new Job that starts in 24 hours, ie the service will start a new Job with start time set as 24 hours and make this one recurring.
I have a service that I would like to be executed daily in my application. The service should only be executed ONCE per day. For some reason my service gets fired several times throughout the day, I do not know what is going on. Here is my alarmmanger set up:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,new Intent(this,ReviewReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
Random random = new Random();
int hour = random.nextInt(22 - 7) + 7;
int minute = random.nextInt(60 - 1) + 1;
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE,minute);
cal.set(Calendar.SECOND,5);
cal.set(Calendar.MILLISECOND,5);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),AlarmManager.INTERVAL_DAY,
pendingIntent );
I have set the alarm to randomly set itself between 7 am and 10 pm upon installation of the application.
So for example, when the alarm sets itself at 13h30, the service will be fired at that time properly. But therafter, it will get fired over and over at random intervals throughout the day. What am I doing wrong. Please help.
P.S. I have already tried using ELAPSED_TIME, ELAPSED_TIME_WAKEUP and they do not work
For Lollipop and greater (M preview also have this behavior), the alarm have a strange behavior if you don't set it in the future and at least adding 5s.
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
now + 5s,
AlarmManager.INTERVAL_DAY,
pendingIntent );
The 5s is a known issue. and since this problem occurred (especially with my nexus 5), I am just using set() that a recall every day instead of setInexactRepeating()
I am trying to execute a background process on my android app every day at around 09h10 am. This works fine, but problem is after the first alarm has been fired at 09h10 am, it gets re-fired after 10 - 20 minutes throughout the day. I just want it to fire once a day, and only at that specified time. My code that sets the alarm manager is below:
PendingIntent reviewsPendingIntent = PendingIntent.getBroadcast(this,0,new Intent(this,ReviewReceiver.class),0);
AlarmManager alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 10);
cal.set(Calendar.SECOND, 10);
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
long interval = 6000*1440;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),interval,reviewsPendingIntent);
I have set the interval to 8640000 which is a day(I believe) if not, please advise accordingly. Thank you
1000ms*60s*60m*24h = 86400000 so You missed one 0
You can use
PendingIntent reviewsPendingIntent = PendingIntent.getBroadcast(this,0,new Intent(this,ReviewReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),AlarmManager.INTERVAL_DAY,reviewsPendingIntent);
FLAG_CANCEL_CURRENT will prevent the alarm to be set multiple times
AlarmManager.INTERVAL_DAY = 1000 * 60 * 60 * 24
If you keep having some delay, it's because the sleep function is not precise. It's around the time you have set. Try with setExact and reschedule every day, doing the math by hand (initialTime + dayPassed * millsInADay) to have the best approximation.
If what Lindus has posted worked though, just forget it :) but I think that you'll have the same problem.