androidserviceandroid-serviceandroid-doze

Run application in background when phone in Doze


Application is running SDK 23 and above. I am running some tasks using Service after completing the task and scheduling the next task using AlaramManager (setExactAndAllowWhileIdle). This is working fine. If the phone is idle continuously for 2 or 3 days then its going to Doze mode. After Doze mode ,application loosing the network and wakelock also not working.

Is there way even if phone is Doze can we run the application with any network interposition issues.I tried to keep the application witelist but i needs device to be rooted.

adb shell dumpsys deviceidle whitelist +<Package Name>

Can anyone suggest me which best way to run application without interruption?


Solution

  • Edit-WakefulBroadcastReceiver is now deprecated

    Firstly, instead of directly calling a service in the AlarmManager call a broadcast receiver which then calls the service.

    The broadcast receiver should extend a WakefulBroadcastReceiver instead of a regular BroadcastReceiver.

    And then, let the broadcast receiver schedule a new Alarm, start the service using startWakefulService() instead of startService()

    public class MyAwesomeReceiver extends WakefulBroadcastReceiver {
    int interval=2*60*60*1000;
        @Override
        public void onReceive(Context context, Intent intent) {
    
            Intent serviceIntent = new Intent(context, MyAwesomeService.class);
            Intent receiverIntent = new Intent(context, MyAwesomeReceiver.class);
    
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 11, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+interval,alarmIntent);
            startWakefulService(context, serviceIntent);
            }
    }
    

    The WakefulBroadcastReceiver and startWakefulService() will let your app a 10 seconds window to let do what it needs to do.

    Also,

    You can always ask the user to let your app ignore battery optimization functionality using-

    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    Intent intent=new Intent();
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    if (powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
         intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
    }
    else {
         intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
         intent.setData(Uri.parse("package:" + getPackageName()));
         startActivity(intent);
    }
    

    and in the manifest

    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>