Tag

foreground service android example

Browsing

In this post, I will explain the foreground service android in Kotlin. We’ll see the real implementation of foreground service. So let’s get started.

In the previous Foreground Service tutorial, I have explained about Foreground Service? and the advantage of Foreground Service. Basically the previous article is based on Java. In this android app tutorial, we’ll learn how to implement is Kotlin.

Steps of implementation Foreground Service

  • Create and Project Setup
  • Create a derived class of Service named is ForegroundService.kt
  • Make Notification Channel
  • Override methods
    • onStartCommand
      • mandatory
    • onBind
      • mandatory
      • must return null
    • onCreate
      • optional to override
      • call only once when Service is being created
    • onDestory
      • optional to override
      • Call when background service is destroyed
  • Declare your service and permission in AndroidManifest.xml
1. Create and Project Setup

Let’s open the Android Studio and create a new project with Kotlin. In this demo, I’m using androidx artifact for this sample project.

2. Create a subclass of Service name is ForegroundService.kt
package com.foregroundservice

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat

class ForegroundService : Service() {
  private val CHANNEL_ID = "ForegroundService Kotlin"

  companion object {

    fun startService(context: Context, message: String) {
      val startIntent = Intent(context, ForegroundService::class.java)
      startIntent.putExtra("inputExtra", message)
      ContextCompat.startForegroundService(context, startIntent)
    }

    fun stopService(context: Context) {
      val stopIntent = Intent(context, ForegroundService::class.java)
      context.stopService(stopIntent)
    }
  }

  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

    //do heavy work on a background thread
    val input = intent?.getStringExtra("inputExtra")
    createNotificationChannel()
    val notificationIntent = Intent(this, MainActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        this,
        0, notificationIntent, 0
    )

    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("Foreground Service Kotlin Example")
        .setContentText(input)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentIntent(pendingIntent)
        .build()

    startForeground(1, notification)
    //stopSelf();
    return START_NOT_STICKY
  }

  override fun onBind(intent: Intent): IBinder? {
    return null
  }

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

      val manager = getSystemService(NotificationManager::class.java)
      manager!!.createNotificationChannel(serviceChannel)
    }
  }
}

In this source file, we are doing two things. first, one is we are creating notification channel. The second part is starting foreground service, So its take two parameters id and notification instance for showing the notification.

You guys well know after android oreo imposed some implication on service. As per Android Developer team, you can’t perform long-running operations in the background without notifying users. That by we are pass notification object inside the startForeground() method.

3. Declare your service and permission in AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.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">
    </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>

4. Add a button inside activity_main.xml layout

Let’s open the activity_main.xml file. I make some changes to test foreground service.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    >

  <androidx.appcompat.widget.AppCompatTextView
      android:id="@+id/buttonStart"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginEnd="8dp"
      android:layout_marginLeft="8dp"
      android:layout_marginRight="8dp"
      android:layout_marginStart="8dp"
      android:layout_marginTop="220dp"
      android:background="@color/colorPrimary"
      android:padding="8dp"
      android:text="Start Service"
      android:textColor="@color/colorWhite"
      android:textSize="18sp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.498"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      />
  <androidx.appcompat.widget.AppCompatTextView
      android:id="@+id/buttonStop"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginEnd="8dp"
      android:layout_marginLeft="8dp"
      android:layout_marginRight="8dp"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:background="@color/colorPrimary"
      android:padding="8dp"
      android:onClick="onStopServiceClick"
      android:text="Stop Service"
      android:textColor="@color/colorWhite"
      android:textSize="18sp"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.498"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/buttonStart"
      app:layout_constraintVertical_bias="0.113"
      />

</androidx.constraintlayout.widget.ConstraintLayout>

5. For testing, foreground service paste below code in MainActivity

package com.foregroundservice

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.buttonStart
import kotlinx.android.synthetic.main.activity_main.buttonStop

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    buttonStart.setOnClickListener(View.OnClickListener {
      ForegroundService.startService(this, "Foreground Service is running...")
    })
    buttonStop.setOnClickListener(View.OnClickListener {
      ForegroundService.stopService(this)
    })
  }
}

Conclusion

Now your job is done, In this post, we learned foreground service implementation in Kotlin. Let’s run the project, 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.

Keep in touch

If you want to keep in touch and get an email when I write new blog posts, follow me on facebook or subscribe usIt only takes about 10 seconds to register. 

Still, if you have any queries please put your comment below.

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.

What is Foreground Service

For more clarity let’s takes example 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 pause the music or play 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.

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

Android Foreground Service Example in Kotlin