📜 ⬆️ ⬇️

Android O and background services

Hello. Like most developers, I was too lazy to make complex changes from version to version of Android. The first such difficult change was “Runtime permissions”, which came to us with the 6th android. But this is already in the past.

The topic of this publication will be changes in Android Oreo. You can read more here . All the articles that I found, with a possible solution to the problems, said "Just inherit the service from the JobIntentService and use it in enqueueWork ()".

Cool, yeah. But not everything is so simple. If you look at the CommandProcessor, you can see that the service stops immediately after running onHandleWork (). This is because the IntentService is not intended to perform complex work, it is created for things like: event delivery, start of other services, and so on.

while ((work = dequeueWork()) != null) { if (DEBUG) Log.d(TAG, "Processing next work: " + work); onHandleWork(work.getIntent()); if (DEBUG) Log.d(TAG, "Completing work: " + work); work.complete(); } //Work @Override public void complete() { if (DEBUG) Log.d(TAG, "Stopping self: #" + mStartId); stopSelf(mStartId); } 

These articles and their solutions did not help me, as they are just a copy from developer.android.com. Therefore, I continued to test and search for simple options for using services while the application is in the background (in compatibility with Android O). And I found a way.
')
Using JobIntentService, you can try to start your service in the old-fashioned way, but the context provided by JobIntentService is not suitable for these purposes, but we can always request the application context. But even when we have the application context, at the start of the service, the limitations of the android will stop us.

What next? These restrictions on background execution work only when you try to start the service with startService (), and if you use bindService, the android will not give you any errors. But, in the case of a bind, the service will only be created and attached to the application and you need to do it all along with the creation and implementation of the ServiceConnection, on the call of which you need to run the required method (onHandleWork () or onHandleIntent () or the required method of your service).

Doing all this, I came to the conclusion that this is not the easiest way. So I wrote a small and simple library that can do it all for you. It also allows you to use background services without their declaration in the manifest and the creation of any classes. You can find it here .

And a small example from the gita:

 //No need to create classes and add manifest declarations ServiceManager.runService(context, () -> {Logg.e(TAG,"Some Action");},true); //if you have already prepared service you can us it as : ServiceManager.runService(context, GeofenceTransitionsIntentService.class); //or if you need to add some data or actions you can use it like : Intent geo = new Intent(context, GeofenceTransitionsIntentService.class); geo.setAction(GeofenceTransitionsIntentService.ACTION_REQUEST_LOCATIONS); ServiceManager.runService(context, geo); 

In order to use the last 2 options - you need to examine the CompatService
An example can be found here .

And going back to the topic of what I started with “The first such difficult change was-Runtime permissions”, you can also evaluate my solution to this problem.

Source: https://habr.com/ru/post/341106/


All Articles