0

I want to set an alarm to check the server for getting new data everyday at 7 AM , 12 AM and 10 PM.
I tried this way :

 public void startAlarm(Context context) {
        AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, ShowNotificationReceiver.class);
        PendingIntent alarmIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);


        Calendar firstTurn = Calendar.getInstance();
        Calendar secondTurn = Calendar.getInstance();
        Calendar thirdTurn = Calendar.getInstance();

        // set times
        firstTurn.set(Calendar.HOUR_OF_DAY,FIRST_TURN_HOUR);
        firstTurn.set(Calendar.MINUTE,FIRST_TURN_MINUTE);
        secondTurn.set(Calendar.HOUR_OF_DAY,SECOND_TURN_HOUR);
        secondTurn.set(Calendar.MINUTE,SECOND_TURN_MINUTE);
        thirdTurn.set(Calendar.HOUR_OF_DAY,THIRD_TURN_HOUR);
        thirdTurn.set(Calendar.MINUTE,THIRD_TURN_MINUTE);

        alarmMgr.cancel(alarmIntent);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, secondTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, thirdTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
    }  

If i comment 2 last line its work correctly and fire in time , but it doesnt work if i want all of them .
Where is my mistake and how can i fix this ?

YFeizi
  • 1,498
  • 3
  • 28
  • 50
  • Why does it have to be fired at those specific time? You can set the alarm to fire every 8 hours - equal to 3 times a day – Kise Jul 22 '15 at 05:33
  • I want to say that using the same pending intent causes it to "overwrite" the previous settings; but I can't find docs to support that ATM. I'd try creating new pending intents w/different `REQUEST_CODE` values and see if that works. – QuinnG Jul 22 '15 at 05:34
  • Its important that user see this messages at this time , those time i said are example and maybe change in future – YFeizi Jul 22 '15 at 05:34

3 Answers3

2

If you simply want it to repeat three times a day you can register it to trigger every 8th hour (As 24 hours divided by 8 is 3).

alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTurn.getTimeInMillis(), AlarmMAnager.INTERVAL_HOUR * 8, alarmIntent);

The reason your code isn't working is because any call to setInexactRepeating will cancel any previous call with an identical PendingIntent. From the documentation:

If there is already an alarm scheduled for the same IntentSender, it will first be canceled.

If you want to perform the operation three times a day but not at every 8th hour, you could instead trigger one alarm at the first turn using AlarmManager.setExact() (i.e., without repeat). Once that alarm is triggered (i.e., onReceive() is called in your receiver) you simply call AlarmManager.setExact() with the second turn and so on.

Erik Hellman
  • 529
  • 4
  • 11
  • 1
    Thanks for your answer , i want the exact time , i found an idea with your explain – YFeizi Jul 22 '15 at 05:51
  • You should be aware that AlarmManager will not the exact time and that all repeating alarms since API level 19 are inexact. Even on API level below 19 you are not guaranteed to receive it at the exact minute you set. If you want to be sure to get the exact time, you need to use AlarmManager.setExact() and then register a new alarm after you have been triggered. – Erik Hellman Jul 22 '15 at 06:03
1

After some search and playing more with code i resolve my problem in this way :

public void startAlarm(Context context) {

        AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, ShowNotificationReceiver.class);

        Calendar firstTurn = Calendar.getInstance();
        Calendar secondTurn = Calendar.getInstance();
        Calendar thirdTurn = Calendar.getInstance();

        // set times
        firstTurn.set(Calendar.HOUR_OF_DAY, FIRST_TURN_HOUR);
        firstTurn.set(Calendar.MINUTE, FIRST_TURN_MINUTE);
        PendingIntent alarmIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);


        secondTurn.set(Calendar.HOUR_OF_DAY, SECOND_TURN_HOUR);
        secondTurn.set(Calendar.MINUTE, SECOND_TURN_MINUTE);
        PendingIntent alarmIntent2 = PendingIntent.getBroadcast(context, REQUEST_CODE2, intent, PendingIntent.FLAG_CANCEL_CURRENT);


        thirdTurn.set(Calendar.HOUR_OF_DAY, THIRD_TURN_HOUR);
        thirdTurn.set(Calendar.MINUTE, THIRD_TURN_MINUTE);
        PendingIntent alarmIntent3 = PendingIntent.getBroadcast(context, REQUEST_CODE3, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        alarmMgr.cancel(alarmIntent);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, secondTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent2);
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, thirdTurn.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent3);
    }

As explained in this answer

If you want to set multiple alarms (repeating or single), then you just need to create their PendingIntents with different requestCode. If requestCode is the same, then the new alarm will overwrite the old one.

Community
  • 1
  • 1
YFeizi
  • 1,498
  • 3
  • 28
  • 50
0

Try to create 3 different AlarmManager objects for your approach. Also, you could instead trigger each alarm after the end of another alarm, inside your BroadcastReceiver

Murillo Ferreira
  • 1,423
  • 1
  • 16
  • 31
  • 2
    You can't create an AlarmManager. The instance you get from `context.getSystemService(Context.ALARM_SERVICE);` is a singleton. – Erik Hellman Jul 22 '15 at 05:59