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

没有,没有。