in
Android
- 02 4月, 2019
[Android] Oreo、Pieで端末起動時にServiceを起動する方法
2019年4月時点での情報をメモしておきます。
今回はKotlinを使って記述します。
目的
端末の起動時に連動させてServiceを起動させたい。
対象
下記のバージョンで動作を確認済
Android 8.0 (Oreo)
Android 9.0 (Pie)
結論
“ACTION_LOCKED_BOOT_COMPLETED”インテントを受信するBroadcastReceiverを実装して、受信したときの処理の中でServiceを起動する。
ServiceはForegroundServiceで実装しなければならない。
【参考】
- ダイレクトブートのサポート … 端末起動時について
- バックグラウンド実行制限 … Service、Broadcastの制限事項について
- 通知チャネルの作成と管理 … 通知について
- Android 9.0 動作の変更点 … ForegroundServiceを実行するのに必要なパーミッションについて
- 既存のAndroidアプリのAndroid 9.0互換性確認方法 … Android 9.0での互換性確認について
サンプル
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
MyBroadcastReceiver.kt
今回はついでに暗黙的インテントを受信してみました。
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
// 端末起動時に送信されるインテント
Intent.ACTION_LOCKED_BOOT_COMPLETED -> {
val startService = Intent(context?.applicationContext, MyForegroundService::class.java)
// Context.startForegroundService()を使ってServiceを起動する
context?.startForegroundService(startService)
}
// ロック解除時のインテント
Intent.ACTION_USER_PRESENT -> {
println("ロックを解除しました")
}
}
}
}
MyForegroundService.kt
暗黙的インテントを受信できるようにレシーバーを登録してみました。
class MyForegroundService : Service() {
// 初期化を遅延できる
lateinit var mReceiver: BroadcastReceiver
override fun onCreate() {
super.onCreate()
// 暗黙的インテントを受け取るレシーバーを登録する
mReceiver = MyBroadcastReceiver()
val filter = IntentFilter()
// ロック解除時のインテント
filter.addAction(Intent.ACTION_USER_PRESENT)
registerReceiver(mReceiver, filter)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
//通知の設定をする。今回はお試しなので雑です。
val notification = Notification.Builder(this,"channelId")
.setContentTitle(applicationContext.getString(R.string.app_name))
.build()
val channel = NotificationChannel("channelId","channelName",NotificationManager.IMPORTANCE_DEFAULT)
channel.description = "description"
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
startForeground(1, notification)
return START_STICKY
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onDestroy() {
super.onDestroy()
// レシーバーを解除する
unregisterReceiver(mReceiver)
}
}
AndroidManifest.xml
permissionを追加する
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- Android 9.0(Pie)から必要 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
BroadcastReceiverとServiceを登録する
<receiver android:name=".MyBroadcastReceiver" android:directBootAware="true"> <intent-filter> <!-- 端末起動時のインテント --> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> </intent-filter> </receiver>
<service android:name=".MyForegroundService" android:directBootAware="true"> </service>


