Use Alarmmanager for Android apps to perform tasks on a daily schedule

Source: Internet
Author: User

Introduced

Android Official document: Alarmmanager
On the Android platform, in addition to using Alarmmanger, you can also use a timer or handler to achieve timed tasks, but these two methods are not too accurate, so if we need to achieve precise timing tasks, it is more reasonable to use Alarmmanger.
The Alarmmanager class provides access to the system alarm Service (or timer service), which can be used to refer to the scheduled task of the order execution, or to specify the task to run repeatedly.
When the alarm clock specifies that the trigger time arrives, the system actually issues a broadcast that is registered for the alarm clock, so we need to implement a broadcast interface for a particular alarm event.
Starting with API 19, the alarm mechanism is non-accurate, and the operating system will convert the alarm to minimize wake-up and battery usage.

Note:beginning with APIs (KITKAT) Alarm delivery is inexact:the OS would shift alarms in order to minimize wakeups and Battery use. There is new APIs to support applications which need strict delivery guarantees; See SetWindow (int, long, long, pendingintent) and setexact (int, long, pendingintent). Applications whose targetsdkversion is earlier than API would continue to see the previous behavior in which all alarms is delivered exactly when requested.

Description

The code in this article is written using Kotlin, Kotlin is a programming language on the JVM that can be seamlessly interfaced with Java, developed by JetBrains, and is officially introduced:

Statically typed programming language for the JVM, Android and the browser
100% interoperable with Java?

Just realize the timing task I wrote this article, so the knowledge in this area is not fully mastered, the text may be wrong, there are opportunities to update.
This article does not post the complete sample code, just the key code, mainly the alarm settings and cancellation, as well as the interaction with the Settings section.

Regular task Implementation constants

First define several constants, including the key for the Settings section, the Requestcode for Pendingintent, and the action for intent, the code is as follows:

ConstVal Action_alarm_replenish_stock ="Witmoon.auto.replenish.stock.action"ConstVal action_alarm_synchronize ="Witmoon.auto.synchronize.action"ConstVal Alarm_replenish_stock_code = OneConstVal Alarm_synchronize_code = AConstVal key_setting_auto_synchronize ="Auto_synchronize_status"ConstVal Key_setting_synchronize_time ="Auto_synchronize_time"ConstVal Key_setting_auto_submit ="Auto_submit_status"ConstVal Key_setting_auto_submit_time ="Auto_submit_time"
Broadcastreceiver

Next is the Alarm event broadcast receiver, as the sample code is very simple, after receiving a broadcast event, first determine the action, according to different action using toast to print different content:

/** * Alarm Clock Broadcast receiver * Created by chuxin on 2016/5/4. * *Class Alarmbroadcastreceiver:broadcastreceiver () {Override fun OnReceive (Context:context, intent:intent?) {var action = intent?. Action when {action_alarm_synchronize.equals (action), dosynchronizeaction (context) ACTI On_alarm_replenish_stock.equals (Action), Doreplenishstockaction (context)}PrivateFundosynchronizeaction(Context:context?) {Toast.maketext (Context!!,"Sync", Toast.length_short). Show ()}/** * Perform supplementary inventory actions, i.e. order/orders/    PrivateFundoreplenishstockaction(Context:context?) {Toast.maketext (Context!!,"Orders", Toast.length_short). Show ()}}

Do not forget to register the receiver in the Androidmanifest.xml file:

<receiver android:name=".receiver.AlarmBroadcastReceiver">      <intent-filter>           <action android:name="witmoon.auto.replenish.stock.action"/>           <action android:name="witmoon.auto.synchronize.action"/>      </intent-filter></receiver>
Set Alarm

Since I need to set up timed tasks when the app starts, I put the code in application and reset the task execution time (once per day) in conjunction with the Settings section, which, after the settings section, only cares about setting the alarm.

Class Homedoorapplication:application () {Companion object {//Custom Delegate Implementation single casevar instance:homedoorapplication by Delegatesext.notnullsinglevalue ()} Override Fun OnCreate () {Super. onCreate () instance = This        //Start timer serviceStartalarm ()}/** * Start timer (use System alarm service) */    PrivateFunStartalarm() {var preferences = Preferencemanager.getdefaultsharedpreferences ( This)//Determine if you need to start a scheduled commit taskvar isautosubmitenable = Preferences.getboolean (Key_setting_auto_submit,true)if(isautosubmitenable) {var Hourminutearray = preferences.getstring (Key_setting_auto_submit_time,"00:00"). Split (":") Setalarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_replenish_stock_code, Action_alarm_replenish_stock) }//Determine if you need to start a scheduled synchronization taskvar isautosynchronizeenable = Preferences.getboolean (Key_setting_auto_synchronize,true)if(isautosynchronizeenable) {var Hourminutearray = preferences.getstring (Key_setting_synchronize_time,"00:00"). Split (":") Setalarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_synchronize_code, Action_alarm_synchronize)}}/** * Cancel Alarm * *Fun Cancelalarm (Requestcode:int, action:string) {var alarmmanager:alarmmanager = Getsystemservice (Context.ALARM _service) as Alarmmanager Alarmmanager.cancel (Pendingintent.getbroadcast ( This, Requestcode, Intent (action), pendingintent.flag_update_current)} fun Setalarm (Type:int, Hour:int, Minute:int,  Intervalmillis:long, Requestcode:int, action:string) {var now = Calendar.getinstance () var targettime =        Now.clone () as Calendar Targettime.set (Calendar.hour_of_day, HOUR) targettime.set (Calendar.minute, MINUTE) Targettime.set (Calendar.second,0) Targettime.set (Calendar.millisecond,0)if(Targettime.before (now)) Targettime.add (Calendar.date,1)//Easy to test, specify the instant start, execute once every 20 secondsSetalarm (Type,0, -* +, Requestcode, Action)//Setalarm (type, Targettime.timeinmillis, Intervalmillis, Requestcode, action)}/** * Set alarms * /Fun Setalarm (Type:int, Triggeratmillis:long, Intervalmillis:long, Requestcode:int, action:string) {var AlarmM Anager:alarmmanager = Getsystemservice (context.alarm_service) as Alarmmanager alarmmanager.setrepeating (type, trig Geratmillis, Intervalmillis, Pendingintent.getbroadcast ( This, Requestcode, Intent (action), Pendingintent.flag_update_current)}}

This code is actually set up at the same time two scheduled tasks, automatic submission of orders and automatic synchronization, in order to make it easier to read the code, we can only see one of them.
In the Startalarm method, I first read the settings of the Settings section, determine whether to start the alarm clock, if the setting value is true, then read the set task execution time, the time format is a few minutes per day (for example, 22:30 means every night 10:30).
After the read time is split into hours and minutes, call the Setalarm method, which includes the alarm type, first trigger time, task interval, and Requestcode and action In this method, I use the split hour and minute to find the number of milliseconds at that point in time (if the time is before the current time, that is, the trigger time is past, then this time tomorrow), call the Setalarm overloaded method.
In the Setalarm overloaded method, build the Pendingintent object and set the alarm.

Set up

First look at the final setup interface

This article does not introduce the settings part of the content, but only the logic of re-setting the task execution time.
For Settings part of Android, please refer to the official documentation: Settings

Settings.xml

Set the interface XML file, which used a custom preference to select the time, in order not to appear too messy this part of the code is no longer posted.

<?xml version= "1.0" encoding= "Utf-8"?><preferencescreen xmlns:android="Http://schemas.android.com/apk/res/android" >    <preferencecategory android:title="Sync">        <switchpreference  androi D:defaultvalue  = "true"  android:key  = "auto_synchronize_status"  android:summary  =
     
       "Automatically synchronizes data with server"  
      android:title  =
       automatic synchronization" /> 
             <com.witmoon.homedoor.ui.preference.TimePickPreferenceandroid:defaultvalue="22:30 "android:key="auto_synchronize_time "android:summary="22:30 per day "  Android:title="Commit time"/>                                                    </preferencecategory>    <preferencecategory android:title="Order">        <switchpreference  androi D:defaultvalue  = "true"  android:key  = "auto_submit_status"  android:summary  =" will automatically submit out of stock orders at a specified point in time " android:title  =" auto-submit Order "/>         <com.witmoon.homedoor.ui.preference.TimePickPreferenceandroid:defaultvalue="23:30 "android:key="auto_submit_time "android:summary="daily 23:30 "android: Title="Commit time"/>                                                    </preferencecategory></preferencescreen>
Settingfragment

The settings section uses Preferencefragment, After 3.0 The official recommends using preferencefragment instead of preferenceactivity, define the settingfragment and place it in a normal activity.

Class Settingfragment:preferencefragment (), Sharedpreferences.onsharedpreferencechangelistener {override fun OnCrea Te (savedinstancestate:bundle?) {Super. OnCreate (Savedinstancestate) Addpreferencesfromresource (r.xml.setting)} override Fun Onresume () {Super. Onresume () PreferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener ( This)} Override Fun OnPause () {Super. OnPause () PreferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener ( This)    }//settings Change responseOverride Fun Onsharedpreferencechanged (sharedpreferences:sharedpreferences., key:string) {when {Key_ Setting_auto_synchronize.equals (Key), onautosynchronizechanged (Sharedpreferences, key) Key_setting_synchro Nize_time.equals (Key), onsynchronizetimechanged (Sharedpreferences, key) Key_setting_auto_submit.equals (key ), onautosubmitchanged (Sharedpreferences, key) Key_setting_auto_submit_time.equals (key), Onsubmittime Changed (Sharedpreferences, Key)}}PrivateFunonsubmittimechanged(Preferences:sharedpreferences, key:string) {//Cancel Scheduled TasksHomeDoorApplication.instance.cancelAlarm (Alarm_replenish_stock_code, Action_alarm_replenish_stock) var Hourminutearray = Preferences?. GetString (Key_setting_auto_submit_time,"00:00")!!. Split":") HomeDoorApplication.instance.setAlarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_replenish_stock_code, Action_alarm_replenish_stock)}PrivateFunonsynchronizetimechanged(Preferences:sharedpreferences, key:string) {//Cancel Scheduled TasksHomeDoorApplication.instance.cancelAlarm (Alarm_synchronize_code, Action_alarm_synchronize)//Set timed Tasksvar Hourminutearray = preferences?. GetString (Key_setting_synchronize_time,"00:00")!!. Split":") HomeDoorApplication.instance.setAlarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_synchronize_code, Action_alarm_synchronize)}//Auto-Submit order settings change, enable to bind alarm, disable to cancel alarm    PrivateFunonautosubmitchanged(Preferences:sharedpreferences, key:string) {var isautosubmit = preferences?. Getboolean (Key,true)!!if(Isautosubmit) {preferencescreen.findpreference (key_setting_auto_submit_time). IsEnabled =truevar Hourminutearray = preferences?. GetString (Key_setting_auto_submit_time,"00:00")!!. Split":") HomeDoorApplication.instance.setAlarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_replenish_stock_code, Action_alarm_replenish_stock) }Else{preferencescreen.findpreference (key_setting_auto_submit_time). IsEnabled =false            //Cancel Scheduled TasksHomeDoorApplication.instance.cancelAlarm (Alarm_replenish_stock_code, Action_alarm_replenish_stock)}}PrivateFunonautosynchronizechanged(Preferences:sharedpreferences, key:string) {var isautosynchronize = preferences?. Getboolean (Key,true)!!if(isautosynchronize) {preferencescreen.findpreference (key_setting_synchronize_time). IsEnabled =true            //Set timed Tasksvar Hourminutearray = preferences?. GetString (Key_setting_synchronize_time,"00:00")!!. Split":") HomeDoorApplication.instance.setAlarm (Alarmmanager.rtc_wakeup, hourminutearray[0].toint (), hourminutearray[1].toint (), Alarmmanager.interval_day, Alarm_synchronize_code, Action_alarm_synchronize)}Else{preferencescreen.findpreference (key_setting_synchronize_time). IsEnabled =false            //Cancel Scheduled TasksHomeDoorApplication.instance.cancelAlarm (Alarm_synchronize_code, Action_alarm_synchronize)}}}

The Sharedpreferences.onsharedpreferencechangelistener interface is used to listen for changes to the settings items, as can be seen from the code, if the automatic task is turned off, the call to cancel the alarm, if the task is reset the time, the alarm is canceled, and then the new time to re- The new alarm is set. Both the cancellation and the settings are defined in the previous application, which is simply called.

Use Alarmmanager for Android apps to perform tasks on a daily schedule

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.