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.

  1. There are 2 buttons in the Android app. When you click the START FOREGROUND SERVICE button, it will create and start a foreground service.
  2. 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.
  3. There are two buttons in the notification, clicking 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.
  4. You can see this example demo video at the end of this article page.

2. Example Source Code.

  1. The below source files are the example project files.
    D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\EXAMPLE
    │
    ├─app
    │  │
    │  └─src
    │      │
    │      ├─main
    │      │  │  AndroidManifest.xml
    │      │  │
    │      │  ├─java
    │      │  │  └─com
    │      │  │      └─dev2qa
    │      │  │          └─example
    │      │  │              ├─service
    │      │  │              │  ├─foreground
    │      │  │              │  │      CreateForegroundServiceActivity.java
    │      │  │              │  │      MyForeGroundService.java
    │      │  │
    │      │  └─res
    │      │      ├─layout
    │      │      │      activity_create_foreground_service.xml
    
  2. There are two java files in this example MyForeGroundService.java & CreateForegroundServiceActivity.java.
  3. 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.
  4. In the onStartCommand method, it will check which button has been pressed by the intent.getAction() method returned value, and then invokes a related method such as startForegroundService().
  5. In the startForegroundService() method, to make the service object run 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);
  6. In the stopForegroundService() method, it will stop the MyForeGroundService service object from the 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.
  7. CreateForegroundServiceActivity.java: This is the activity class java file. It will be created when the android app starts. It will listen to the two buttons on-click event, and when one button is clicked, it will start the MyForeGroundService object by creating an Intent object, setting the intent object action, and then calling the 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.
  2. 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
  3. You can see this example demo video on URL https://youtube.com/shorts/RVBESdVwZu8?feature=share.

2 thoughts on “Android Foreground Service Example”

  1. 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”.

    1. 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)
      }

Leave a Comment

Your email address will not be published. Required fields are marked *

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