How to keep a service alive using AlarmManager.setInexactRepeating()?

廉价感情. 提交于 2020-08-10 08:26:09

问题


I have some existing code that spawns a service intent which does a bunch of stuff in the background. This code does work...

Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startService(serviceIntent);

My question is: how to change this to use the AlarmManager.setInexactRepeating(...) methods?

I have changed the above code to this:

Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.putExtra("STARTED_BY", starter);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//Set up recurring alarm that restarts our service if
// it crashes or if it gets killed by the Android OS
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, serviceIntent, 0);
//am.cancel(pi);

am.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP    //wake up the phone if it's asleep
        , cal.getTimeInMillis()
        , 10000
        , pi);

And I have added these permissions to AndroidManifest.xml...

<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="com.android.alarm.permission.WAKE_LOCK"/>

My understanding is that this is supposed to start the service immediately and then try to restart it again every 10 seconds. But this code isn't working properly.

Using this new code, the service never starts at all and I cannot see why not. To complicate matters the debugger never seems to attach to the app in time to see what's going on.

Can anyone see what I'm doing wrong?


回答1:


Your service is not starting because of AlarmManager.ELAPSED_REALTIME_WAKEUP, while it should be using AlarmManager.RTC_WAKEUP

If you want to run every 10s keep in mind that above API 21 alarm intervals below 60s are rounded up to 60s.

Also, consider using WakefulIntentService https://github.com/commonsguy/cwac-wakeful




回答2:


Put AlarmManager code under onDestroy() function of service to schedule start of service as below:

    @Override
        public void onDestroy() {

    /**
             * Flag to restart service if killed.
             * This flag specify the time which is ued by
             * alarm manager to fire action.
             */
            final int TIME_TO_INVOKE = 5 * 1000; // try to re-start service in 5 seconds.

            // get alarm manager
            AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, AutoStartServiceReceiver.class);
            PendingIntent pendingIntent = PendingIntent
                .getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

            // set repeating alarm.
            alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() +
                    TIME_TO_INVOKE, TIME_TO_INVOKE, pendingIntent);

    }

And handle starting of your service in AutoStartServiceReceiver as below:

public class AutoStartServiceReceiver extends BroadcastReceiver {

    private static final String TAG = AutoStartServiceReceiver.class.getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent) {
        // check broadcast action whether action was
        // boot completed or it was alarm action.
        if (intent.getAction().equals(AppConstants.ACTION_ALARM_INTENT)) {
            context.startActivity(new Intent(context, YourActivity.class));
            // handle service restart event
            LockerServiceHelper.handleServiceRestart(context);
        }
    }
}

Kindly note that, your service will not restart if you stop it manually from settings-apps-running apps-your app.



来源:https://stackoverflow.com/questions/34789311/how-to-keep-a-service-alive-using-alarmmanager-setinexactrepeating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!