Question

I've got a question about setting alarms in the AlarmManager. I found something in the docs I didn't understand (see below). I'd like to set 10 alarms which trigger the ringer mode alternately silent and normal, all with a different trigger time. Now the device goes asleep, and becomes active again after all 10 alarms are outdated. Does the AlarmManager then immediately broadcast an alarm? Would it be only the 10th (what about the ringer mode)?

Alarm intents are delivered with a data extra of type int called Intent.EXTRA_ALARM_COUNT that indicates how many past alarm events have been accumulated into this intent broadcast. Recurring alarms that have gone undelivered because the phone was asleep may have a count greater than one when delivered.

Was it helpful?

Solution

From what I understand, when scheduling an alarm with an alarm manager, you have to provide a PendingIntent instance.

There are two Types of alarms ones that will wake up and do work even if the phone is asleep or locked and ones that will not.

Also, If you were to schedule 10 things at one time The AlarmManager will replace the existing Scheduled Pending intent with the new one, unless you were giving it different intent actions. When I use Alarms I have always used a sqlite database to queue up jobs that I wanted to execute on some schedule. From there I would schedule one alarm at a time, because they all executed the same Intent when the buzzer went ding.

The EXTRA_ALARM_COUNT extra would come into play if you had a reoccurring alarm scheduled and it went off multiple times when the users device was asleep. When the phone wakes up it will replay anything that it has queued up in the past. In this case your pending intent will fire off and have the value of how many times your Alarm was skipped because it was constructed with RTC or ELAPSED_REALTIME as the type when calling the set method.

Here is a sample of how I usually interact with the AlarmManger

protected void scheduleNext(Context context) {
    AlarmManager alarmManager = getAlarmManager();
    Intent intent = new Intent(MyIntent.ACTION_DO_WORK);
    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

    String where = Queue.SCHEDULED_DATE + "= (select min(" + Queue.SCHEDULED_DATE + ") from queue where " + Queue.COMPLETED_DATE + " is null)";
    Cursor cursor = context.getContentResolver().query(Queue.CONTENT_URI, Queue.PROJECTION, where, null, null);

    if (cursor.moveToFirst()) {
        int id = cursor.getInt(cursor.getColumnIndex(Queue._ID));
        long when = cursor.getLong(cursor.getColumnIndex(Queue.SCHEDULED_DATE));
        alarmManager.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
    }   

    cursor.close();
}

OTHER TIPS

One thing that is most unknown (mainly because the Android documentation tells that its "not used at the moment") is that the PendingIntent will not be reused if the requestCode differs. So instead create the PI with an request code of 0:

    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

You could implement a counter and do someting like:

    PendingIntent pendingIntent = PendingIntent.getService(context, counter, intent, 0); 

I know that this will work for SMS delivered/sent notifications PendingIntents, where you have the same problem: If the PendingIntent is reused and you have more than 1 outstanding notification, you will not know for which SMS it was. But chances are good that this will also work for outstanding alarm PendingIntent.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top