Android Alarm Setup Issues

Source: Internet
Author: User

Android development, Alarmmanager in more than 5.0 system, startup time setting invalid problemto make an app, you need to keep sending the heartbeat pack in the background. The heartbeat packet thread is suspended because the CPU hibernation after the lock screen, so try to send the heartbeat package using the Alarmmanager timed wake-up service.
Here is the code to open Alarmmanager
//turn on polling service     Public Static voidStartpollingservice (Context context,intSeconds, class<?>cls,string Action) {        //Get Alarmmanager System ServicesAlarmmanager Manager =(Alarmmanager) context. Getsystemservice (Context.alarm_service); //packaging needs to perform service intentIntent Intent =NewIntent (context, CLS);        Intent.setaction (action); Pendingintent pendingintent= Pendingintent.getservice (Context, 0, intent, pendingintent.flag_update_current); //start time of the triggering service        LongTriggerattime =Systemclock.elapsedrealtime (); //Use the Setrepeating method of Alarmmanger to set the time interval (seconds seconds) for periodic execution and the service that needs to be performedmanager.setrepeating (Alarmmanager.elapsed_realtime, triggerattime, seconds* 1000, pendingintent); }

And it turned out to be a strange problem.
The incoming time is 2500, that is, every 2.5 seconds.
On the red meter 1s (system is CM12.1 android5.1.1), it takes several 10 seconds to wake up the screen (not hibernate), the lock screen (hibernation) will not wake up
On the Xiaomi 4 (System is MIUI7 android4.4.4), the state of the screen is normal, the lock screen will not wake up
I tried Broadcastreceiver rewrite onreceive, also tried the service rewrite Onstartcommand, are the same situation

The reason for this is that Android Alarmmanagerservice has a repeating alarm limit.Note : In19 or later, thesetrepeating is set in the recommended value, The minimum value in the source code above 5.0 is 60s
classAlarmmanagerserviceextendsSystemservice {//Minimum Alarm recurrence intervalPrivate Static Final Long  min_interval =   -* 1000;//One minute, in MillisvoidSetimpl (intTypeLongTriggerattime,LongWindowlength,Longinterval, pendingintent operation,BooleanIsstandalone, WorkSource WorkSource, Alarmmanager.alarmclockinfo alarmclock) {        if(Operation = =NULL) {SLOG.W (TAG,"Set/setrepeating ignored because there is no intent"); return; }        //sanity Check the window length. This would catch people mistakenly//trying to pass an End-of-window timestamp rather than a duration.        if(Windowlength >alarmmanager.interval_half_day) {SLOG.W (TAG,"Window Length" +Windowlength+ "Ms suspiciously long; Limiting to 1 hour "); Windowlength=Alarmmanager.interval_hour; }        //sanity Check the recurrence interval. This would catch people who supply//seconds when the API expects milliseconds.        if(Interval > 0 &&interval< min_interval) {SLOG.W (TAG,"Suspiciously short interval" +interval+ "Millis; Expanding to "+ (int) (min_interval/1000)        + "Seconds"); interval = Min_interval; }       ...        }}

modification of Alarmmanager mechanism above API19

API19 before the Alarmmanager provides three ways to set the alarm clock, because the business needs alarm clock only need one-time, so the use of set (int type,long starttime,pendingintent pi);
Starting with API 19, the Alarmmanager mechanism is non-accurate, and the operating system will convert the alarm to minimize wake-up and battery usage.

In the previous program, no API19 above the alarm set to do processing, resulting in more than 4.4 of the phone set alarm clock is not responding (the application has not been killed in the case there is no alarm).

As a result, setting the alarm will need to be processed separately according to the version of the API. The code is as follows:

Alarmmanager am = (Alarmmanager) getactivity (). Getsystemservice (Context.alarm_service); if (Build.VERSION.SDK_INT >= build.version_codes. KITKAT) {    am.setexact (alarmmanager.rtc_wakeup, Timeutils        . Stringtolong (Recordtime, Timeutils.no_second_ FORMAT), sender);} Else {    am.set (alarmmanager.rtc_wakeup, Timeutils        stringtolong (Recordtime, Timeutils.no_second_format), sender);}

more than 5.0 of Jobscheduler

About 5.0 New Jobscheduler The API can read this article first. Here
Here to use more than 5.0 Jobscheduler to create a timed task, timed to detect the existence of the alarm clock service, do not exist to restart the alarm service. (Here I set every minute to detect the alarm service)

Detect if the current system is above 5.0 when entering the application, and if yes, start the Jobscheduler service. The code is as follows:

if(Build.VERSION.SDK_INT >=Build.version_codes. LOLLIPOP) {Mjobscheduler=(Jobscheduler) Getsystemservice (Context.job_scheduler_service); Jobinfo.builder Builder=NewJobinfo.builder (job_id,NewComponentName (Getpackagename (), Jobschedulerservice.class. GetName ())); Builder.setperiodic (60 * 1000);//run once every 60 secondsBuilder.setrequirescharging (true); Builder.setpersisted (true);//whether to re-execute the task after setting the device restartBuilder.setrequiresdeviceidle (true); if(Mjobscheduler.schedule (Builder.build ()) <= 0) {        //If something goes wrong    }}

One of the builder.setpersisted (true); The method is whether the task is re-executed after the device restarts, in which the task can be restarted.

The above operation further ensures that the service is restarted after the alarm is killed. However, in more than 6.0 introduced the doze mode, when more than 6.0 of the mobile phone into this mode, it will make Jobscheduler stop working.

6.0 above doze mode processing

In order to allow Jobscheduler to enter the Doze mode at more than 6.0, there is a special treatment for more than 6.0 of the Doze mode- ignoring battery optimization .

  1. Adding Permissions in Manifest.xml

    1. <android:name= "Android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"  />
  2. When setting the alarm clock, determine whether the system is more than 6.0, if so, then determine whether to ignore the battery optimization. Determine whether to ignore the battery optimization code as follows:

    @TargetApi (build.version_codes. M)publicstaticboolean== (powermanager) activity          if (Pm.isignoringbatteryoptimizations (PackageName)) {     returntrue;} Else {     returnfalse;}}

  3. If the battery optimizer is not ignored, a pop-up reminder dialog box prompts the user to ignore battery optimizer actions. The code is as follows:
    1. /*** for doze mode above n * *@paramActivity*/ Public Static voidisignorebatteryoption (activity activity) {if(Build.VERSION.SDK_INT >=Build.version_codes. M) {Try{Intent Intent=NewIntent (); String PackageName=Activity.getpackagename (); PowerManager pm=(PowerManager) Activity.getsystemservice (Context.power_service); if(!pm.isignoringbatteryoptimizations (PackageName)) {//intent.setaction (settings.action_ignore_battery_optimization_settings);intent.setaction (settings.action_request_ignore_battery_optimizations); Intent.setdata (Uri.parse ("Package:" +PackageName));         Activity.startactivityforresult (Intent, Request_ignore_battery_code); }     } Catch(Exception e) {e.printstacktrace (); } }}
  4. The interface overrides the Onactivityresult method to capture the user's choice. For example, the code is as follows:
  5. @Overrideprotected voidOnactivityresult (intRequestcode,intResultCode, Intent data) { if(ResultCode = =RESULT_OK) {     if(Requestcode = =Batteryutils.request_ignore_battery_code) {         //TODO Something     } }Else if(ResultCode = =result_canceled) {     if(Requestcode = =Batteryutils.request_ignore_battery_code) {Toastutils.show (Getactivity (),"Please turn on ignore battery optimization ~"); } }}

Supplement

When the application is killed, but the alarm service is not killed, then the alarm is set. This means that the alarm set is not placed in the alarm service. So in this case, the alarm set will expire. To resolve this situation, reset the alarm by invoking the alarm service's reset alarm method using the Aidl (alarm service is required for interprocess communication in another process).

Start the alarm service in the application's Oncreat () method, and then bind the alarm service.

Private voidInitalarmservice () {StartService (NewIntent ( This, Daemonservice.class));//Start Alarm Service    if(Build.VERSION.SDK_INT >=Build.version_codes. LOLLIPOP) {//Jobscheduler        ...    } //Binding Alarm ServiceIntent Intent =NewIntent ( This, Daemonservice.class); Intent.setaction ("Android.intent.action.DaemonService"); Bindservice (Intent, mconnection, context.bind_auto_create);}

In the OnDestroy () method, call the alarm service to reset the alarm method. The code is as follows:

@Overrideprotected voidOnDestroy () {Super. OnDestroy (); Try{//determine if there is an alarm clock, no turn off the alarm serviceString alarm =localpreferenceshelper.getstring (Localpreferenceshelper.alarm_clock); if(Daemonservice! =-1 && miremoteservice! =NULL) {//android.os.Process.killProcess (daemonservice);Miremoteservice.resetalarm (); }        if(!alarm.equals ("[]")) {            if(Daemonservice! =-1) {StartService (NewIntent ( This, Daemonservice.class)); }        } Else {            if(Build.VERSION.SDK_INT >=Build.version_codes.            LOLLIPOP) {mjobscheduler.cancel (job_id); }} unbindservice (Mconnection); //unbind the service. }Catch(Exception e) {}}

This explains that Unbindservice does not stop the service when the service is started and bound. You can view this article specifically. Here

Android Alarm Setup Issues

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.