eclipse-paho / paho.mqtt.android

MQTT Android
Other
2.94k stars 890 forks source link

Android O - Background execution restrictions #195

Open Nupraptor opened 7 years ago

Nupraptor commented 7 years ago

Question for @jpwsutton

With the recently released Android O Developer Preview it appears that long running background services are no longer going to be supported, the platform will actively stop services once an app enters idle mode.

I appreciate it is early days and O could be subject to change but as this could have a significant impact on the functionality of the library I thought it was worth raising here and potentially get some conversation/feedback kicked off.

Has any impact analysis already been carried out / planned?

Thanks

jpwsutton commented 7 years ago

Hi @Nupraptor

We started looking at this a few months ago, unfortunately it seems like Google is Intentionally positioning Android O in such a way that only GCM (Google Cloud Messaging) is able to conduct background messaging operations.

I contacted the Devs to ask them about it here: https://plus.google.com/+JamesSutton42/posts/GQFy9QZEUqb

This issue is already affecting people here: https://github.com/eclipse/paho.mqtt.android/issues/104

In reality, I think we will have to face the fact that unless developers can get their Apps whitelisted within Android, they won't be able to run the Paho Android Service in the background. However, they would still be able to use MQTT whilst their App is in the foreground.

One potential flow that Google suggested was:

An approach I've seen that was quite successful was using MQTT/etc while your app is in the foreground and then using GCM when in the background. This gives you the best of both worlds - instant send/receive when open and low battery usage when closed. This would have to be implemented by App developers themselves though.

Nupraptor commented 7 years ago

Hi @jpwsutton

I thought this may be the case, one of my primary concerns was how the service and MqttAndroidClient would react to being stopped by the system under Android O, however my fears may be unfounded due to some information provided on the developer preview changes page, which states:

While an app is in the foreground, it can create and run both foreground and background services freely. When an app goes into the background, it has a window of several minutes in which it is still allowed to create and use services. At the end of that window, the app is considered to be idle. At this time, the system stops the app's background services, just as if the app had called the services' Service.stopSelf() methods.

With a side note of:

Bound services are not affected These rules do not affect bound services in any way. If your app defines a bound service, other components can bind to that service whether or not your app is in the foreground.

As the MqttService supports binding and MqttAndroidClient actively uses that binding it would appear that it is exempt as any call to stop the service would fail while clients are actively bound.

Of course this would need verifying as O progresses and doesn't help with Doze and AppStandby which, as you've already pointed out, is already having an effect. Although, subject to a working AlarmPingSender which can re-establish the connection at least everything will keep working once an app is no longer affected by Doze/AppStandby restrictions.

On the topic of Doze, I do like the suggestion from @binarybucks on #102 to make use of maintenance windows to re-establish a connection and allow messages to flow. Perhaps usage of JobScheduler to fire off the appropriate process once network access is available? (for Android M and higher)

chintan-mishra commented 7 years ago

https://stackoverflow.com/questions/12692636/best-architecture-for-a-long-running-service-on-android

How about this as a solution for now?

The above link suggests making the service a foreground task.

This API by Evernote can also be helpful to schedule connecting to MQTT server.

antgustech commented 6 years ago

I'm having this problem on both 7.1 and 8.1.

Is a foreground task the any viable option to mitigate this problem? I suppose I can hide the notification inside Android so you wouldn't see the notification.

chintan-mishra commented 6 years ago

How would you hide the notification?

PawanDalal commented 6 years ago

@chintan-mishra No. You can't hide notification if the service is running in foreground.