Reputation: 1055
Currently, I am trying to run a piece of code at a specific time. After some research, I think the correct way to go is to make usage of the AlarmManger
. The code should be executed every day at 3 am. If the phone is at 3 am shut down, the code should be executed directly after turning the phone on.
I used googled and found a lot of results. But my code isn't working correctly.
Yesterday I got a notification. The notification time was 10 pm. But in the code, the time is set to 3 am. I set up a lot of alarm manager over the time (because of testing). Could it be possible, that the triggered AlarmManager was an old one? Note: Before setting up a new AlarmManager I deleted the complete application from my phone and installed it new. (I think this will delete all set AlarmManager's?)
Okay, here is the code I am using:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 0);
calendar.add(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR, 3);
Intent _myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
_myIntent.putExtra("MyMessage","Content of the message");
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 123, _myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) MainActivity.this.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*60*24, pendingIntent);
This code will be executed on every startup of my app (inside MainActivity's
onCreate();
method).
Upvotes: 1
Views: 4908
Reputation: 21043
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time.
Inexact scheduling means the time between any two successive firings of the alarm may vary. Thats what happening in your case i guess.To overcome the exact time issue i think you should use one shot alarm.But in this case you need to reschedule it for next day. and so on. You can get a very clear understanding from the Documentation setrepeating , setInexactRepeating.
EDIT:- TO optimizing DOZE mode
In Case you are Using setAndAllowWhileIdle()
or setExactAndAllowWhileIdle()
,
Then you must read This Document which says :-
Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.
Upvotes: 4
Reputation: 119
I think this is due to the fact, that the Power Manager causes Problems with the App Actvivity.
Try using the Power Manager
PARTIAL_WAKE_LOCK
added in API level 1 int PARTIAL_WAKE_LOCK Wake lock level: Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off.
If the user presses the power button, then the screen will be turned off but the CPU will be kept on until all partial wake locks have been released.
Constant Value: 1 (0x00000001)
This is just an assumption, if it still doesnt work, could you post some Logs or more code snippets of the activity :)
Example:
//Initialize the Power Manager
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
//Create a PARTIAL_WAKE_LOCK
//This will keep the cpu running in the Background, so that the function will be called on the desired Time
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
//Check if the WackLock is held (may throw erro if you try to acquire twice)
//TRUE --> Do nothing, all good
//FALSE --> Acquire the WakeLock
if(!wl.isHeld()){
wl.acquire();
}
//*****
//You code for the repeating task goes Here
//*****
//If the Repeating task is not active, release the Lock
//Check if the WackLock is held (may throw error if you try to release a none acquired Lock)
//TRUE --> Release Lock
//FALSE --> Do nothing, all good
if(wl.isHeld()){
wl.release();
}
Upvotes: 0