Services Tutorials: Part 2. A foreground Service

  • Written by  Clive

Services Tutorial project filesOut in the open: The foreground Service

Android foreground service tutorial icon

It’s unlikely that the system will kill a foreground Service.

Typically we’d use foreground Services for work that the user is aware of, like playing music.

When we use a foreground Service, we have to send a notification to:

  • let the user know that the Service is running
  • give the user the opportunity to stop it

If you haven’t already done so, you may want to have a look at the article All about Services and Part 1 of the series of Services tutorials, A Simple Service

Our foreground Service tutorial app

Our tutorial app uses a foreground Service to play a sound file.

This is the second part of the tutorial on Services. It uses the same app.

Start the app, press the ForegroundActivity button and the foreground activity screen appears.

The foreground activity screen is on the left:

Foreground Service Tutorial app screenshot

The foreground activity screen, on the left, displays the control buttons. Pressing Play starts the Service and a new screen appears

Press the Play button to start the foreground Service and the music playing. A new activity, the DisplayActivity activity is also started.

The app remains responsive while the music plays. You can test it. Press the Counter button and it responds by displaying a counter which increases with each press.

Starting the foreground Service sends a notification. The notification appears at the top of the screen. You can see the Music Playing ticker text at the top of the right activity screen.

Sliding the drawer down reveals the notification:

Foreground Servive notification

The foreground Service notification is only removed when the foreground Service stops

Clicking on the notification returns the user to the foreground activity with its control buttons.

Pressing the Move Foreground to Background button moves the Service from the foreground to the background. It will also start a background Service if the foreground Service is not running.

Pressing the Stop button stops the Service.

The Controller: The ForegroundActivity activity

The foreground activity displays three buttons. These are the music player controls.

Game on: The Play button

Pressing the Play button starts the foreground Service.

Here’s the code:

Foreground Service paly button

The Play button starts the foreground Service

Note the following:

  • buttonPlay – we create a button
  • findViewById – we get an instance of the button identified by its id in the layout file
  • setOnClickListener – our listener to listen for when this button is clicked
  • onClick – contains the code that’s executed when the button is pressed
  • startForegroundIntent – the intent that we’ll use to start the Service. It will contain information about the Service that we want to start
  • ACTION_FOREGROUND – the custom action that we want to perform. More on this later
  • setClass – we identify the Service that we want to start here. There are two parameters:
    • the context
    • the Service that we want to start
  • startService – this starts the Service. We pass the intent as a parameter. It contains all the information needed to start the Service

Game over: The Stop button

Pressing the Stop button stops the Service if it’s running. Nothing happens if it is not running.

Here’s the code that appears inside the Stop button’s onClick method:

Foreground Service stop button

Use stopService() to stop the Service

Note the following:

  • stopIntent – the intent that contains the information to identify which Service to stop. It has two parameters:
    • the context
    • the Service that we want to stop
  • stopService – this stops the Service identified in the parameter, stopIntent

Move over: The Move Foreground to Background button

Pressing the Move Foreground to Background button moves the foreground Service to the background, if it’s running.

If the foreground Service is not running then a new background Service is started.

The Service is now more likely to be killed by the system if it needs resources.

Here’s the code:

Foreground Service move to background button

Moving the foreground Service to the background

Note the following:

  • startBackgroundIntent – the intent that we’ll use to move the Service to the background. The intent will contain all the necessary information about the Service and what we want to do
  • ACTION_BACKGROUND – the custom action that we want to perform. More on this later
  • setClass - we identify the Service that we want to start here. Although we want to move the Service to the background, we still call startService. This ensures that the Service’s onStartCommand method is called. This is where we move the Service to the background. There are two parameters:
    • the context
    • the Service that we’re working with
  • startService – this ensures that the Service’s onStartCommand is called. This is where we’ll deal with the request to move the Service to the background

The Serving Class: MyForegroundService class

This is the Service that we’ll run in the foreground and move to the background.

The little black book: The manifest

As with all Services, you need to declare them in the AndroidManifest.xml file, like this:

Foreground Service AndroidManifest.xml file

Declare the Service in the manifest file

Note the following:

  • name – this is the only required attribute in the <service> element. Use your Service class as the name

In the beginning: onCreate

We use the onCreate() method to create our Media Player and Thread.

Here’s the code:

Foreground Service onCreate() method

Instantiate the Media Player and Thread in onCreate()

Note the following:

  • player – our Media Player object. We use it to play the sound file
  • sound file – the sound file is in the res/raw folder
  • setLooping – we set the player to loop the sound file. It plays the file in a continuous loop
  • backgroundThread – the sound file will play in this background thread. See Processes and Threads for more on threads
  • we display a Toast message indicating that the Service has started

Make it so: onStartCommand

This is where it all happens.

The onStartCommand is called each time you call startService() and also if the Service needs to restart after being killed by the system.

Foreground Service onStartCommand() method

The onStartCommand is called after each call to startService and on a restart

Note the following:

  • onStartCommand has three parameters:
    • intent – this is the intent we used in our startService call
    • flag – additional information about the start request. It’s generated by the system
    • startId – a unique identity for each start request. It’s generated by the system
  • if statement – we use an if statement to filter the action contained in the intent. There are two options:
    • ACTION_FOREGROUND – this means that we want to start a foreground Service. We call startForeground() to start the foreground Service and startActivity() to start another activity. More on both of these later
    • ACTION_BACKGROUND – this means that we want to move the Service to the background. We call stopForeground() to stop the foreground Service. It will continue running in the background, making it more likely to be killed by the system if its resources are needed. We pass true as the parameter to remove the notification. If the foreground Service is not running then a background Service is started. Note that each call to onStartCommand will start a Service if one is not already running
  • If the player is not playing – we have another if statement that checks if the player is playing. If it is then we do nothing. If it isn’t then we start the background thread which starts playing the music (actually it just loops a sound file)
  • Return START_STICKY – this guarantees that the onStartCommand will be recalled when the system tries to restart the Service after having killed it. The intent will be passed as null on the restart

Backwards and forwards: The Actions

We declared two static constants in our MyForegroundService class:

Foreground Service action constants

Our two constant ACTION fields

We use these for our custom actions which we include in the intents that we pass as parameters to our startService() calls in the foreground activity.

They are then filtered in our onStartCommand’s first if statement to determine which action to take.

Much to do about nothing: Starting the DisplayActivity activity

When we start the foreground Service, we also start a new activity. Here’s the code:

Foreground Service startActivity

Starting the display activity using FLAG_ACTIVITY_NEW_TASK

Note the following:

  • intentDisplayActivity – our intent that will contain information about the activity that we want to start. It receives two parameters:
    • the context
    • the activity that we want to start
  • FLAG_ACTIVITY_NEW_TASK – we’re calling startActivity() from outside an activity context so we need to start this activity as a new task
  • startActivity – starts the activity specified in the intent

Put it up front: Starting the foreground Service with startForeground()

The startForeground() method receives two parameters:

  • NOTIFICATION_ID – the unique identifier for the notification that will display when the Service starts. I’ve used the NOTIFICATION_ID constant. It must not be 0
  • getCompatNotification – this builds the notification that we want to display

You’ve been notified: The Notification

You have to show a notification when running a Service in the foreground.

We use the NotificationCompat class to build our notification. This allows us to build notifications from as low as API level 4.

Here’s the code:

Foreground Service build notification

Build the notification

Note the following:

  • builder – we construct a Builder object which we use to build our notification
  • setSmallIcon – we use the ic_launcher drawable as the icon to display in the notification
  • setContentTitle – this is the title or first row of text in the notification
  • setTicker – this is the text that displays in the title bar when the notification first arrives on screen
  • setWhen – this will be the time that the notification will be sent. It’s used to sort the notifications
  • startIntent – when the user clicks on the notification, we want them to be taken back to the ForegroundActivity activity. We put this information into this intent. There are two parameters:
    • the context
    • the activity that we want started
  • contentIntent – this is our PendingIntent. It contains the intent specifying the activity that we want to start when the notification is clicked
  • getActivity – this retrieves the pending intent that will start the new activity. It is passed four parameters:
    • the context
    • a unique request code
    • the intent specifying the activity that we want to start
    • flags – we pass 0 here as we don’t specify any flags
  • setContentIntent – sets the pending intent to be used when the notification is clicked
  • notification – our notification that will be sent when the foreground Service starts
  • build – combines all the options that we set using the set<> methods and returns a new notification
  • return – we return the notification for use by the startForeground() method

The big clean up: onDestroy

onDestroy is called by the system when the Service is no longer used. This is where we release any resources for use elsewhere.

Here’s the code:

Foreground Service onDestroy

The Service is no longer used so release any resources that it is using

Note the following:

  • we check if the player is playing. If it is then we release any resources used by it
  • We interrupt the background thread if it is still running
  • Throughout the app we use the LogCat to display information that may interest you. Have a look at Using Android’s Log class API to debug Android application code for more on the LogCat

Play on: Playing the music

The playMusic method starts the Media Player. The sound will continue to play while the Service is running.

Foreground Service Media Player

The music player plays the sound file in a continuous loop

I hope that you have found this tutorial helpful.

Check out the Bound Services tutorial

This tutorial was created using Android Studio. You can download the project files here Download icon

Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.