Frequently in an app we need to perform a task when the activity has been completely shut down. For example, in a music player, we probably want the music to continue to play when the user has closed the player's main activity - and we want the user to be able to pause or rewind the same music when they relaunch the activity. Another example might be a mapping application in which the user would like to record their walking route using GPS. We want the recording to continue even if the user closes the activity - and allow the user to stop the recording if they re-launch the activity.
Services 
(see the Android developer documentation for full details - here).<service android:name=".MusicService"></service>
android.app.Service and then launch it from the main activity.onBind() method in your service
import android.app.Service
import android.content.Intent
import android.os.IBinder
class MyService: Service() {
    // start handler
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY // we will look at this return value below
    }
    // bind handler - not needed in many cases but defined as an abstract
    // method in Service, therefore must be overridden
    override fun onBind(intent: Intent?): IBinder? {
        return null // can just return null if binding is not needed
    }
}
Services, like activities, have lifecycle methods including:
onCreate() - when the service is created;onStartCommand(intent: Intent?, startFlags: Int, id: Int): Int  - runs when a service is started (see below); onBind(intent: Intent?): IBinder? - runs when a service is bound. As seen above, you have to implement this even if you do not use binding, but it can just return nullonDestroy() - when a service is destroyed.val startIntent = Intent(this, MusicService::class.java) startService(startIntent)
onStartCommand() is called when a service is started with startService()START_STICKY (see here)START_NOT_STICKY insteadSTART_STICKY:
 override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        
    // do something, e.g. start GPS, or music playing, etc.
    return START_STICKY // Important if you want service to be restarted!
}
intent parameter will be null (again, see here; otherwise, this is the intent used to start the service)stopService() with the same Intent used to start the service, for example:
stopService(serviceIntent)
onDestroy() method of the service will be called. In the Service's onDestroy(), you must stop any threads, background tasks, etc. that the Service is running, as otherwise, the thread will continue to run after its parent Service has been destroyed, resulting in possible memory leaks and unintended behaviourBinder object which provides access to your Service from your Activity.android.os.Binder and provides a method to return the Service.onBind() method within the Service to create a new Binder object and return it when the 
Activity binds to the service. 
To bind a service, we need two more components, a Binder (as we have seen) and a ServiceConnection, which is used to provide a connection between the activity and the service. Here is an example.
(Note that IBinder is an interface which Binder implements).
class MusicService: Service() {
    inner class MusicServiceBinder(val musicService: MusicService): android.os.Binder()
    override fun onBind(intent:Intent) : IBinder {
        return MusicServiceBinder(this)
    }
}
Note the following:
onBind() method. This method runs when the activity binds to it.musicService. This is needed as the activity will receive only the binder, not the service. Thus, if the activity wants the service, it must obtain it from the binder.In our activity, we must create a ServiceConnection object, to obtain a connection to the service. Here is an example:
 val serviceConn = object: ServiceConnection {
     override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
        service = (binder as MusicService.MusicServiceBinder).musicService
     }
     override fun onServiceDisconnected(name: ComponentName?) {
     }
 }
It is an instance of an anonymous class (a class with no name, which inherits from the abstract class ServiceConnection and overrides the required methods on-the-fly. These methods are:
    onServiceConnected() method is a callback method which runs as soon as the Activity has been bound to the Service. The Binder object (the inner class within our Service, see above) is provided as a parameter to onServiceConnected(), so we cast it to the correct object (MusicService.MusicServiceBinder) and obtain our Service using its service attribute.onServiceDisconnected() runs when the service is disconnected from the activity. Here, we're not doing anything in the method but we still need to override it.bindService() to actually bind the serviceFinally, In your main activity, you bind the service using bindService()
which, like startService() takes an Intent for the Service.
val bindIntent = Intent(this, MusicService::class.java); bindService(bindIntent, serviceConn, Context.BIND_AUTO_CREATE)This will bind the activity to the service and trigger the onBind() method in the MusicService. The Context.BIND_AUTO_CREATE flag will "automatically create the service as long as the binding exists" (see here), without this flag, you will also need to call
startService() to start the service.
unbindService() to let Android know that the activity does not wish to be connected anymore.unbindService() takes the ServiceConnection as an argument
override fun onDestroy() {
    super.onDestroy()
    unbindService(gpsServiceConn)
}
startService() and bindService().Intent and as such can pass data to another
application component as a BundleBroadcastReceiver objectactionIntentFilter
val broadcast = Intent().apply {
    action = "sendTime"
    putExtra("time", System.currentTimeMillis())
}
sendBroadcast(broadcast)
intent with an action of sendTimetime, containing the current time in 
milliseconds since Jan 1st 1970sendBroadcast() to send the Intent as a broadcastService (so that the Service can broadcast updates to one or more activities) but could equally well be placed in any application component, such as an activity
receiver = object:BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
         when (intent?.action) {
                "sendTime" -> toast("${intent?.getLongExtra("time", 0)}")
            }
        }
 }
IntentFilter in our activity to explicitly state
that this activity is capable of receiving intents with an action of sendTime:
val filter = IntentFilter().apply {
    addAction("sendTime")
}
registerReceiver(receiver, filter)
sendTime. Even though this is specified by the
intent filter, it is recommended to do this as "it is possible for senders
to force delivery to specific recipients, bypassing filter resolution"
(see the documentation)onDestroy()override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(receiver)
}
https://github.com/nwcourses/ServicesStarter.gitwhich is another version of the mapping application. It features a map plus three buttons: "Start GPS", "Get GPS location" and "Stop GPS". Using a service, complete the app as follows. The functionality associated with each button should only run if the
permissionsGranted boolean is true.
initService() method, start and bind the service. The service should contain a LocationListener. Start this up in a method of the service called startGps() and call this from onStartCommand(). Also write a method in the service called stopGps and remove updates on the listener in this method. Call this method from the onDestroy() in the service.startGps() method.stopGps() method.startGps() and stopGps() methods). Register the receiver in onStartCommand().