Android AlarmManager 和 IntentService - Marshallow 及更高版本
Android AlarmManager and IntentService - Marshallow and above
如何让 AlarmManager 与每 5 秒重复一次的 IntentService 一起工作?
是否有可能 "bypass" 1/15 分钟障碍(idle/doze 模式)?它必须一直工作(即使应用程序已关闭)。
编辑:
这里我有从 WakefulBroadcastReceiver 扩展的 AlarmReceiver 代码。
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, VidService.class);
startWakefulService(context, service);
}
public void setAlarm(Context context) {
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT) {
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 5000, alarmIntent);
} else {
if (currentapiVersion < android.os.Build.VERSION_CODES.M) {
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, 5000, alarmIntent);
} else {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 5000, alarmIntent);
}
}
}
还有我的 IntentService 的代码。
@Override
protected void onHandleIntent(@Nullable Intent intent) {
checkIncommingCall();
AlarmReceiver.completeWakefulIntent(intent);
}
很遗憾,我的服务"worked"只有一次。我在 Android 7.0 上进行了测试,所以我的问题 - setExactAndAllowWhileIdle 是否重复?
@SuppressLint("NewApi")
private static void startbyalarm(Context ctx, boolean wakeup, long nexttime) {
AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
Intent intent = new Intent(BRPing.INTENT_FILTER);
PendingIntent pi = PendingIntent.getBroadcast(ctx, intentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT){
am.set(wakeup?AlarmManager.RTC_WAKEUP:, nexttime, pi);
} else {
if (currentapiVersion < android.os.Build.VERSION_CODES.M) {
am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi);
} else {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pi);
}
}
}
尽管如此,我强烈建议不要每 5 秒唤醒一次设备!
这真的很耗电!
编辑
public class BRPing extends WakefulBroadcastReceiver {
public static final String INTENT_FILTER = "Some.Intent.Name.BRPing";
@Override
public void onReceive(Context ctx, Intent intent) {
ComponentName comp = new ComponentName(ctx.getPackageName(),
YourService.class.getName());
startWakefulService(ctx, intent.setComponent(comp));
}
}
manifest.xml:
<receiver
android:name=".BRPing"
android:exported="false">
<intent-filter>
<action android:name="Some.Intent.Name.BRPing" />
</intent-filter>
</receiver>
Is setExactAndAllowWhileIdle repetitive?
不,不是。如果您需要重复,则必须在当前警报触发时安排一个新警报。
How to make an AlarmManager to work with an IntentService which will be repeated every 5 seconds?
这是不可能的,因为当打瞌睡处于活动状态时,两次闹钟之间至少需要 15 分钟。
Is there any possibility to "bypass" the 1/15 min barrier (idle/doze mode)? It has to work all time (even if app is closed).
没有,没有。
如何让 AlarmManager 与每 5 秒重复一次的 IntentService 一起工作? 是否有可能 "bypass" 1/15 分钟障碍(idle/doze 模式)?它必须一直工作(即使应用程序已关闭)。
编辑: 这里我有从 WakefulBroadcastReceiver 扩展的 AlarmReceiver 代码。
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, VidService.class);
startWakefulService(context, service);
}
public void setAlarm(Context context) {
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT) {
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 5000, alarmIntent);
} else {
if (currentapiVersion < android.os.Build.VERSION_CODES.M) {
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, 5000, alarmIntent);
} else {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 5000, alarmIntent);
}
}
}
还有我的 IntentService 的代码。
@Override
protected void onHandleIntent(@Nullable Intent intent) {
checkIncommingCall();
AlarmReceiver.completeWakefulIntent(intent);
}
很遗憾,我的服务"worked"只有一次。我在 Android 7.0 上进行了测试,所以我的问题 - setExactAndAllowWhileIdle 是否重复?
@SuppressLint("NewApi")
private static void startbyalarm(Context ctx, boolean wakeup, long nexttime) {
AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
Intent intent = new Intent(BRPing.INTENT_FILTER);
PendingIntent pi = PendingIntent.getBroadcast(ctx, intentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT){
am.set(wakeup?AlarmManager.RTC_WAKEUP:, nexttime, pi);
} else {
if (currentapiVersion < android.os.Build.VERSION_CODES.M) {
am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi);
} else {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pi);
}
}
}
尽管如此,我强烈建议不要每 5 秒唤醒一次设备! 这真的很耗电!
编辑
public class BRPing extends WakefulBroadcastReceiver {
public static final String INTENT_FILTER = "Some.Intent.Name.BRPing";
@Override
public void onReceive(Context ctx, Intent intent) {
ComponentName comp = new ComponentName(ctx.getPackageName(),
YourService.class.getName());
startWakefulService(ctx, intent.setComponent(comp));
}
}
manifest.xml:
<receiver
android:name=".BRPing"
android:exported="false">
<intent-filter>
<action android:name="Some.Intent.Name.BRPing" />
</intent-filter>
</receiver>
Is setExactAndAllowWhileIdle repetitive?
不,不是。如果您需要重复,则必须在当前警报触发时安排一个新警报。
How to make an AlarmManager to work with an IntentService which will be repeated every 5 seconds?
这是不可能的,因为当打瞌睡处于活动状态时,两次闹钟之间至少需要 15 分钟。
Is there any possibility to "bypass" the 1/15 min barrier (idle/doze mode)? It has to work all time (even if app is closed).
没有,没有。