この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ユーザが任意のタイミングでForeground Serviceを終了したいとき、アプリを起動して操作するのは地味に手間です。 そこで、通知に「停止する」ボタンを表示して、そのボタンをタップしたらForeground Serviceを停止させてみました。
環境
- Android Studio 3.6
- Pixcel 3a (Android 10)
サンプルアプリを作ってみる
下記の続きから作成していきます。
ブロードキャストを受信するクラスを作成
通知の停止するボタンが選択されたことを受け取るブロードキャストレシーバーとして、LocationBroadcastReceiver.kt
を新規作成します。
onReceive()
でstopService()
を呼んでForeground Serviceを停止させます。
LocationBroadcastReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class LocationBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val targetIntent = Intent(context, LocationService::class.java)
context.stopService(targetIntent)
}
}
AndroidManifestファイルにブロードキャストレシーバークラスを追加
AndroidManifest.xml
にreceiver
を追加します。
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.test.tryforegroundservicesample">
...
<application ...>
<activity android:name=".MainActivity">
...
</activity>
<service android:name=".LocationService" />
<receiver android:name=".LocationBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="jp.test.tryforegroundservicesample.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
- マニフェストで宣言されたレシーバー
- <action> | Android デベロッパー | Android Developers
- <category> | Android デベロッパー | Android Developers
- 暗黙的インテントを受け取る
通知表示に「停止する」ボタンを追加する
ForegroundServiceとして動くLocationService.kt
で作成している通知に「停止する」ボタンを追加します。
LocationService.kt
class LocationService : Service() {
...
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
...
val openIntent = Intent(this, MainActivity::class.java).let {
PendingIntent.getActivity(this, 0, it, 0)
}
val sendIntent = Intent(this, LocationBroadcastReceiver::class.java).apply {
action = ACTION_SEND
}
val sendPendingIntent = PendingIntent.getBroadcast(this, 0, sendIntent, 0)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("位置情報テスト")
.setContentText("位置情報を取得しています...")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(openIntent)
.addAction(R.drawable.ic_launcher_foreground, "停止する", sendPendingIntent)
.build()
startForeground(9999, notification)
startLocationUpdates()
return START_STICKY
}
}
動作確認
アプリをビルドして起動し、「START」ボタンを押すと、通知が表示されます。
ログもしっかり出力されています。
[1] 35.xxxx , 139.yyyy
[2] 35.xxxx , 139.yyyy
[3] 35.xxxx , 139.yyyy
この状態で通知にある「停止する」ボタンを押すと、通知が消えてログの出力も止まりました!
さいごに
Foreground Service実行時に表示される通知画面にボタンを追加し、そのボタンを選択するとForeground Serviceを終了させてみました。
BroadcastReceiver
なるものまで登場し、色々と絡み合っているんだなぁと思いつつ、BroadcastReceiver
についても分かりました。
どなたかの参考になれば幸いです。