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
Why Do I Want to Avoid Non-Default Constructors in Fragments
How to Move the Layout Up When the Soft Keyboard Is Shown Android
Make an Android Button Change Background on Click Through Xml
Android: Using Simplecursoradapter to Get Data from Database to Listview
How to Fix Error: No Signature of Method: Build_Ap86Oam3Dut3Pxce3X49Rdtma.Android()
Android Device Manager Fails to Launch After Updating to MACos Big Sur 11.3
Further Understanding Setretaininstance(True)
Handle Button Click Inside a Row in Recyclerview
How to Show an Empty View with a Recyclerview
How to Display a List of Images in a Listview in Android
Android Recyclerview:Notifydatasetchanged() Illegalstateexception
The Import Android.Support.V7 Cannot Be Resolved
Open Soft Keyboard Programmatically
Launch Skype from an App Programmatically & Pass Number - Android