test foreground service

Foreground Services in Android, Kotlin

What is a foreground service in android?

A foreground service runs in the background but must come with a notification, so the user knows it’s running on the OS.

It’s used for tasks the user should be aware of that shouldn’t be killed by the OS, such as tracking on a run or playing music, or looking for a ride.

Before writing a foreground service you should add foreground service permission in AndroidManifest.xml

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

Now create a very simple TestForegroundService

class TestForegroundService : Service() {

    companion object {
        var isServiceRunning = false

        const val ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE"
        const val ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE"
    }

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


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START_FOREGROUND_SERVICE -> {
                isServiceRunning = true
                startForegroundService()
            }
            ACTION_STOP_FOREGROUND_SERVICE -> {
                isServiceRunning = false
                stopForeground(true)
                stopSelf()
            }
        }
        return START_STICKY
    }

    private fun startForegroundService() {
        val pendingIntent = Intent(this, MainActivity::class.java).let {
            it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            PendingIntent.getActivity(this, 0, it, 0)
        }

        val notification = NotificationCompat.Builder(this, App.NOTIFICATION_CHANNEL_ID)
            .setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher_round)
            .setContentIntent(pendingIntent)
            .setContentTitle("TestForegroundService")
            .setContentText("This is content text of notification")
            .build()

        startForeground(1, notification)
    }

}

startForegroundService() will launch your service as a foreground service. It needs an ongoing sticky notification we created here.

You must create the Application class and notification channel before.

class App : Application() {
    companion object {
        const val NOTIFICATION_CHANNEL_ID = "YOUR_NOTIFICATION_CHANNEL_ID"
    }

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val serviceChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID, "Test Service Channel", NotificationManager.IMPORTANCE_DEFAULT)
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(serviceChannel)
        }
    }
}

Now add application into AndroidManifest.xml

    <application
        android:name=".App"
         ............>
</application>

Now launch service from an activity or a fragment like below.

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        binding.button.setOnClickListener {
            val serviceIntent = Intent(this, TestForegroundService::class.java)
            serviceIntent.action = TestForegroundService.ACTION_START_FOREGROUND_SERVICE
            startService(serviceIntent)
        }
    }
}

If an application class is not added in manifest and a notification channel is not created then you will get an error like below

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: info.androidboss.sample, PID: 17306
    android.app.RemoteServiceException: Bad notification for startForeground
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2005)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7664)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Whatever you do in this service will now be executed reliably in the background until you force stop the app from phone Settings.

Add TestForegroundService in AndroidManifest.xml

<application
........>

        <service
            android:name=".TestForegroundService"/>

</application>

Keep more alive foreground service by ignoring battery optimization – Read This Post By Clicking Here

chevron_left
chevron_right
0 0 votes
Article Rating

Leave a Reply

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x