iCaesar
iCaesar

Reputation: 411

Android alarm manager every week

In my android application i need to show notification to user every monday at 09.00. I using alarm manager for this. bur it doeesnt work.

Here is my code:

public void addReminder() {
    Intent alarmIntent = new Intent(this, WeeklyReminderReceiver.class);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.DAY_OF_WEEK, 2);
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    alarmManager.setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY * 7,
            PendingIntent.getBroadcast(this, 1, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}

But this code doesn't work properly. Can anyone help me with this?

Upvotes: 1

Views: 1634

Answers (2)

Opiatefuchs
Opiatefuchs

Reputation: 9870

On Android API 19 and above, setRepeating() will not be exact anymore. If you want to fire exact alarms, you have to set setExact(). If you want to have an exact repeating alarm, you´ll have to do it by yourself. For example, in that way: Create a class outside any activity where you pass the context to fire an alarm. In that way, you are independant of an activity and can add the alarm from wherever you want.

//pass the context, so you are independant from any activity
public void addReminder(Context context) {

  Intent alarmIntent = new Intent(context, WeeklyReminderReceiver.class);

  PendingIntent  pendingIntent = PendingIntent.getBroadcast(context, 0, 
            alarmIntent, PendingIntent.FLAG_ONE_SHOT);    

  AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

  Calendar calendar = Calendar.getInstance();

  calendar.set(Calendar.DAY_OF_WEEK, 2);
  calendar.set(Calendar.HOUR_OF_DAY, 9);
  calendar.set(Calendar.MINUTE, 0);
  calendar.set(Calendar.SECOND, 0);
  calendar.set(Calendar.MILLISECOND, 0);   

  alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);     

    }

Now if the alarm fires, the user have to kill it by a button press for example. And at this button press, you can set the new alarm again:

stopButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){

     yourAlarmClass.addReminder(yourContext);
   }    
});

But there are a few things to be aware of:

  1. even setExact() is not guaranteed to fire exact, it fires only as exact as the system can do, this is described in API:

The alarm will be delivered as nearly as possible to the requested trigger time.

  1. If your device will be shut down and restarted, your alarm will not be alive anymore, so you´ll have to get a Broadcast for BOOT_COMPLETED. Example:

create a BroadcastReceiver:

public class AlarmBootReceiver extends BroadcastReceiver
{

            public void onReceive(Context context, Intent intent)
            {
               yourAlarmClass.addReminder(context);
            }
}

register this in your manifest:

<receiver android:name=".AlarmBootReceiver">
    <intent-filter>
       <action android:name="android.intent.action.BOOT_COMPLETED" />
       <category android:name="android.intent.category.HOME" />
    </intent-filter>
</receiver>

and add permissions to the manifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  1. If you develop on Marshmallow and (in the future) above, you´ll have to request that permissions on runtime. But this is going beyond that thread, so if you need it, read API: http://developer.android.com/training/permissions/requesting.html

  2. You´ll have to do it with the thought that the system should not needlessly overloaded. Even this is noted in the API for setExact():

Note: only alarms for which there is a strong demand for exact-time delivery (such as an alarm clock ringing at the requested time) should be scheduled as exact. Applications are strongly discouraged from using exact alarms unnecessarily as they reduce the OS's ability to minimize battery use.

If all this examples are not working for you, than there must be another issue that you have not shown in your question. If so, come back and we´ll try to find the problem.

Upvotes: 2

user3673952
user3673952

Reputation: 987

AlarmManager's alarms will not persist trough a phone restart, that is my best guess why your code is not working based on the details you provided.

Upvotes: 0

Related Questions