如何使用 AlarmManager.setInexactRepeating() 使服务保持活动状态?

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

我有一些现有的代码可以产生一个服务意图,它在后台做很多事情。此代码确实有效...

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

context.startService(serviceIntent);

我的问题是:如何更改它以使用 AlarmManager.setInexactRepeating(...) 方法?

我把上面的代码改成了这样:

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);

并且我已将这些权限添加到 AndroidManifest.xml...

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

我的理解是,这应该立即启动服务,然后每隔 10 秒尝试重新启动一次。但是这段代码不能正常工作。

使用这个新代码,服务根本无法启动,我不明白为什么。更复杂的是,调试器似乎永远不会及时附加到应用程序以查看发生了什么。

谁能看出我做错了什么?

将AlarmManager代码放在服务的onDestroy()函数下,安排服务启动如下:

    @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);

    }

并在 AutoStartServiceReceiver 中启动您的服务,如下所示:

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);
        }
    }
}

请注意,如果您从 settings-apps-running apps-your 应用手动停止服务,您的服务将不会重新启动。

您的服务没有启动,因为 AlarmManager.ELAPSED_REALTIME_WAKEUP,而它应该使用 AlarmManager.RTC_WAKEUP

如果您想 运行 每 10 秒,请记住以上 API 21 个低于 60 秒的警报间隔被四舍五入为 60 秒。

此外,考虑使用 WakefulIntentService https://github.com/commonsguy/cwac-wakeful