3

According to this thread after Android Oreo, Google introduced some background limitations so it's not possible to run a Service always in background without displaying a user notification.

Is it possible to achieve this with root privileges?

EDIT: I see that people are voting to close my question because apparently it looks like it's too broad, but I am running LineageOS, and I would like to put my app to run as system service if possible, and I think that this would be feasible without modifying the source code. For example when installing the OS, I could flash GApps, but it was optional, and they seem to have the functionality that I'm talking about. I am also not expecting you to do all my research for me, and I am willing to accept the answer that points me in the right direction.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
Andrej
  • 384
  • 1
  • 6
  • 23

2 Answers2

4

There's indeed an undocumented shell command, which can be used to white-list packages, by adding them to the global location_background_throttle_package_whitelist (I haven't tested it):

settings put global location_background_throttle_package_whitelist "package1,package2,package3"

^ this is for location services, but there might be further background_throttle settings available:

settings list global | grep background_throttle

Source: XDA Developers.


Also in the source code I've only found these settings:

Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST
Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS
Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS

The documentation is clear about the fact that certain services are being added into a temporary white-list. To find out what actually white-lists these services, one would have to dig further. These background service restriction is actually being described in Context.java ...while the methods annotated with @UnsupportedAppUsage are the ones which only the system uses.


The Firebase WorkManager is still the best option available - or the underlying JobIntentService, which will still run as a regular background service < Android O. Flashing Android N or Lineage OS 14.1 would be a certain workaround, which is barely being considered.

The assumption that root permissions would provide super-powers might be a misconception. Permitting unfettered location access is still quite limited and even Google's own services are only temporarily white-listed. The only services excluded from these background execution restrictions would be Linux system services, written in C++ (which are running outside of the JVM) - while this is something very else than Android background services, written in Java (which are running inside the JVM and all extend the same restricted Service class).

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
1

One technique I've found that works quite well is to use a bound service. No user notification required and since you never call startService(), it works on Oreo and higher. No root needed either. A good place to bind to a service that will always run is from your application object's onCreate() method. Whenever your app is running the service will be running.

Greg Moens
  • 1,705
  • 8
  • 15
  • this still does not meet the demand of **not** having to run the app... the problem is, that `JobScheduler` does not run tasks instantly & `ForegroundService` does not run in the background. `root` does not really help either, because `root` isn't `system`. – Martin Zeitler Apr 14 '19 at 01:19
  • A boot receiver could be used to start the app process, which would then start (bind) the service. This would all happen without the user having to "run" the app. – Greg Moens Apr 14 '19 at 03:59
  • This would still run the app in foreground. `WorkManager` (or the underlying `JobIntentService`) run in the background - and I'd still be waiting for a valid reason not to use them; especially since there is no real alternative, even if the execution may be delayed. Just imagine 20 apps would use your suggestion... then you can scroll through the notification panel; it does not scale too well. – Martin Zeitler Apr 14 '19 at 05:12
  • The app would only run in the foreground if startForeground() was called from within the service. Until then a bound service would run in the background and there would be no notification displayed. I guess it all depends on the purpose of the service. I've used JobIntentService too, but that is used to execute a time limited task of some kind. I haven't found it useful for running a service always in the background like the question was asking. I'm assuming WorkManager is similar, although I've never used it. – Greg Moens Apr 14 '19 at 14:44