Simple Android Foreground Service Example Tutorial

By | September 2, 2015

In this tutorial we will see a very simple implementation of android foreground service.

A Service is an application component that can perform long-running operations in the background and does not provide a user interface.

A Foreground Service in android is a background service which keeps running even after the parent application is closed.

Use Cases:
– For downloading a file in background from a server.
– For playing songs in background in a music player app.
– For showing the status of Connection to the chat server for a chat messenger app.

Implementation:
Create an empty android application project and copy the content for MainActivity.java as shown below:

MainActivity.java:

package com.tutorialsface.example.foregroundservice;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void buttonClicked(View v) {
		Button button = (Button) v;
		Intent service = new Intent(MainActivity.this, ForegroundService.class);
		if (!ForegroundService.IS_SERVICE_RUNNING) {
			service.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
			ForegroundService.IS_SERVICE_RUNNING = true;
			button.setText("Stop Service");
		} else {
			service.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
			ForegroundService.IS_SERVICE_RUNNING = false;
			button.setText("Start Service");

		}
		startService(service);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

 

Now modify the layout file with the following content:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.tutorialsface.example.foregroundservice.MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="62dp"
        android:text="Tutorial on Forground Service \n| Tutorials Face - www.tutorialsface.com " />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Start Service"
        android:onClick="buttonClicked" />

</RelativeLayout>

The graphical view of the layout will  look like this:

Graphical Layout:

We have created a button in this layout to start/stop the service. Now lets create the class for service

Create a new java class named ForegroundSerivice.java and copy the content as show below:

ForegroundService.java:

package com.tutorialsface.example.foregroundservice;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

public class ForegroundService extends Service {
	private static final String LOG_TAG = "ForegroundService";
	public static boolean IS_SERVICE_RUNNING = false;

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
			Log.i(LOG_TAG, "Received Start Foreground Intent ");
			showNotification();
			Toast.makeText(this, "Service Started!", Toast.LENGTH_SHORT).show();

		} else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
			Log.i(LOG_TAG, "Clicked Previous");

			Toast.makeText(this, "Clicked Previous!", Toast.LENGTH_SHORT)
					.show();
		} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
			Log.i(LOG_TAG, "Clicked Play");

			Toast.makeText(this, "Clicked Play!", Toast.LENGTH_SHORT).show();
		} else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
			Log.i(LOG_TAG, "Clicked Next");

			Toast.makeText(this, "Clicked Next!", Toast.LENGTH_SHORT).show();
		} else if (intent.getAction().equals(
				Constants.ACTION.STOPFOREGROUND_ACTION)) {
			Log.i(LOG_TAG, "Received Stop Foreground Intent");
			stopForeground(true);
			stopSelf();
		}
		return START_STICKY;
	}

	private void showNotification() {
		Intent notificationIntent = new Intent(this, MainActivity.class);
		notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
				| Intent.FLAG_ACTIVITY_CLEAR_TASK);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				notificationIntent, 0);

		Intent previousIntent = new Intent(this, ForegroundService.class);
		previousIntent.setAction(Constants.ACTION.PREV_ACTION);
		PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
				previousIntent, 0);

		Intent playIntent = new Intent(this, ForegroundService.class);
		playIntent.setAction(Constants.ACTION.PLAY_ACTION);
		PendingIntent pplayIntent = PendingIntent.getService(this, 0,
				playIntent, 0);

		Intent nextIntent = new Intent(this, ForegroundService.class);
		nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
		PendingIntent pnextIntent = PendingIntent.getService(this, 0,
				nextIntent, 0);

		Bitmap icon = BitmapFactory.decodeResource(getResources(),
				R.drawable.ic_launcher);

		Notification notification = new NotificationCompat.Builder(this)
				.setContentTitle("TutorialsFace Music Player")
				.setTicker("TutorialsFace Music Player")
				.setContentText("My song")
				.setSmallIcon(R.drawable.ic_launcher)
				.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
				.setContentIntent(pendingIntent)
				.setOngoing(true)
				.addAction(android.R.drawable.ic_media_previous, "Previous",
						ppreviousIntent)
				.addAction(android.R.drawable.ic_media_play, "Play",
						pplayIntent)
				.addAction(android.R.drawable.ic_media_next, "Next",
						pnextIntent).build();
		startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
				notification);

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.i(LOG_TAG, "In onDestroy");
		Toast.makeText(this, "Service Detroyed!", Toast.LENGTH_SHORT).show();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// Used only in case if services are bound (Bound Services).
		return null;
	}
}

 
When we simply extend a java class to Service then we have to implement the method onBind(). But this method nBind() is only used when our Service is bounded to our Activity. You can learn more about Bounded Services which are used when we need our service to communicate with our activity.

We have also implemented onDestroy() to get notified by a Toast that our service has been destroyed.

For now we just need to start a foreground service and be notified that our service is running in the background. So to show that our service is still running in the background, we have created a notification inside ForegroundService.java class.

We have to override onStartCommand() method inside our service class. onStartCommand() is called every time we start a service by calling startService() inside Activity.
The Notification to show that our service is running is implemented inside the method showNotification(). This method is called in onStartCommand() based on the Action i.e Constants.ACTION.STARTFOREGROUND_ACTION provided via intent while calling startService().

Similar to starting the Service, we have added different action conditions and based on them, different actions are performed in onStartCommand(). We have defined all those action by declare String constants in another class named Constants.java

The content for Constants.java :

package com.tutorialsface.example.foregroundservice;

public class Constants {


	public interface ACTION {
		public static String MAIN_ACTION = "com.marothiatechs.foregroundservice.action.main";
		public static String INIT_ACTION = "com.marothiatechs.foregroundservice.action.init";
		public static String PREV_ACTION = "com.marothiatechs.foregroundservice.action.prev";
		public static String PLAY_ACTION = "com.marothiatechs.foregroundservice.action.play";
		public static String NEXT_ACTION = "com.marothiatechs.foregroundservice.action.next";
		public static String STARTFOREGROUND_ACTION = "com.marothiatechs.foregroundservice.action.startforeground";
		public static String STOPFOREGROUND_ACTION = "com.marothiatechs.foregroundservice.action.stopforeground";
	}

	public interface NOTIFICATION_ID {
		public static int FOREGROUND_SERVICE = 101;
	}
}

As we are using a service inside our android application, we need to declare that service inside AndroidManifest.xml

Add the declaration of service in AndroidManifest.xml as shown below:

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <service android:name=".ForegroundService" >
        </service>
    
    </application>

</manifest>

Now run the application and test the results.
The screenshot of the application:

Foreground Service App Screenshot

Foreground Service App

Foreground Service notification

Foreground Service notification

20,232 total views, 43 views today

(Visited 16,757 times, 33 visits today)
  • Sunook Niklane Choi

    thanks a lot!

    • Laxman Marothiya

      Welcome ☺️

  • Junmo Kim

    which file is playing music in this example?

    • Максим Моторный

      This example is not about music player. It’s about foreground service with notification.

  • Pradyut Bhattacharya

    that was really helpful. Cheers 🙂

  • Dalila HAMIDOUCHE

    hello

    can any one plz explain to me the class “Constants” ? what’s “com.marothiatechs.foregroundservice.” ?????

    thank you

    • Максим Моторный

      It’s just simple unique string.

      • Dalila HAMIDOUCHE

        Thank you

  • http://about.me/eazyigz Igor Ganapolsky

    What do you mean by ~”parent application is closed”? When user presses the back button to go home?

  • Nikola Djukic

    Is foreground service, a good solution for tracking user’s sports activity?

    • Максим Моторный

      I think no, because it will drain battery too fast. Maybe JobScheduler will be suitable for you