Table of contents
1.
Introduction
2.
Android Services
2.1.
Foreground Services
2.2.
Background Services 
2.3.
Bound Services
3.
Life Cycle of Android Services
3.1.
Started Service
3.2.
Bounded Service 
4.
Callback Methods of Android Services Lifecycle
5.
Example
6.
FAQs
7.
Key Takeaways  
Last Updated: Mar 27, 2024

Android Services

Author Pradeep Kumar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In this blog, we will look into Android Services. Services allow applications to run in the background and perform tasks. We will discuss how Services are created and registered. Additionally, we will look at the different kinds of Services and their uses.

In this article, we will be creating an Android Studio application with an Empty Activity, so in case you are not familiar with activities, you can check out this article.

You can also read about, android operating system

Android Services

In Android, service is a particular type of component which allows an android application to run in the background and still perform operations. It is generally used to perform long time-consuming operations where the application doesn't necessarily have to be in the foreground. Ensuring that the app is running in the background and completing the specified task is one of the essential tasks of service. It is used in many applications, such as - a music player. Even when you minimize the music player app and shift to another application, the songs still play in the background. 

Following are the three main types of Android Services:

Foreground Services

These services keep the user informed about the progress of its ongoing operations. Like - when you are downloading a file, you can see how much your file has been downloaded and can also pause/resume the download. You can interact with Foreground services by responding to the notification about the ongoing task. 

Background Services 

As the name suggests, these services run in the background and don't need user interaction. Unlike Foreground ServicesBackground services don't notify the user about its ongoing task. You might have seen a notification for data syncing in your mobile device, which generally occurs after a specified period of time, to sync your mobile data. These types of processes are an example of Background Services.

Bound Services

Bound Service allows activities or any other application components to bound them to it. Multiple activities can bind themselves to one Bound Service. Upon unbinding all the activities, the service gets destroyed automatically. 

Life Cycle of Android Services

Two paths for completion of an android service's lifecycle are as follows:

Started Service

When an application component calls the startService() method, a service will start. Once a service is started on this path, it will not stop even if the component which called this service gets killed itself. The service will come to a halt only when the stopService() or the stopSelf() method is invoked.

Bounded Service 

The bindService() method is used to bind an application component to a Bounded Service. The execution of this service will not stop unless all the bound components unbind themselves, which can be done using the unbindService() method. It functions like a client-server interface where the components can interact with it by sending requests, and the service will then respond by sending some data back in return. 

This is how the android services lifecycle looks like by following these paths:

                                                                      

Image Source: androidcookbook

Callback Methods of Android Services Lifecycle

Following are some important methods that need to be overridden to write an android service:

  • onCreate(): When a new service is started, this is the method that gets invoked the first. It is used to perform a one-time-set-up upon starting of a service. 
  • onStartCommand(): As the name suggests, this method is called when you need to start a service. To stop the started service, the stopService() or stopSelf() method can be used.
  • onBind(): When an application component calls the bindService() method to bind itself with a particular service, this method is invoked. This method is mandatory to implement. In case you don't need to bind anything, you can simply return null from this method.
  • onUnbind(): This method is used when an application component needs to unbind itself from a service.
  • onRebind(): When all the existing components have unbinded themselves from the service, and you need to add new components with the service, this method is called.
  • onDestroy(): This method is invoked when the service finishes and is being cleared from the memory. This is the final callback received by any service, as after this, the service is destroyed. 

Example

In this example, we will create a service to play the default mobile ringtone. 

First, we need to create a new project in Android Studio by selecting the empty activity option. In this activity_main.xml file, we have added code for adding two buttons for a start and stop of service.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">


   <Button
       android:id="@+id/button1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginStart="48dp"
       android:text="Start Service"
       app:layout_constraintBaseline_toBaselineOf="@+id/button2"
       app:layout_constraintStart_toStartOf="parent" />

   <Button
       android:id="@+id/button2"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginStart="29dp"
       android:layout_marginBottom="82dp"
       android:text="Stop Service"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintStart_toEndOf="@+id/button1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Now we will create a CustomService.kt file in the same directory as your MainActivity.kt file. In this file, we have created a service to play the mobile ringtone. 

CustomService.kt

import android.content.Intent
import android.app.Service
import android.os.IBinder
import android.media.MediaPlayer
import android.provider.Settings
import android.util.Log
import android.widget.Toast

// Custom Service extending the Service Class
class CustomService : Service() {

    // declaring object of MediaPlayer
    lateinit var ringtone_player:MediaPlayer
    var show_text = ""

    // overriding the onStartCommand
    override fun onStartCommand(intent: Intent, flags: Int, Id: Int): Int {

        var ringtone = Settings.System.DEFAULT_RINGTONE_URI // default ringtone of the device
        // creating a MediaPlayer
        ringtone_player = MediaPlayer.create(this, ringtone)

        show_text = "Service has been Started"
        ringtone_player.setLooping(true)

        val duration = Toast.LENGTH_LONG // setting the duration to Long
        // start the process
        ringtone_player.start()

        Toast.makeText(this, show_text, duration).show()

        return START_STICKY
    }

    // stop on calling this method
    override fun onDestroy() {
        super.onDestroy()
        // text that needs to be displayed when this function gets invoked
        show_text = "Service has been Stopped"

        ringtone_player.stop() // stop the ringtone_player

        val duration = Toast.LENGTH_LONG // setting the duration to Long

        Toast.makeText(this, show_text, duration).show()

    }
    // overriding the onBind Method
    override fun onBind(intent: Intent): IBinder? {
        //as we don't need to bind anything to this service
        // we are returning null from this method
        return null
    }
}

Now that, we have created a custom service, we will now add it to the MainActivtiy.kt file.

MainActivtiy.kt

import android.util.Log
import android.os.Bundle
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.widget.Button
import android.view.View

// Main Activity class extends the OnClickListener and AppCompactActivity
class MainActivity : View.OnClickListener, AppCompatActivity()  {

    // declaring objects of Button class
    var button1: Button? = null
    lateinit var tag_name : String // tag for logging
    var button2: Button? = null
    lateinit var msg: String

    // overriding the onCreate Function
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        tag_name = "Android Services: "
        // assign id to button1
        button1 = findViewById<View>(R.id.button1) as Button
        // declaring listeners for button 1
        msg = "Declaring Listener for button 1"
        button1!!.setOnClickListener(this)

        Log.d(tag_name, msg)
        // assign id to button1
        button2 = findViewById<View>(R.id.button2) as Button
        // declaring listeners for button 1
        msg = "Declaring Listener for button 1"
        button2!!.setOnClickListener(this) // declaring listeners for button 2

        Log.d(tag_name, msg)
    }

    override fun onClick(current_view: View) {

        var custom_service = CustomService::class.java
        lateinit var var_intent: Intent

        // check if the current_view is equal to button1
        // if yes, then we need to start the service
        if (current_view === button1 ) {

            var_intent = Intent(this, custom_service)
            startService(var_intent)
        }
        // stop the service if current_view is equal to button2
        else if (current_view === button2) {

            var_intent = Intent(this, custom_service)
            stopService(var_intent)
        }
    }
}

Finally, we will register the service in the AndroidManifest.xml file.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidservices">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AndroidServices">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--Registering the New Service-->
        <service android:name=".CustomService"/>

    </application>

</manifest>

Output

When the Start Service button is clicked, the following message is displayed on the screen, and the ringtone starts playing in the background. 

                                                                                          


Upon clicking the stop Service button, the ringtone is stopped, and the following message is displayed on the screen.

                                                                                         

FAQs

  1. What does START_STICKY do?
    START STICKY instructs the OS to recreate the service and run onStartCommand() with a null intent once it has enough memory.
     
  2. What is the purpose of using Toast.Length_Long?
    It signifies the amount of time the message will be displayed on the screen. Length_Long is used when we need to show the message for a longer duration.
     
  3. When do we use lateinit?
    While working with variables that are declared first but initialized at a later time, we use the lateinit tag in the front of those variables. 

Key Takeaways  

In this article, we have extensively discussed Services in Android topics and their implementation in Android Studio. We discussed how Services could be created and registered in an android application.

Read more: Operating System, Free Space Management in OS and Usb debugging

We hope that this blog has helped you enhance your knowledge regarding Android Services and if you would like to learn more, check out our articles on Android Intents. Do upvote our blog to help other ninjas grow. Happy Coding!

Live masterclass