このプログラムは、未完成です。
WorkManager の例題として、毎分時間を表示してみます。
環境
app/build.gradle.kts
(省略)
dependencies {
implementation("androidx.work:work-runtime-ktx:2.8.0")
(省略)
画面
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
プログラム
MainViewModel.kt
package com.example.clock02
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.Data
import java.util.concurrent.TimeUnit
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val workManager = WorkManager.getInstance(application)
private val workRequest = OneTimeWorkRequest.Builder(ClockWorker::class.java)
.setInitialDelay(1, TimeUnit.SECONDS)
.addTag("clock_worker")
.build()
private val workInfoLiveData: LiveData<WorkInfo> = workManager.getWorkInfoByIdLiveData(workRequest.id)
// MutableLiveData to observe the formatted date
private val formattedDateLiveData = MutableLiveData<String>()
init {
workManager.enqueue(workRequest)
// Observe the work status and update the LiveData
workManager.getWorkInfoByIdLiveData(workRequest.id).observeForever { workInfo ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
val formattedDate = workInfo.outputData.getString("formattedDate")
formattedDateLiveData.postValue(formattedDate)
}
}
}
fun getWorkInfoLiveData(): LiveData<WorkInfo> {
return workInfoLiveData
}
fun getFormattedDateLiveData(): LiveData<String> {
return formattedDateLiveData
}
}
ClockWorker.kt
package com.example.clock02
import android.content.Context
import androidx.work.Data
import androidx.work.ListenableWorker
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.concurrent.TimeUnit
class ClockWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
try {
println("*** ClockWorker *** aaa ***")
val now = LocalDateTime.now()
val df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val fdate = df.format(now)
val outputData = Data.Builder().putString("formattedDate", fdate).build()
println("*** ClockWorker *** ccc ***")
// 次回の実行を1分後にスケジュールする
val nextExecutionTime = now.plusMinutes(1)
val timeDiff = nextExecutionTime.toInstant(ZoneOffset.UTC).toEpochMilli() - System.currentTimeMillis()
val nextRequest = OneTimeWorkRequest.Builder(ClockWorker::class.java)
.setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)
.build()
WorkManager.getInstance(applicationContext).enqueue(nextRequest)
return Result.success(outputData)
} catch (e: Exception) {
return Result.failure()
}
}
}
MainActivity.kt
package com.example.clock02
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.Observer
import androidx.work.WorkInfo
class MainActivity : AppCompatActivity() {
private lateinit var textView: TextView
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.textView)
println("*** check *** aaa ***")
// MainViewModelのインスタンスを作成
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
println("*** check *** ccc ***")
// WorkInfoを監視してUIを更新
viewModel.getWorkInfoLiveData().observe(this, Observer { workInfo ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
val formattedDate = workInfo.outputData.getString("formattedDate")
println("*** check *** eee ***")
textView.text = formattedDate
println("*** check *** fff ***")
} else if (workInfo != null && workInfo.state == WorkInfo.State.FAILED) {
// エラーハンドリング
}
})
}
}