はじめに
通常のサービスには制限がありますが、フォアグラウンドサービスにすることにより制限を緩和できます。
実装
次のコードは通常のサービスの実装です。
class MyService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}
}
それに対して次のコードはフォアグラウンドサービスの実装です。
class MyService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val CHANNEL_ID = "asdf"
// Android 8.0 以降では必ず通知チャネルを作成する必要がある
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val mChannel =
NotificationChannel(
CHANNEL_ID,
"ここが通知チャネル名として表示される",
NotificationManager.IMPORTANCE_DEFAULT,
)
mChannel.apply {
description = "ここが通知チャネルの説明として表示される"
}
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
// 既存の通知チャネルを作成しても問題ない
manager.createNotificationChannel(mChannel)
}
// Android 8.0 よりも前では `CHANNEL_ID` は無視される
val notification = NotificationCompat.Builder(this, CHANNEL_ID).build()
startForeground(1, notification)
return START_STICKY
}
}
通知チャネルと通知を作成し、startForeground()
に通知を渡しています。この通知はサービス起動中は常に通知領域に表示されます。
フォアグラウンドサービスを生成する側では、次の2行のコードを実行するだけでOKです。
val intent = Intent(this, MyService::class.java)
startForegroundService(intent)
通知チャネルの注意点
- 一度作成した通知チャネルの名前、説明文、優先度は変更できない
- フォアグラウンドサービスを起動するだけであれば
setSmallIcon
は必須ではない(通常の通知では必須) - ただし、
setSmallIcon
を設定しないとsetContentTitle
とsetContentText
の設定は反映されない