Android Foreground Service Example

Android foreground service is an android service object. It always runs in the foreground, this can avoid service objects being recycled by the android system when android os does not have enough resources. Android foreground service can interact with users through notification. It is usually used in a music player, file downloader, etc which user has few interactions with the player service but the service should not be stopped and recycled.

1. Android Foreground Service Example.

There are 2 buttons in the Android app. When you click the START FOREGROUND SERVICE button, it will create and start a foreground service. The foreground service will show a head-up notification which will pop up at the screen top with max priority. The notification is also a text-style notification.

There are two buttons in the notification, click each button will display a toast message at the screen bottom. When you click the STOP FOREGROUND SERVICE button, it will stop the service and remove the notification.

2. Example Source Code.

android-foreground-service-file-structure

There are two java files in this example. MyForeGroundService.java & CreateForegroundServiceActivity.java.

  1. MyForeGroundService.java: This is the android foreground service class. It overrides the android.app.Service.onStartCommand(Intent intent, int flags, int startId) method. This method will be invoked when the activity invokes the startService(intent) method.
  2. In the onStartCommand method, it will check which button has been pressed by intent.getAction() method returned value, and then invokes a related method such as startForegroundService().
  3. In the startForegroundService() method, to make the service object running in the foreground, it will create a Notification object, and then call the startForeground() method to make the service object run as foreground service.
    // Build the notification. 
    Notification notification = builder.build(); 
    
    // Start foreground service. 
    startForeground(1, notification);
  4. In the stopForegroundService() method, it will stop the MyForeGroundService service object from foreground service by invoking the stopForeground(true) method, this will also remove the notification object. Then it will call the stopSelf() method to stop the service object.
  5. CreateForegroundServiceActivity.java: This is the activity class java file. It will be created when the android app starts. It will listen on the two buttons on-click event, and when one button is clicked, it will start the MyForeGroundService object by creating an Intent object, set the intent object action, and then call startService(intent) method to start the service object. Then the MyForeGroundService object will be created, and its onStartCommand method will be invoked.

2.1 Android Foreground Service Class.

MyForeGroundService.java

package com.dev2qa.example.service.foreground;

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.util.Log;
import android.widget.Toast;
import android.support.v7.app.NotificationCompat;

import com.dev2qa.example.R;

public class MyForeGroundService extends Service {

    private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";

    public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";

    public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";

    public static final String ACTION_PAUSE = "ACTION_PAUSE";

    public static final String ACTION_PLAY = "ACTION_PLAY";

    public MyForeGroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG_FOREGROUND_SERVICE, "My foreground service onCreate().");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent != null)
        {
            String action = intent.getAction();

            switch (action)
            {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();
                    Toast.makeText(getApplicationContext(), "Foreground service is started.", Toast.LENGTH_LONG).show();
                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:
                    stopForegroundService();
                    Toast.makeText(getApplicationContext(), "Foreground service is stopped.", Toast.LENGTH_LONG).show();
                    break;
                case ACTION_PLAY:
                    Toast.makeText(getApplicationContext(), "You click Play button.", Toast.LENGTH_LONG).show();
                    break;
                case ACTION_PAUSE:
                    Toast.makeText(getApplicationContext(), "You click Pause button.", Toast.LENGTH_LONG).show();
                    break;
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    /* Used to build and start foreground service. */
    private void startForegroundService()
    {
        Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");

        // Create notification default intent.
        Intent intent = new Intent();
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        // Create notification builder.
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

        // Make notification show big text.
        NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
        bigTextStyle.setBigContentTitle("Music player implemented by foreground service.");
        bigTextStyle.bigText("Android foreground service is a android service which can run in foreground always, it can be controlled by user via notification.");
        // Set big text style.
        builder.setStyle(bigTextStyle);

        builder.setWhen(System.currentTimeMillis());
        builder.setSmallIcon(R.mipmap.ic_launcher);
        Bitmap largeIconBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_music_32);
        builder.setLargeIcon(largeIconBitmap);
        // Make the notification max priority.
        builder.setPriority(Notification.PRIORITY_MAX);
        // Make head-up notification.
        builder.setFullScreenIntent(pendingIntent, true);

        // Add Play button intent in notification.
        Intent playIntent = new Intent(this, MyForeGroundService.class);
        playIntent.setAction(ACTION_PLAY);
        PendingIntent pendingPlayIntent = PendingIntent.getService(this, 0, playIntent, 0);
        NotificationCompat.Action playAction = new NotificationCompat.Action(android.R.drawable.ic_media_play, "Play", pendingPlayIntent);
        builder.addAction(playAction);

        // Add Pause button intent in notification.
        Intent pauseIntent = new Intent(this, MyForeGroundService.class);
        pauseIntent.setAction(ACTION_PAUSE);
        PendingIntent pendingPrevIntent = PendingIntent.getService(this, 0, pauseIntent, 0);
        NotificationCompat.Action prevAction = new NotificationCompat.Action(android.R.drawable.ic_media_pause, "Pause", pendingPrevIntent);
        builder.addAction(prevAction);

        // Build the notification.
        Notification notification = builder.build();

        // Start foreground service.
        startForeground(1, notification);
    }

    private void stopForegroundService()
    {
        Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");

        // Stop foreground service and remove the notification.
        stopForeground(true);

        // Stop the foreground service.
        stopSelf();
    }
}

2.2 Main Activity.

CreateForegroundServiceActivity.java

package com.dev2qa.example.service.foreground;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.dev2qa.example.R;

public class CreateForegroundServiceActivity extends AppCompatActivity{ // implements View.OnClickListener{

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

        setTitle("dev2qa.com - Android Foreground Service Example.");

        Button startServiceButton = (Button)findViewById(R.id.start_foreground_service_button);
        startServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
                intent.setAction(MyForeGroundService.ACTION_START_FOREGROUND_SERVICE);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                     startForegroundService(intent);
                } else {
                     startService(intent);
                }
            }
        });

        Button stopServiceButton = (Button)findViewById(R.id.stop_foreground_service_button);
        stopServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
                intent.setAction(MyForeGroundService.ACTION_STOP_FOREGROUND_SERVICE);
               
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                     startForegroundService(intent);
                } else {
                     startService(intent);
                }     
            }
        });
    }
}

2.3 Layout Xml File.

activity_create_foreground_service.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <Button
        android:id="@+id/start_foreground_service_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Foreground Service"/>

    <Button
        android:id="@+id/stop_foreground_service_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Foreground Service"/>

</LinearLayout>

2.4 Android Manifest Xml File.

AndroidManifest.xml

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

    <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/AppTheme">
        
        <!-- Declare foreground service -->
        <service
            android:name=".service.foreground.MyForeGroundService"
            android:enabled="true"
            android:exported="true" />

        <!-- Declare activity -->
        <activity android:name=".service.foreground.CreateForegroundServiceActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

2.5 Assign FOREGROUND_SERVICE Permission.

If your android app os version is higher than or equal to level 26, you need to assign FOREGROUND_SERVICE permission in your android app to avoid crashes. To implement this, you should add the below XML snippet in the AndroidManifest.xml file.

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Reference

  1. Android Custom Notification Example
  2. How To Create, Start, Stop Android Background Service
1 1 vote
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Pawan Shahani
Pawan Shahani

This gives error for Android O & above versions.
I am facing error as : Developer warning for package “com.xxx.xxx”. Failed to post notification on channel “null”.

Dara Dalton
Dara Dalton
Reply to  Pawan Shahani

Android O Need Notification Channel like that

private fun startForegroundService(){
Log.d(TAG_FOREGROUND_SERVICE, “Start foreground service.”)

// Create notification default intent.
val intent = Intent()
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

val channelId = “NOTIFICATION_CHANNEL_NAME”

// Create notification builder.
val builder = NotificationCompat.Builder(this,channelId)

// Make notification show big text.
val bigTextStyle = NotificationCompat.BigTextStyle()
bigTextStyle.setBigContentTitle(“Music player implemented by foreground service.”)
bigTextStyle.bigText(“Android foreground service is a android service which can run in foreground always, it can be controlled by user via notification.”)
// Set big text style.
builder.setStyle(bigTextStyle)

builder.setWhen(System.currentTimeMillis())
builder.setSmallIcon(R.mipmap.ic_launcher)
val largeIconBitmap = BitmapFactory.decodeResource(resources, R.drawable.abc_ic_ab_back_material)
builder.setLargeIcon(largeIconBitmap)
// Make the notification max priority.
builder.priority = Notification.PRIORITY_MAX
// Make head-up notification.
builder.setFullScreenIntent(pendingIntent, true)

// Add Play button intent in notification.
val playIntent = Intent(this, MyForeGroundService::class.java)
playIntent.action = ACTION_PLAY
val pendingPlayIntent = PendingIntent.getService(this, 0, playIntent, 0)
val playAction = NotificationCompat.Action(android.R.drawable.ic_media_play, “Play”, pendingPlayIntent)
builder.addAction(playAction)

// Add Pause button intent in notification.
val pauseIntent = Intent(this, MyForeGroundService::class.java)
pauseIntent.action = ACTION_PAUSE
val pendingPrevIntent = PendingIntent.getService(this, 0, pauseIntent, 0)
val prevAction = NotificationCompat.Action(android.R.drawable.ic_media_pause, “Pause”, pendingPrevIntent)
builder.addAction(prevAction)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId, “NOTIFICATION_CHANNEL_NAME”,
NotificationManager.IMPORTANCE_HIGH
).apply {
enableLights(true)
lightColor = Color.DKGRAY
setShowBadge(true)
enableVibration(true)
vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
}
notificationManager.createNotificationChannel(channel)
}
// Build the notification.
val notification = builder.build()

// Start foreground service.
startForeground(1, notification)
}

2
0
Would love your thoughts, please comment.x
()
x