Good morning,
I would like to add a localization service in background. After many unsuccessful searches, I decided to ask the question here.
My problem is this, I can’t find complete documentation that explains how to make a service in the background on Android.
I managed to find a preferred code on github, which uses the functions:
startForegroundService
, and startService
.
The concern being that I would like to pass the data recovered in the class initiated by my intent on my activity. These data are obligatorily used in the activity (for display and backup). So I thought about several solutions, including one that would be most likely, which would be to install a callback in the class that is used in background.
So I have two questions:
- Do you have the link to documentation that correctly explains how functions running in the background on Android (Java) and how to (if possible) improve my overall understanding (currently I do not understand the official documentation) ?
- How can I pass a callback to my class instantiated by intent? Or pass them from class to activity ?
Github where I stole the code for launch the intent in background : https://github.com/mahdices/AndroidBackgroundLocation/blob/39facab3252dd43742f7626a57feb76bbce10d93/app/src/main/java/com/ces/backgroundlocation/MainActivity.java#L34
final Intent intent = new Intent(MainActivity.this, MyLocationManager.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}
PS : The funniest thing is that I don’t feel that the service in the background is really launching. (Probably because I don't understand the background services and how to use them)
Thank you in advance for your answers.
CodePudding user response:
Check this medium article.
Also bound service will solve your problem to keep passing the data to your service and getting updates from it.
https://medium.com/@huseyinozkoc/android-services-tutorial-with-example-fa329e6a5b4b
CodePudding user response:
I'll explain their differences in your use case. I hope to be useful: For location tracking applications, first of all, you should determine your rules, what is your business logic?
If you just wanna track him while your app is in the foreground, you don't need any ForegroundService. You just need to run a BoundService which is bound to (for example) your activity and gets stopped whenever your activity is destroyed.
On the other hand, ForegroundService lets you track the location even after your app has been closed, showing the user a message that says: "Hey! I'm tracking your location if you don't mind :)". You have to show this notification because Android won't let you track the location without this notification.
Soon I'll write a post and explain it more and attach it here
CodePudding user response:
This is the official documentation about services - there are a few sections on the side. It's worth reading because it does pretty much cover everything.
I don't think you want a foreground service. The terminology is a bit confusing, but a foreground service is one that still runs when the user isn't interacting with the app, like a music player. (There's more info in the Foreground services section of those docs.)
It's foreground because the service is basically elevated from a background thing, and becomes a foreground component that will keep the app's process running, on the same level as an Activity
. The difference is you can see an Activity
, but you don't necessarily know that a foreground Service
is running. That's why Android puts a bunch of restrictions on foreground services, including requiring you to display a permanent notification while it's running. That's why you have to call startForeground
to put a Service
in the foreground, and why you have to pass a Notification
when you do it.
So let's assume you don't want a foreground service - you shouldn't run one unless you need to. If your Service
only runs while the user is interacting with your app (and maybe keeps going a little while the app is in the background your app and its background services won't be killed immediately) then just a plain service is fine.
There's two ways to run a Service
- call startService
or bind to it with bindService
. startService
makes it run until you call stopService
. bindService
adds to the count of clients bound to the service - if it's not already running it will start, and it'll keep running until all the clients unbind from it.
These two systems work together to keep the service running. If you've called startService
and all the clients unbind, it will still run because it's been explicitly started, until you call stopService
. If you call stopService
but clients are still bound, the service will still run. So you might find it more useful to use both of these methods, instead of just one, to keep the service running.
Generally speaking, if you want access to the running Service
you want to bind to it. Here's the documentation for that, but the basic idea is the Service
creates an IBinder
object with a bunch of methods and variables that interact with that running instance, and when something binds to the service, it gets that Binder
object and has access to the service through those methods. Or if you like, you could just put a bunch of public methods on the Service
and stick a reference to the service instance in the Binder
, like in the documentation example:
class LocalService : Service() {
// Binder given to clients
private val binder = LocalBinder()
inner class LocalBinder : Binder() {
// Return this instance of LocalService so clients can call public methods
fun getService(): LocalService = this@LocalService
}
override fun onBind(intent: Intent): IBinder {
return binder
}
}
So basically, you can access the running service by binding to it, and you receive an object that has a reference to that service.
Using startService
is more like telling the service to run and do its thing, like an independent component you don't directly interact with. It's possible for a started service to e.g. interact with some application-level variables, like a global var
or something that an Activity
or whatever can also look at, but that's limited and often hacky. Using a bound service is the way you're meant to do it.
I've skimmed over some of the stuff (like the boilerplate you need to bind to a service) but that's all in the docs - once you know what you want their example code is a good place to start building from!