Android & Kotlin

Foreground Service Android Example

Pinterest LinkedIn Tumblr

In this tutorial, I will explain about foreground service android, How does work? What are the advantages and implementation? At last, I will prepare a foreground service sample app. So let’s get started. If you are looking Kotlin solution please have a look our another post is Foreground Service Android Example in Kotlin

What is Foreground Service

For more clarity let’s take example of Gmail, You are just using Gmail app and listening to music that is being played by Music Player application. So Music Player is basically using the foreground service to play the music. The foreground service always uses the notification to notify the user and using the notification you can actually interact with the service or the ongoing operation such as pausing the music or playing the next music.

So whenever in your app you see a notification that is performing some long running tasks that service is basically the foreground service and Foreground Service is always noticeable to the user that is the user is aware of this ongoing process.

Step up to writing implementation

  • Initial Project Setup
  • Create a subclass of Service – ForgroundService.java
  • Create Notification Channel
  • Override methods
    • onStartCommand
      • Mandatory to override for Foreground Service
    • onBind
      • Mandatory to override for Foreground Service
      • Must return null for Foreground Service
    • onCreate
      • Optional to override
      • Call only once, when Service is being created for the first time
    • onDestory
      • Optional to override
      • Call when background service is destroyed
  • Declare your service in Manifest.xml

Foreground Service Android Example (Demo App)

1. Initial Project Setup

Let’s move to Android Studio and create a new project with EmptyActivity template. Here I’m using package name is com.wave.foregroundservice. You can use as per your project need

2. Create a subclass of Service – ForgroundService.java

Just create a subclass of Service class in main package and override necessary methods.

package com.wave.foregroundservice;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;

public class ForegroundService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String input = intent.getStringExtra("inputExtra");
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(1, notification);

        //do heavy work on a background thread


        //stopSelf();

        return START_NOT_STICKY;
    }

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

3. Create Notification Channel

For creating Notification Channel add below code in Foreground Service class

private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }

Full Source code of ForegroundService.java

package com.wave.foregroundservice;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;

public class ForegroundService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String input = intent.getStringExtra("inputExtra");
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(1, notification);

        //do heavy work on a background thread


        //stopSelf();

        return START_NOT_STICKY;
    }

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }
}

4. Declare your service and add uses permission in Manifest.xml

Let’s open the AndroidManifest file, In this file, you have to add two things. first is to register the service inside the manifest. The second one is you need add uses permission FOREGROUND_SERVICE for android pie.

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

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

    <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">
        <service
            android:name=".ForegroundService"
            android:enabled="true"
            android:exported="true"></service>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

5. Modify actviity_main.xml

Go to res=> layout and open activity_main.xml, I’m adding 2 button this layout one for start service another one for stop service.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/buttonStartService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:background="@color/colorAccent"
        android:padding="16dp"
        android:text="Start Service"
        android:textColor="#fff"
        app:layout_constraintBottom_toTopOf="@+id/buttonStopService"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />

    <Button
        android:id="@+id/buttonStopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="@color/colorAccent"
        android:padding="16dp"
        android:text="Stop Service"
        android:textColor="#fff"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonStartService"
        app:layout_constraintVertical_bias="0.218" />
</android.support.constraint.ConstraintLayout>

6. Open MainActivity and add onClickListener on button

Let’s open MainActivity from src folder and add below code

package com.wave.foregroundservice;

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

public class MainActivity extends AppCompatActivity {
    Button btnStartService, btnStopService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStartService = findViewById(R.id.buttonStartService);
        btnStopService = findViewById(R.id.buttonStopService);

        btnStartService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService();
            }
        });

        btnStopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService();
            }
        });
    }

    public void startService() {
        Intent serviceIntent = new Intent(this, ForegroundService.class);
        serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");

        ContextCompat.startForegroundService(this, serviceIntent);
    }

    public void stopService() {
        Intent serviceIntent = new Intent(this, ForegroundService.class);
        stopService(serviceIntent);
    }
}

Conclusion

Now your job is done, Your foreground service code is ready to run. Let’s run the project, Your app is up and running. While you click on ‘start service’ button than service will be started, and notification will appear on notification bar. Notification will disappear once you clicked on ‘stop service’ button.

I hope it’s helpful for you, then help me by sharing this post with all your friends who learning android app development.

Download Source Code

If you have any queries, feel free to ask them in the comment section below. Happy Coding 🙂

Android Foreground Service Example in Kotlin

28 Comments

  1. Jeff Jones Reply

    Thanks so much! Well done. Working on my Android S9+. One issue, stopService() does not remove the notification. Is there another step to do that?

  2. Thank you so much, I’ve been searching for an updated example and even official docs use deprecated methods or are very unclear. Thanks for this!!

  3. Eduardo Sánchez Reply

    Thanks, very simple and clear to understand, it works perfect!
    Eduardo

  4. João Clobocar Reply

    Thanks. This article helped me a lot.
    I could start a foreground service and my App is not killed anymore by the system.

  5. why don’t you post this sample on github ??????
    it only takes your 2 minutes bro but it saves our life 🙂
    plz post the github link in the end of every article.

  6. Beyond Android 9, you need to add permission in manifest.

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

     

  7. Cis myname Reply

    This doesnt seem to work if you replace the imports;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.content.ContextCompat;

    with androidx like we are supposed to for updated OS
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.content.ContextCompat;

  8. Hoi Fei Kwok Reply

    No, it doesn’t work on pie even I have set the permission and used contextcompat.startforegroundservice.

  9. Mantosh Kumar Reply

    It’s not working for mi phone when app is kill from background then notification is also killed.

    • will look into it. can you share device details such as model name and OS version

  10. Nice article on Foreground Service.
    I want my app to run whole night (say 8 hours), I am using sensors to detect motion using the service which is foreground with notification (also used start_sticky with all higher priorities notifications options) .
    But in the morning it doesn’t response (for my motion data calculations) until I turn on the screen.
    I am sure no any external app or setting (by phone manufacturer) is hibernating my app.
    What more I need to add, do I need to implement wakelockes or anything to keep the phone cpu on?
    Please suggest me an optimum workaround.
    Thanks!

  11. Hi, Thanks for your good article.
    But this crashs on android pie by pressing the startService button, and I dont know how to fix that.
    Do you have a solution for this?!

    • you need to add the permissions for the foreground service in your android manifest.xml

    • Nauman Zafar

      Instead of startService use
      ContextCompat.startForegroundService(mContext, intent1);
      because startService is used for pre-oreo and for oreo and above startForegroundService is used.

  12. Pronab Pal Reply

    Good example; Just to add , for Android 9 onwards the manifest would need :

  13. Steve Palmer Reply

    Thanks for the example. Unfortunately, on a Android Pie, after pressing the Start Service button the app stops with Android reporting “foregroundservice keeps stopping”. This is the same problem I’m having with my app. I wonder if something is different with Android Pie?

    Yup – just tried it on Android Orio and it works fine!

    • Nuno Diogo

      you need to add the permissions for the foreground service in your android manifest.xml:

Write A Comment