Android Alarmmanager - Rtc_Wakeup VS Elapsed_Realtime_Wakeup

Android AlarmManager - RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

AlarmManager.ELAPSED_REALTIME_WAKEUP type is used to trigger the alarm since boot time:

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);

will actually make the alarm go off 10 min after the device boots.

There is a timer that starts running when the device boots up to measure the uptime of the device and this is the type that triggers your alarm according to the uptime of the device.

Whereas, AlarmManager.RTC_WAKEUP will trigger the alarm according to the time of the clock. For example if you do:

long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);

this, on the other hand, will trigger the alarm 30 seconds from now.

AlarmManager.ELAPSED_REALTIME_WAKEUP type is rarely used compared to AlarmManager.RTC_WAKEUP.

What is the difference between RTC and RTC_WAKEUP of AlarmManager

Does not RTC wake up the device and fire the PendingIntent when device is in sleeping mode ?

RTC and ELAPSED_REALTIME do not wake up the device out of sleep mode. If the device is in sleep mode at the time of the event, nothing immediately happens. You will be notified about missed events when the device wakes up for other reasons (e.g., user presses the power button).

RTC_WAKEUP and ELAPSED_REALTIME_WAKEUP will wake up the device out of sleep mode. If your PendingIntent is a broadcast PendingIntent, Android will keep the device awake long enough for onReceive() to complete. If you have significant work, that you do not want to do in onReceive() (because onReceive() is called on the main application thread), you will need to arrange to keep the device awake long enough for some service of yours to complete the work, such as by using WakefulBroadcastReceiver.

difference between RTC and RTC_WAKEUP in android

Use RTC_WAKEUP if you want your service to perform some operation every 30 min as RTC_WAKEUP will wake the device up and deliver the pending intent.
On the other hand RTC will deliver the intent only when the device wakes up.

What does exactly AlarmManager.ELAPSED_REALTIME_WAKEUP do in android

I would use AlarmManager.RTC_WAKEUP as opposed to AlarmManager.ELAPSED_REALTIME_WAKEUP. Here is an example of how I was using AlarmManager in a recent app:

MainActivity.class:

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

Intent intent = new Intent(this, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

mAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);

// Cancel any existing service(s)
mAlarmManager.cancel(pendingIntent);

// Start service
long alarmTime = System.currentTimeMillis() + 10000L; // 10 seconds from now
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mAlarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else {
mAlarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
}

AlarmReceiver.class:

public class AlarmReceiver extends BroadcastReceiver {

public AlarmReceiver() { }

@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "AlarmService Triggered.", Toast.LENGTH_SHORT).show();
Log.d(this.getClass().getSimpleName(), "Service triggered");
}
}

it seems like your AlarmReceiver class was extending AppCompatActivity which won't work - you need to extend Broadcast Receiver as I have done. Then, within the onReceive() function in AlarmReceiver, you need to navigate to your desired Activity, like this:

Intent newIntent = new Intent(context, NewActivity.class);
context.startActivity(newIntent);

Try these changes and see if they work!

Android Alarm manager is repeating after 5 seconds and ignoring interval time

AlarmManager.ELAPSED_REALTIME is used to trigger the alarm since system boot time. Whereas AlarmManager.RTC uses UTC time.

 alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), interval, pendingIntent);

This will start running after system boots and repeats at the specified interval.

alarm.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), interval, pendingIntent);

This will start running from now and repeats at the specified interval.

To solve the problem, I suggest using AlarmManager.RTC. In case you want to start the alarm after 1 minute and then repeat, then pass the second param like this:

calendar.getTimeInMillis() + interval

Also check out the android documentation and this answer for more explanation in Alarms.

Android: Alarm not being triggered through AlarmManager

This part of your code seems wrong:

notificationIntent.setAction("com.example.basicalarmsetter.MatchNotification");

You're using the class name here. You need to use the action of the broadcast receiver, the one you put in your intent filter, a.k.a:

notificationIntent.setAction("com.example.notificationtest.MatchNotification");

Another issue: You're creating two alarms, which is unnecessary, at here:

AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, futureInMillis, pendingIntent);
assert alarmManager != null;
alarmManager.setExact(AlarmManager. ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);

At this section, following lines are unnecessary:

alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, futureInMillis, pendingIntent);
assert alarmManager != null;

The value RTC_WAKEUP is supposed to be used with System.currentTimeMillis(), not SystemClock.elapsedRealtime().

The final of your MainActivity.java would look like this:

package com.example.basicalarmsetter;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;

public class MainActivity extends AppCompatActivity {
private int uniqueId = 0;

// Schedules a notification in the future given the delay
@RequiresApi(api = Build.VERSION_CODES.O)
private void scheduleNotification(int matchId, long delay) {
// Construct the PendingIntent which will trigger our alarm to go off
Intent notificationIntent = new Intent();
notificationIntent.setAction("com.example.notificationtest.MatchNotification");

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), matchId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) ;
long futureInMillis = SystemClock.elapsedRealtime() + delay;

// Set off our PendingIntent
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager. ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}

// Sets an Alarm at a future specified date
@RequiresApi(api = Build.VERSION_CODES.O)
private void setAlarm(long notificationDelay) {
try {
System.out.println("Setting alarm at " + notificationDelay + " seconds");

// Sets off a notification after 5 seconds
scheduleNotification(uniqueId, notificationDelay);

uniqueId++;

} catch (Exception ex) {
System.out.println("Cannot print alarm!");
System.out.println("Exception: " + ex.toString());
}
}

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

setAlarm(15000);
}
}

How to set an alarm to fire properly at fixed time?

You are using the AlarmManager.ELAPSED_REALTIME_WAKEUP flag, but you are using a Calendar object. These two things don't go together.

You need to use AlarmManager.RTC or AlarmManager.RTC_WAKEUP if you are specifying the alarm time using a Calendar or Date object (milliseconds since 1970).

You use AlarmManager.ELAPSED_REALTIME or AlarmManager.ELAPSED_REALTIME_WAKEUP when you are specifying the alarm time via SystemClock.elapsedRealtime() (milliseconds since the phone booted).



Related Topics



Leave a reply



Submit