AlarmManager profile

AlarmManager essence is a global timer, is one of the commonly used in Android system level prompt Service, within a specified time or periodically launch other components (including the Activity, Service, BroadcastReceiver). This article shows you how to use AlarmManager to implement periodic alerts.

The alarm clock configuration

The alarm clock cycle

Intent intent = new Intent();
intent.setAction(GlobalValues.TIMER_ACTION_REPEATING);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5 * 1000.3 * 1000, sender);Copy the code
setRepeating(int type,long startTime,long intervalTime,PendingIntent pi)Copy the code

This method is used to set a scheduled service that executes periodically. Type: indicates the type of the alarm. StartTime: indicates the time when the alarm is executed for the first time. IntervalTime: indicates the interval between two executions of the alarm.

setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi)Copy the code

This method is also used to set up the periodic schedule service, similar to the previous one. However, the interval between the two alarms is not fixed. It is relatively power-efficient because the system may combine several similar alarms into one, reducing the number of times the device wakes up.

IntervalTime built-in variable

Interval one day: INTERVAL_DAY Half a day: INTERVAL_HALF_DAY Fifteen minutes: INTERVAL_FIFTEEN_MINUTES Half an hour: INTERVAL_HALF_HOUR One hour: INTERVAL_HOUR

Timing alarm clock

// Obtain the object of the system-provided AlarmManager service
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// The Intent sets the component to start
Intent myIntent = new Intent();
myIntent.setAction(GlobalValues.TIMER_ACTION);
PendingIntent sets the intent to start an Activity, Service, or broadcast.
PendingIntent sender = PendingIntent.getBroadcast(context, 0, myIntent,0);
// Register the alarm clock
alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5 * 1000, sender);Copy the code
set(int type,long startTime,PendingIntent pi)Copy the code

This method is used to set the one-time timing service. Type: indicates the alarm type. StartTime: indicates the alarm execution time. PI: indicates the alarm response action.

Cancel the alarm clock

Intent myIntent = new Intent();
myIntent.setAction(GlobalValues.TIMER_ACTION);
//myIntent.setAction(GlobalValues.TIMER_ACTION_REPEATING);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, myIntent,0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(sender);Copy the code

Set multiple alarms:

If multiple alarms are set consecutively, only the last alarm will take effect. How do we handle this situation? It’s really simple. We can give each alarm a unique ID, passing the getBroadcast() second argument. In this case, I increment each ID by 1 and store it in Shareprefrence to keep the ID unique.

 // Set a different ID for each alarm to prevent overwriting
int alarmId = SharedPreUtils.getInteger(context, "alarm_id".0);
SharedPreUtils.setInteger(context, "alarm_id", ++alarmId);
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, myIntent, 0);Copy the code

We can also turn off different alarms based on this ID when canceling the alarm.

Parameters,

Type: indicates the alarm clock type

ELAPSED_REALTIME: Sends a broadcast after the specified delay, but does not wake up the device (the alarm clock is not available during sleep). If the alarm is triggered while the system is asleep, it will not be delivered until the next device wakes up. ELAPSED_REALTIME_WAKEUP: After the specified delay, a broadcast is sent and the device is awakened (the corresponding component of operation is executed even after shutdown). Delay is to put the system startup time SystemClock elapsedRealtime () into account. RTC: Specifies the device to start operation when the system.CurrentTimemillis () method returns a value equal to triggerAtTime (at the specified time, broadcast, but not wake up the device). If the alarm is triggered while the system is asleep, it will not be delivered until the next device wakes up (the alarm is not available while asleep). RTC_WAKEUP: Specifies the device to start operation when the system.currentTimemillis () method returns a value equal to triggerAtTime (at the specified time, broadcast and wake up the device). Operation components are executed even if the system is shut down. POWER_OFF_WAKEUP: indicates that the alarm clock can alert normally even when the phone is turned off. Therefore, it is one of the most used states among the five states. In this state, the alarm clock also uses absolute time and the state value is 4. However, this status seems to be affected by the SDK version, some versions are not supported.

Long intervalTime: execution time

The first execution time of the alarm, in milliseconds. You can customize the time, but generally use the current time. Note that this attribute is closely related to the first attribute (type). If the first parameter corresponds to an alarm clock that uses a relative time (ELAPSED_REALTIME and ELAPSED_REALTIME_WAKEUP), then this attribute uses a relative time (relative to the system startup time). Such as the current time is expressed as: SystemClock. ElapsedRealtime (); If the first parameter corresponds to an alarm clock that uses absolute time (RTC, RTC_WAKEUP, POWER_OFF_WAKEUP), then this property must use absolute time. For example, the current time is: system.currentTimemillis ()

Long startTime: indicates the interval

For periodic timing, this attribute is used to indicate the interval between two alarms, also in milliseconds.

PendingIntent PI: Executes the action

Are the actions of the alarm clock, such as sending a broadcast, giving a hint, etc. PendingIntent is an Intent wrapper class. PendingIntent (Context C,int I,Intent Intent,int J); PendingIntent (Context C,int I,Intent Intent,int J); If it is done by radio alarm prompt, PendingIntent object access should adopt PendingIntent. GetBroadcast (Context c, int, Intent Intent, int j) method; If it is with the method of the Activity to realize the alarm prompt, PendingIntent object access should adopt PendingIntent. GetActivity (Context c, int, Intent Intent, int j) method. If these three methods are used incorrectly, although the error will not be reported, but can not see the alarm prompt effect.

Radio configuration

New alarm BroadCastReceiver:

public class AlarmReceiver extends BroadcastReceiver {
    private NotificationManager m_notificationMgr = null;
    private static final int NOTIFICATION_FLAG = 3;
    @Override
    public void onReceive(Context context, Intent intent) {
        m_notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVIC
        if (intent.getAction().equals(GlobalValues.TIMER_ACTION_REPEATING)) {
            Log.e("alarm_receiver"."Periodic alarm clock");
        } else if (intent.getAction().equals(GlobalValues.TIMER_ACTION)) {
            Log.e("alarm_receiver"."Timer alarm clock");
                        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.logo);
            Intent intent1 = new Intent(context, WriteDiaryActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent1, 0);
            Notification notify = new Notification.Builder(context)
                    .setSmallIcon(R.drawable.logo) // Set a small image in the status bar. The recommended size is 24 x 24
                    .setLargeIcon(bitmap) // You can also set the big icon here
                    .setTicker("Family Calendar") // Set the prompt text to display
                    .setContentTitle("Family Calendar") // Set the display title
                    .setContentText("You have a diary reminder.") // The details of the message
                    .setContentIntent(pendingIntent) / / associated PendingIntent
                    .setNumber(1) // The number displayed on the right side of the TextView. You can define a variable externally. Click add setNumber(count) to display the sum
                    .getNotification(); // Note that build() is added in API Level16 and later. In API11 you can use getNotificatin()
            notify.flags |= Notification.FLAG_AUTO_CANCEL;
            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIF
            manager.notify(NOTIFICATION_FLAG, notify);
            bitmap.recycle(); / / recycling bitmap}}}Copy the code

Registered BroadCastReceiver:

Finally, don’t forget to sign up for broadcasts on the list.

<! -- Alarm clock receives broadcast -->
<receiver android:name=".util.service.AlarmReceiver">
    <intent-filter>
        <action android:name="com.e_eduspace.TIMER_ACTION_REPEATING" />
        <action android:name="com.e_eduspace.TIMER_ACTION" />
    </intent-filter>
</receiver>Copy the code

The attachment

Constants:

public class GlobalValues {
    // Periodic alarm clock
    public final static String TIMER_ACTION_REPEATING = "com.e_eduspace.TIMER_ACTION_REPEATING";
    // Timer alarm clock
    public final static String TIMER_ACTION = "com.e_eduspace.TIMER_ACTION";
}Copy the code

Utility class

package com.e_eduspace.familycalendar.util;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

import com.prolificinteractive.materialcalendarview.CalendarDay;

/** * Alarm clock timing tools **@author xulei
 * @time2016/12/13 10:03 * /

public class AlarmTimer {

    /** * Set periodic alarm **@param context
     * @param firstTime
     * @param cycTime
     * @param action
     * @paramAlarmManagerType Alarm type. The value is as follows: Alarmmanager.elapsed_realtime, * alarmManager.elapsed_realtime_wakeup, alarmManager.rtc, and * AlarmManager. RTC_WAKEUP, AlarmManager. POWER_OFF_WAKEUP * /
    public static void setRepeatingAlarmTimer(Context context, long firstTime,
                                              long cycTime, String action, int AlarmManagerType) {
        Intent myIntent = new Intent();
        myIntent.setAction(action);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, myIntent, 0);
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarm.setRepeating(AlarmManagerType, firstTime, cycTime, sender);
        // Param1: indicates the type of the alarm. Param1: indicates the first execution time of the alarm. Param1: indicates the interval between the two executions of the alarm.
    }

    /** * Set timer alarm **@param context
     * @param cycTime
     * @param action
     * @paramAlarmManagerType Alarm type. The value is as follows: Alarmmanager.elapsed_realtime, * alarmManager.elapsed_realtime_wakeup, alarmManager.rtc, and * AlarmManager. RTC_WAKEUP, AlarmManager. POWER_OFF_WAKEUP * /
    public static void setAlarmTimer(Context context, long cycTime,
                                     String action, int AlarmManagerType, CalendarDay date) {
        Intent myIntent = new Intent();
        // Pass the timing date
        myIntent.putExtra("date", date);
        myIntent.setAction(action);
        // Set a different ID for each alarm to prevent overwriting
        int alarmId = SharedPreUtils.getInteger(context, "alarm_id".0);
        SharedPreUtils.setInteger(context, "alarm_id", ++alarmId);
        PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, myIntent, 0);
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarm.set(AlarmManagerType, cycTime, sender);
    }

    /** * Cancel the alarm **@param context
     * @param action
     */
    public static void cancelAlarmTimer(Context context, String action) {
        Intent myIntent = new Intent();
        myIntent.setAction(action);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, myIntent,0); AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarm.cancel(sender); }}Copy the code