/android-foreground-service

βš™οΈ π™΅πš˜πš›πšŽπšπš›πš˜πšžπš—πš πšœπšŽπš›πšŸπš’πšŒπšŽ 𝚝𝚘 πš›πšžπš— πšŠπš— πš’πš—πšπš’πš—πš’πšπšŽ πšπšŠπšœπš” πš’πš— πšŠπš—πšπš›πš˜πš’πš

Primary LanguageKotlinApache License 2.0Apache-2.0

πšŠπš—πšπš›πš˜πš’πš-πšπš˜πš›πšŽπšπš›πš˜πšžπš—πš-πšœπšŽπš›πšŸπš’πšŒπšŽ

Android-App-Development-With-Kotlin

βš™οΈ π™΅πš˜πš›πšŽπšπš›πš˜πšžπš—πš πšœπšŽπš›πšŸπš’πšŒπšŽ 𝚝𝚘 πš›πšžπš— πšŠπš— πš’πš—πšπš’πš—πš’πšπšŽ πšπšŠπšœπš” πš’πš— πšŠπš—πšπš›πš˜πš’πš

π™²π™Ύπ™½πšƒπ™΄π™½πšƒπš‚
What is a foreground service
Demo
Starting service from background
Creating a simple foreground service

What is a foreground service

  • In Android, a foreground service is a type of service that has a higher priority than regular background services.
  • It is designed to perform operations that are noticeable to the user, and its notification is shown to keep the user aware of ongoing tasks. When an app runs a foreground service, it is less likely to be killed by the system, even when resources are scarce.

Where a foreground service is used

  • Foreground services are often used for tasks that the user should be aware of and that have a visual or noticeable impact on the application.
  • For example, when an app is playing music in the background, downloading files, or providing navigation instructions, it might use a foreground service to ensure that the user is aware of these activities.

Why a foreground service is useful

  • The notification associated with a foreground service serves as a persistent visual indicator to the user, informing them that the app is running a foreground service.
  • This helps users understand why certain operations are ongoing, even when the app is not in the foreground.
  • It ensures that the user is informed about ongoing activities that might affect their interaction with the app.

Demo

demo.mp4

Starting service from background

  • Apps that target Android 12 or higher can't start foreground services while the app is running in the background, except for a few special cases.
  • If an app tries to start a foreground service while the app runs in the background, and the foreground service doesn't satisfy one of the exceptional cases, the system throws a ForegroundServiceStartNotAllowedException.

Creating a simple foreground service

Contents
Define the constants needed
Create a service class
Define the channel creation
Define the runtime permission
Define the permissions in the manifest
Declare the service tag in the manifest
Initiate start and stop actions from your UI

Define the constants needed

object Constants {
    const val NOTIFICATION_CHANNEL_ID = "STOPWATCH_NOTIFICATION_ID"
    const val NOTIFICATION_CHANNEL_NAME = "STOPWATCH_NOTIFICATION"
    const val NOTIFICATION_ID = 10
}

Create a service class

class StopwatchService : Service() {

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

    /**
     * This method is triggered when another Android component sends the intent to the running service
     */
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        when(intent?.action){
            Actions.START.toString() ->{
                start()
            }
            Actions.STOP.toString() ->{
                stopSelf()
            }
        }

        return super.onStartCommand(intent, flags, startId)
    }

    private fun start() {
        val notification = NotificationCompat
            .Builder(this,NOTIFICATION_CHANNEL_ID).setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("Stop Watch")
            .setContentText("Content of the notification")
            .build()

        startForeground(NOTIFICATION_ID,notification)
    }


    enum class Actions{
        START, STOP
    }

}

Define the channel creation

MyApplication.kt

class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        if(Build.VERSION.SDK_INT >= (Build.VERSION_CODES.O)){
            val channel = NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME ,
                NotificationManager.IMPORTANCE_HIGH
            )
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}

Define the runtime permission

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= (Build.VERSION_CODES.TIRAMISU)) {
            ActivityCompat.requestPermissions(
                this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0
            )
        }
        setContent {
            // Content
        }
    }
}

Define the permissions in the manifest

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

Declare the service tag in the manifest

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

    <!--- Define your permissions ---!>

    <application
        android:name=".MyApplication">
      
        <!-- Other codes -->

        <service
            android:name=".service.StopwatchService"
            android:foregroundServiceType="shortService"
            android:exported="false"/>

    </application>

</manifest>

Initiate start and stop actions from your UI

@Composable
fun CurrentScreen() {

    val context = LocalContext.current

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Button(onClick = {
            Intent(context,StopwatchService::class.java).also {
                it.action = StopwatchService.Actions.START.toString()
                context.startService(it)
            }
        }) {
            Text(text = "Start Service")
        }
        Button(onClick = {
            Intent(context,StopwatchService::class.java).also {
                it.action = StopwatchService.Actions.STOP.toString()
                context.startService(it)
            }
        }) {
            Text(text = "Stop Service")
        }
    }
}

πš‚πšžπš™πš™πš˜πš›πš β˜•

π™Έπš 𝚒𝚘𝚞 πšπšŽπšŽπš• πš•πš’πš”πšŽ πšœπšžπš™πš™πš˜πš›πš πš–πšŽ 𝚊 𝚌𝚘𝚏𝚏𝚎𝚎 πšπš˜πš› πš–πš’ πšŽπšπšπš˜πš›πšπšœ, 𝙸 πš πš˜πšžπš•πš πšπš›πšŽπšŠπšπš•πš’ πšŠπš™πš™πš›πšŽπšŒπš’πšŠπšπšŽ πš’πš.
π™±πšžπš’ π™ΌπšŽ 𝙰 π™²πš˜πšπšπšŽπšŽ

π™²πš˜πš—πšπš›πš’πš‹πšžπšπšŽ πŸ™‹β€β™‚οΈ

𝚁𝚎𝚊𝚍 πšŒπš˜πš—πšπš›πš’πš‹πšžπšπš’πš˜πš— πšπšžπš’πšπšŽπš•πš’πš—πšŽπšœ πšπš˜πš› πš–πš˜πš›πšŽ πš’πš—πšπš˜πš›πš–πšŠπšπš’πš˜πš— πš›πšŽπšπšŠπš›πšπš’πš—πš πšŒπš˜πš—πšπš›πš’πš‹πšžπšπš’πš˜πš—.

π™΅πšŽπšŽπšπš‹πšŠπšŒπš” ✍️

π™΅πšŽπšŠπšπšžπš›πšŽ πš›πšŽπššπšžπšŽπšœπšπšœ πšŠπš›πšŽ πšŠπš•πš πšŠπš’πšœ πš πšŽπš•πšŒπš˜πš–πšŽ, π™΅πš’πš•πšŽ πšŠπš— πš’πšœπšœπšžπšŽ πš‘πšŽπš›πšŽ.

π™΅πš’πš—πš πšπš‘πš’πšœ πš™πš›πš˜πš“πšŽπšŒπš πšžπšœπšŽπšπšžπš• ? ❀️

πš‚πšžπš™πš™πš˜πš›πš πš’πš πš‹πš’ πšŒπš•πš’πšŒπš”πš’πš—πš πšπš‘πšŽ ⭐ πš‹πšžπšπšπš˜πš— πš˜πš— πšπš‘πšŽ πšžπš™πš™πšŽπš› πš›πš’πšπš‘πš 𝚘𝚏 πšπš‘πš’πšœ πš™πšŠπšπšŽ. ✌️

π™»πš’πšŒπšŽπš—πšœπšŽ Licence πŸ’³

πšƒπš‘πš’πšœ πš™πš›πš˜πš“πšŽπšŒπš πš’πšœ πš•πš’πšŒπšŽπš—πšœπšŽπš πšžπš—πšπšŽπš› πšπš‘πšŽ π™°πš™πšŠπšŒπš‘πšŽ π™»πš’πšŒπšŽπš—πšœπšŽ 𝟸.𝟢 - 𝚜𝚎𝚎 πšπš‘πšŽ π™»π™Έπ™²π™΄π™½πš‚π™΄ πšπš’πš•πšŽ πšπš˜πš› πšπšŽπšπšŠπš’πš•πšœ.