Android DOZE mode, how to deal with it..

Android is launching new versions with cool features and many changes that Android developer should be updated with.

If you are updated with new versions you must have heared about DOZE mode.

Android 6.0 introduced Doze, a system mode that saves battery by deferring apps’ CPU and network activities when the device is idle.

Now in Android 7.0, Doze takes a step further and saves battery while on the go. Any time the screen is off for a period of time and the device is unplugged, Doze applies a subset of the familiar CPU and network restrictions to apps. This means users can save battery even when carrying their devices in their pockets.

Doze applies the full CPU and network restrictions on AlarmManager alarms.

So how to deal with this situation?Dont worry just follw below steps.

Step 1:

Extend Your Alarm Broadcast Receiver class with WakefulBroadcastReceiver.

public class AlarmBroadCastReceiver extends WakefulBroadcastReceiver

Step 2:

Note:If you have to start a IntentService from receiver then follow Example B else follow Example A

Example A :Acquire wakelock — do your work such as create notification ,etc-release wakelock

public class AlarmBroadCastReceiver extends WakefulBroadcastReceiver
{
private PowerManager.WakeLock screenWakeLock;
@Override
public void onReceive(Context context, Intent intent)
{
if (screenWakeLock == null)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
screenWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, “ScreenLock tag from AlarmListener”);
screenWakeLock.acquire();
}
//TODO:Do your code here related to alarm receiver.
if (screenWakeLock != null)
screenWakeLock.release();
}
}

Example B:

If you have to start a intent service then you dont need to use PowerManager.Wakelock used in above example.

So you have to start your service by using startWakefulService(context, service) And from service you have to inform by AlarmBroadCastReceiver.completeWakefulIntent(intent) to AlarmBroadCastReceiver that your service task is done.For detail follow example:

public class AlarmBroadCastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to your service.

Intent service = new Intent(context, WakefulService.class);

// Start the service, keeping the device awake while it is launching.

startWakefulService(context, service);
}
}
The service does some work. When it is finished, it releases the wake lock by calling completeWakefulIntent(intent).
public class WakefulService extends IntentService {
public WakefulService() {
super(“WakefulService”);
}

@Override
protected void onHandleIntent(Intent intent)
{
    //TODO:Service code
    AlarmBroadCastReceiver.completeWakefulIntent(intent)
  }
}

Well receiver is done but how to set alarm,so for setting alarm you have to check android OS version first and set your alarm, check it out.

Step 3:

AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmBroadCastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, reminderiId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= 23)
{
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
}
else if (Build.VERSION.SDK_INT >= 19)
{
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
}
else
{
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
}

Step 4:

Last step but very important step,give wake lock permission in manifest.

<uses-permission android:name=”android.permission.WAKE_LOCK” />