Skip to content

Instantly share code, notes, and snippets.

@heronsanches
Last active October 16, 2020 14:10
Show Gist options
  • Save heronsanches/31a956ab5bac457f51c8c39deabc6d04 to your computer and use it in GitHub Desktop.
Save heronsanches/31a956ab5bac457f51c8c39deabc6d04 to your computer and use it in GitHub Desktop.
Foreground Service: starting and biding
/** You should start the service by calling
* [startForegroundService] for API >= [Build.VERSION_CODES.O] to be certain that the Android will
* not try to kill your service so soon. */
class SomeService : Service() {
private val serviceBinder = PrepareBackupBinder()
override fun onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createSomeNotificationChannel()
val notificationBuilder = applicationContext.basicNotificationBuilder(
notificationTitle, notificationChannelId
).apply {
setOngoing(true)
setAutoCancel(false)
}
startForeground(NOTIFICATION_ID, notificationBuilder.build())
}
}
override fun onBind(intent: Intent?): IBinder? = serviceBinder
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// do some work - remember that here is the Main Thread
return START_NOT_STICKY // return what is more accurate to you
}
fun somePublicFunctionToBeCalledFromBinder() {}
inner class SomeServiceBinder : Binder() {
fun service() = this@SomeService
}
}
// some place on your project
@RequiresApi(Build.VERSION_CODES.O)
fun Context.createSomeNotificationChannel() {
createNotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
CHANNEL_DESCRIPTION
)
}
fun Context.basicNotificationBuilder(title: String, channelId: String): NotificationCompat.Builder {
return NotificationCompat.Builder(applicationContext, channelId).apply {
setSmallIcon(R.drawable.icon)
setContentTitle(title)
}
}
fun Context.createNotificationChannel(
id: String, name: String, description: String
) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT).apply {
this.description = description
setSound(null, null)
}
notificationManager.createNotificationChannel(channel)
}
//################## activity ##################
// starting and binding the service
val intent = Intent(this, SomeService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(intent)
else startService(intent)
bindService(intent, someServiceConnection, 0)
// in this way you can communicate with the service
val someServiceConnection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as SomeService.SomeServiceBinder
binder.service().somePublicFunctionToBeCalledFromBinder()
}
override fun onServiceDisconnected(arg0: ComponentName) {}
}
//################## Manifest ##################
<!-- declaring the service as private -->
<service
android:name="...SomeService"
android:exported="false" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment