Kotlin Foreground Service (KFS)

In this post I will explain about android foreground service in Kotlin. We will 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 advantages of Foreground Service. Basically the previous article is based on Java. In this android application tutorial, we will learn how to implement Kotlin.

Foreground Service implementation steps

  1. Create and Project Setup
  2. Create a derived class of Service named is ForegroundService.kt
  3. Create Notification Channel
  4. Override methods
  5. onStartCommand
  6. mandatory
  7. onBind
  8. mandatory
  9. must return null
  10. onCreate
  11. optional to override
  12. call only once when Service is being created
  13. onDestory
  14. optional to override
  15. Call when background service is destroyed
  16. Declare your service and permission in AndroidManifest.xml

Create and Setup Projects

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

Create a subclass of the Service named 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 do two things. First, we create a notification channel. The second part is to start the foreground service, So it takes two parameters id and notification instance to display the notification.

You know very well after android oreo enforced some implications on services. As per Android Dev team, you can’t perform long running operations in the background without notifying the user. That we are passing notification object inside startForeground() method.

Declare your services and permissions 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>

Add a button inside the activity_main.xml layout

Let's open the activity_main.xml file. I made some changes to test the 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>

For testing, paste the foreground service code below 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 work is done, In this post, we learned the implementation of foreground service in Kotlin. Let's run the project, you click on the 'start service' button than the service will start, and a notification will appear in the notification bar. The notification will disappear after you click on the 'stop service' button.

Source

https://androidwave.com/foreground-service-android-example-in-kotlin/


Post a Comment

Previous Next

نموذج الاتصال