Search code examples
androidalarmmanagerandroid-6.0-marshmallowintentserviceandroid-7.0-nougat

Android AlarmManager and IntentService - Marshallow and above


How to make an AlarmManager to work with an IntentService which will be repeated every 5 seconds? 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).

EDIT: Here I have code of AlarmReceiver which extends from WakefulBroadcastReceiver.

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

And there is code of my IntentService.

    @Override
protected void onHandleIntent(@Nullable Intent intent) {
    checkIncommingCall();
    AlarmReceiver.completeWakefulIntent(intent);
}

Unfortunately, my service "worked" only once. I tested on Android 7.0 so my question - Is setExactAndAllowWhileIdle repetitive?


Solution

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

    Nonetheless, I highly recomment do not wakeup the devices each 5 seconds! This really consumes battery!

    EDIT

    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>