Frage

I am following Android developers documentation and some other tuts to create an Alarm manager which fires and wakes up the CPU at 4pm everyday, following is my code:

    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    BroadcastReceiver br;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    // Set the alarm to start at approximately 2:00 p.m.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 16);
    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, alarmIntent);
}


public void setup() {
    br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent i) {
            Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
            //Invoke the service here Put the wake lock and initiate bind service

        }
    };
    registerReceiver(br, new IntentFilter("com.testrtc") );
    alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),
            0 );
    alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}

}

Manifest:

   <uses-permission android:name="android.permission.WAKE_LOCK" />

However I dont get any errors, but the alarm (Toast message) wont fire.

EDIT from the developer docs:

RTC examples

Here are some examples of using RTC_WAKEUP.

Wake up the device to fire the alarm at approximately 2:00 p.m., and repeat once a day at the same time:

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

This one for set Repeating, says that if I want my alarm to fire at 8:30 and then repeat after each 20 minutes, however I just want to fire my alarm at a specific time but I dont want to repeat it.

Wake up the device to fire the alarm at precisely 8:30 a.m., and every 20 minutes thereafter:

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);
War es hilfreich?

Lösung

Decide how precise your alarm needs to be

Choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be. For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.

For the rare app that has rigid time requirements like yours, the alarm needs to fire precisely at 4:00 p.m. everyday then use setRepeating().

Reference: Decide how precise your alarm needs to be

Solution :

    alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Set the alarm to start at approximately 4:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 16);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000*60*60*24, alarmIntent);

Edited Testing : (Fire alarm at every 10seconds)

        alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
        1000*10, alarmIntent);

Conclusion :

setup() method was not called before dealing with alarms.


Update for API 19+

setRepeating is inexact when targeting api level 19 or higher. For exact repating you can now use setExact() and manage repeating yourself.

reference: AlarmManager documentation

Andere Tipps

Instead of using setInexactRepeating() I suggest you to use setRepeating()

from the docs,

setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

  • Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour.

setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

  • Schedule a repeating alarm.

Documentation is quite clear:

public void setInexactRepeating (...)

triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type). This is inexact: the alarm will not fire before this time, but there may be a delay of almost an entire alarm interval before the first invocation of the alarm.

so to my understanding but there may be a delay of almost an entire alarm interval means you may have one day delay, because u use AlarmManager.INTERVAL_DAY.

set minutes and seconds also to calendar ..

 calendar.set(Calendar.HOUR, 16); // At the hour you wanna fire
 calendar.set(Calendar.MINUTE, 0); // Particular minute
 calendar.set(Calendar.SECOND, 0); 

and use

  alarmManager.setRepeating(AlarmManager.RTC,
        calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
        alarmIntent);  

I had your same problem (usually is an Huawei issue) and I resolved by enabling the app in the PowerManager or Protected Apps.

Try to create a receiver that extends WakefulBroadcastReceiver:

public class MyReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        Intent myService = new Intent(context, MyService.class);
        context.startService(myService);
    }
}

In your service, you can put your toast, or try to write a log in a file to be sure that it works. Then, in your activity:

       Intent myAlarm = new Intent(context.getApplicationContext(), MyReceiver.class);
       PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
       AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
       alarms.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 4 * 1000 * 60, recurringAlarm); 

// Alarm every 4 minutes

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top