しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

WorkManagerを使ってバックグラウンド処理を行う

Androidアプリでバックグラウンド処理を行うためにWorkManagerを試してみました

まずはbuild.gradle.ktsにライブラリを追加します

implementation("android.arch.work:work-runtime-ktx:1.0.1")

次にWorkerを継承したクラスを作成します
doWorkメソッドの中がバックグラウンドで呼ばれる処理になります

class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        Log.d("MyWorker", "バックグラウンド処理を実行中")

        return Result.success()
    }
}

次は先程のWorkerを使ったRequestを作ってバックグラウンド処理を行います
MainActivityのonPauseに下のような処理を追加します

val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
    .setInitialDelay(10, TimeUnit.SECONDS)
    .build()
WorkManager.getInstance().enqueue(workRequest)

そうするとアプリが閉じて10秒後にログが出力されます

上記を使って通知も送る事が可能です
まずはAndroidManifest.xmlにパーミッションの記述を追加します

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

次は下のようにdoWorkに通知処理を追加すれば通知を送る事ができます

val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (notificationManager.getNotificationChannel("test") == null) {
    val mChannel = NotificationChannel("test", "name", NotificationManager.IMPORTANCE_HIGH)
    mChannel.apply {
        description = "説明"
    }
    notificationManager.createNotificationChannel(mChannel)
}

val notification = NotificationCompat.Builder(applicationContext, "test").apply {
    setContentText("テスト")
    setSmallIcon(android.R.drawable.btn_plus)
}.build()
notificationManager.notify(0, notification)

OneTimeWorkRequestBuilderの代わりにPeriodicWorkRequestBuilderを使う事で繰り返しのバックグラウンド処理を行う事ができます
設定できる間隔は15分が最小になります

val workRequest = PeriodicWorkRequestBuilder<MyWorker>(30, TimeUnit.MINUTES).build()

次はWorkerに値を渡します
OneTimeWorkRequestBuilderのsetInputDataメソッドで下のように値をセットします

val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
    .setInitialDelay(10, TimeUnit.SECONDS)
    .setInputData(workDataOf("key" to "value"))
    .build()

doWorkでは下のように値を取り出す事ができます

inputData.getString("key")?.let {
    Log.d("MyWorker", "key: $it")
}

バックグラウンド処理をキャンセルしたい時はcancelWorkByIdを使います

WorkManager.getInstance().cancelWorkById(workRequest.id)

まとめてキャンセルしたい時はcancelAllWorkを使います

WorkManager.getInstance().cancelAllWork()