如何使用 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
我有一些现有的代码可以产生一个服务意图,它在后台做很多事情。此代码确实有效...
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