September 23, 2015

September 23, 2015 jpcarlino

Take your Android app to the next Push level

Last 17th August we did receive the news about the first official release of Android 6.0, codenamed “Marshmallow”. This milestone includes several new features and improvements for both final users and developers. One of the most interesting aspects is the new set of power saving optimizations (or constraints, if you look at them as a developer) which raises the bar of future applications. With this recent move, remote notifications (pushes) will become essential for the success of long running applications.

A brief summary about the power saving optimizations

Android 6 (or, to be more precise, its previous beta versions known simply as Android-M) introduced two new behavioral changes under the Power-Optimization category:

I recommend this article by Dave Smith, which gives more insight into the new ‘Doze mode’, even if some details may have changed since the time of writing, three months ago. However we can clearly see the major cause of this set of constraints: the reduced battery life produced by resource-hungry applications, which began to be addressed with the addition of the power saving mode on Android Lollipop. The consequence of this new policy is the increased leading role of push notifications as the essential mechanism to reconcile shorter resource availability with long life-cycle applications.

Why notification pushes are now “a must” for most applications?

Lets first summarize what ‘Doze mode’ and ‘App Standby’ implies for your applications (while active):

Network access is disabled, unless your app receives a high-priority Google Cloud Messaging tickle.

The system ignores Wake locks.

Alarms scheduled using the AlarmManager class are deferred, unless you have exempted them using the setAndAllowWhileIdle() method.

The system does not perform Wi-Fi scans.

The system does not permit syncs or jobs for your sync adapters.

The system does not allow JobScheduler to run.

To cite the official documentation:

“The power saving features of Doze and App Standby limit the amount of background processing that your app can perform when a device is in an idle state or while your app is not in focus. The restrictions the system may impose on apps include limited or no network access, suspended background tasks, suspended Notifications, ignored wake requests, and alarms.”

There are of course a few exceptions to this rule, like releasing applications with foreground services:

“A foreground service is a service that’s considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the “Ongoing” heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.”

However you see what is the goal: commit your application to a more efficient battery usage. And if you are going to run continuously don’t hide it to the user. Make him clearly aware that you are consuming resources, so he can later take the decision of closing it.

Imagine for instance a conversation application like Facebook Messenger, Whatsapp, Skype, Conversations, etc. Usually these kind of apps use a connection-oriented protocol under the hood. These applications don’t show an ongoing UI notification (i.e., showing you are currently online) because these use background services to manage the ongoing connection. However using this mechanism would become problematic on Android 6, because background processing will be suspended. This means that your IM application would be disconnected for (possibly) long periods. How to overcome this limitation?. By using notification pushes to notify the user about incoming messages.

Of course, the user can whitelist applications using the Settings app to exclude them from these limitations, but this is a privilege you shouldn’t assume anymore for your application. And I think this is a good motivation to make applications more efficient and enhance the user experience on Android devices.

Prepare your application for Android 6 Marshmallow

According to the official documentation, even GCM pushes have “limited power”:

“Note: As of M Preview 3 release, Google Cloud Messaging (GCM) lets you designate high-priority messages. If your app receives high-priority GCM messages, the system grants brief network access even when the app is idle.”

Because GCM pushes are sent by default with normal priority, that means that you don’t have networking access upon push reception unless you set them as high priority. It is yet not clear from the official documentation, although some users receive delayed normal priority GCM pushes when device is in doze mode. In either case, you should evaluate if your application is of real-time nature at the time of assigning priorities to your pushes.

There is an official guide to test applications against these two device modes. Unfortunately there are still some bugs that need to be addressed on this area, but this should be the starting point to check that your applications are prepared to the new requirements.

Conclusions

With the recent launch of Android 6 (API 23) Google seeks to engage developers to be good citizens on the Android ecosystem and help with battery life, relying on Google Cloud Messaging whenever this is possible. They still provide a last workaround for this set of policies (foreground services) but your application now takes a much higher risk to be uninstalled or simply disabled by the final user because placing your application permanently in the notification area is not an option for many of them. The bottom line is that Android applications are not expected to be constantly running and GCM is proposed as the main platform for this to happen.

Only top messaging apps can expect to be tolerated by user in the notification area, so the developer needs to switch to GCM or at least have an option to support it, otherwise, be prepared to be uninstalled by users.

It’s time to be more efficient and adjust your new or existing applications to use the small (and sparse) time slots you will have to synchronize your application state in the new Android world.