1

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).

Samir Bhatt
  • 3,041
  • 2
  • 25
  • 39
MyNewName
  • 1,035
  • 2
  • 18
  • 34
  • Instead of using alaram manager have you tried storing date and time in sharepreference if that date and time is diffrent from current day date and time you can run ur code and store new date and time instead of old one.. – Lokesh Desai Dec 05 '17 at 10:07
  • @LokeshDesai but how can I get the basic `AlarmManager` working? Currently it's not firing at 3 pm. And to realize you idea, it need to fire at a specific time, that is given in the shared preferences. – MyNewName Dec 05 '17 at 10:11
  • yes you are right with my idea it will run on specific time but it will run accurately – Lokesh Desai Dec 05 '17 at 10:15
  • For your question that when you switch on phone you want to directly run that code you need to implement BroadCastReceiver – Lokesh Desai Dec 05 '17 at 10:17
  • I have implemented an `BroadcastReceiver`. I tested it several times. It's working. `Intent _myIntent = new Intent(MainActivity.this, AlarmReceiver.class);` – MyNewName Dec 05 '17 at 10:20

2 Answers2

4

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.

ADM
  • 20,406
  • 11
  • 52
  • 83
  • The alarm should be excact. A few minutes should be no problem, but a few hours is a problem. So I will create a new alarm every time the alarm is getting fired. And the first alarm will be created on the first application start. **On more question**. What happens with a fired alarm? Will it be deleted? Do I need to delete it when it getting fired? – MyNewName Dec 05 '17 at 10:31
  • Single Shot alarm will be auto deleted once fired(One shot life span) . You have to read the documentation for more clarity on the best way to do. I have given my opinion. – ADM Dec 05 '17 at 10:34
  • Okay, I solved it be resetting the single shot alarm when it gets fired. You helped me alot thanks! – MyNewName Dec 05 '17 at 12:07
  • How did you do that, can you please paste some example code here? – Mahabub Karim Apr 23 '19 at 12:14
0

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();
 }
  • 1
    My main problem is that the `AlarmManager` is not firing at the given time. I have no idea how `PowerManager` could help me? Can you be a bit more specific? Of course I can show you more code, but it's not necessary. That's the only interesting code. – MyNewName Dec 05 '17 at 10:18