Android O Background Limitations: Not Just for targetSdkVersion 'O'

In Monday’s post on ODP2, I wrote:

The biggest concern is “Even for apps not targeting O, users can use the Settings screen to enable background execution limits.” This implies that all developers need to concern themselves with the changes in Service behavior, the semi-ban on implicit broadcasts, and the changes in background location behavior. Previously, this was limited to developers who jumped to targetSdkVersion of O or higher. However, I cannot find where in Settings that the user can make this change. I cannot even find it in Developer Options. So, it is unclear how much of an issue this is.

Yesterday, Oasis Feng pointed out that the place in Settings where the user can apply background limitations to apps is in the Battery screen, for apps that are listed there as big battery consumers.

(of course, it’s not every app, as the Google App does not have that option)

From the standpoint of whether or not users toggling this setting will become common, this Settings location is not bad. Users will have limited ability to apply the background limitations to apps. However, it is possible, and so developers who are not planning on shipping a targetSdkVersion of O right away need to test this scenario.

However, developers cannot use the Settings app to apply this limitation, unless their app happens to be in the battery blame list, which ideally doesn’t happen. So, I updated my issue to request some instructions for how developers can toggle this by other means.

And, today, I received a response.

Apparently, developers can do the same thing that users can, but to any app, via the undocumented adb shell appops command:

adb shell appops set RUN_IN_BACKGROUND ignore

(where is your app’s applicationId)

I say “apparently”, as I have no good way of confirming that this “appop” is the same as what users can do from the battery blame list, but I’ll take it on faith that it is the same thing.

Based on my testing, the behavior of an app with targetSdkVersion of O and an app with a lower targetSdkVersion but affected by this appop is slightly different:

  • In either case, you cannot receive broadcasts of implicit Intent objects via manifest-registered receivers

  • In either case, a background unbound service (i.e., started via startService()), will be stopped after ~1 minute

  • In the targetSdkVersion 'O' case, you will not be able to start a service via startService() after ~1 minute (“Background start not allowed”), but in the appop case, you still can start services in this state

The argument about why this is not documented anywhere is:

We are not generally advertising this for development because it does not behave the same in many important ways as an app that is targeting O, so you need to actually target O to test your app against background check. (And generally we are not wanting to encourage developers to mess around with how broken their app may be with the background app op restriction imposed on it, but instead target O so they work within the new background limits and don’t need to worry about the user trying to do this to them.)

However, developers routinely do not move to the latest targetSdkVersion as soon as it is released. For example, here are some better-known apps from my “daily driver” device that are not on targetSdkVersion of 25 (the now-current latest version):

  • Adobe Reader: 24
  • Amazon Kindle: 24
  • Barcode Scanner: 19
  • Fastmail: 21
  • Foxit PDF: 22
  • Mozilla Firefox: 23
  • TripIt: 23
  • United Airlines: 21
  • VLC: 23
  • Vonage: 23

And so on.

Now, plenty of app developers do aim for the latest targetSdkVersion. But it is certainly not all. Google should be aware of this; I have to imagine that they have metrics on the state of apps in the Play Store.

An attitude of “we don’t want to document this because developers should always use the latest targetSdkVersion” is unrealistic and, IMHO, unfortunate.

So — once again, IMHO — here’s what you should do:

  • If your app will ship with a targetSdkVersion of 26 (or whatever O turns into) shortly after Android O ships, hopefully you are already testing how your app behaves with the background limitations, and so you know how it will affect your app.

  • If you plan on sticking with a lower targetSdkVersion for a while, and you are really really sure that your app will not show up on the battery blame list, and you want to ignore the background limitations for now, that’s your decision to make.

  • If, however, you plan on sticking with a lower targetSdkVersion and your app does tend to consume a fair bit of battery life, you should test your app with the adb shell appops command cited above. If nothing else, you can identify the likely symptoms that users will experience if they limit your background work through the Battery screen in Settings. That way, if you get customer service calls/emails/texts/Play Store comments/candygrams about those symptoms, you can better advise users about what to do.

Meanwhile, the War on Background Processing continues.