はじめに
この記事で説明した通り、様々な機能を活用していきましょう。
Workerクラスに何かしらの情報(データ)を引き渡したいといったこともあるでしょう。
その様な場合にも対応する機能が存在します。
今回はデータの渡し方を説明します。
動作環境
この記事の動作環境は以下のとおりです。
- Android Studio:3.3
- Kotln:1.3.11
- Open JDK:1.8
- compileSdkVersion:28
- targetSdkVersion:28
- minSdkVersion:19
目標
Workerクラスにデータを渡す!
完成イメージ
概要
Workerにデータを渡すにはWorkRequestに格納して渡すことになります。
詳細な説明の前にイメージを確認しておきます。
説明
DataクラスとData.Builderクラス
Workerクラスにデータを渡すにはDataクラスを利用します。
名前が一般的すぎて、更に同じ名前のクラスが多いため、パッケージも含めて覚える必要があります。
完全クラス名は「 androidx.work.Data 」です。
内部的にMapを保持しており、そのMapに格納したデータがWorkerクラスを継承したクラスに渡されます。
Dataクラスのオブジェクトを生成するには、Data.Builderクラスを利用します。
BuilderクラスのsetXXXメソッドを呼び出しデータを格納していきます。
実際の実装例を確認すると理解が早まると思います。
val data = Data.Builder().apply {
putString("message", editInput.text.toString())
}.build()
WorkRequestへの格納
生成したDataクラスのオブジェクトを格納するには、WorkRequestのsetInputDataメソッドを呼び出します。
Dataクラス同様に、実際の実装例を確認すると理解が早まると思います。
val request = OneTimeWorkRequestBuilder<MyWorker>().apply {
setInputData(data)
}.build()
Workerクラス内でDataの取得と値の取得
Dataを受け取るには、Workerクラスを継承したクラス内でgetinputDataメソッドを呼び出します。Kotlinの場合は、プロパティのアクセスでgetterメソッドを呼び出すことなく、変数のようにアクセス可能です。
取得したDataから格納されている値を取得するには、getXXXメソッドに格納したときのキーを指定して取得します。
コードで確認してみましょう。
inputData.getString("message")
実装コード
この記事で動作確認したコードをすべて掲載します。
AndroidManifest.xmlはテンプレートで作成された状態から変更していないため、省略します。
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "jp.co.casareal.workmanagersenddata"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
def work_version = "1.0.0"
implementation "android.arch.work:work-runtime-ktx:$work_version"
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Casareal"
android:ems="10"
android:id="@+id/editInput" android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/btnStart"/>
<Button
android:text="WorkStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnStart"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="@+id/editInput"
android:layout_marginBottom="8dp"/>
</android.support.constraint.ConstraintLayout>
package jp.co.casareal.workmanagersenddata
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.support.v4.app.NotificationCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import java.text.SimpleDateFormat
class MyWorker(cxt: Context, params: WorkerParameters) : Worker(cxt, params) {
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// カテゴリー名(通知設定画面に表示される情報)
val name = "通知のタイトル的情報を設定"
// システムに登録するChannelのID
val id = "casareal_chanel"
// 通知の詳細情報(通知設定画面に表示される情報)
val notifyDescription = "この通知の詳細情報を設定します"
private val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
companion object {
var nid = 1;
}
init {
// Channelの取得と生成
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager.getNotificationChannel(id) == null
val mChannel = NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH)
mChannel.apply {
description = notifyDescription
}
notificationManager.createNotificationChannel(mChannel)
}
}
override fun doWork(): Result {
val notification = NotificationCompat.Builder(applicationContext, id).apply {
setContentText("受け取ったメッセージ:${inputData.getString("message")}")
setSmallIcon(R.drawable.ic_launcher_background)
}
notificationManager.notify(MyWorker.nid, notification.build())
return Result.success()
}
}
package jp.co.casareal.workmanagersenddata
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val manager = WorkManager.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnStart.setOnClickListener {
val request = OneTimeWorkRequestBuilder<MyWorker>().apply {
val data = Data.Builder().apply {
putString("message", editInput.text.toString())
}.build()
setInputData(data)
}.build()
manager.enqueue(request)
}
}
}
まとめ
この記事ではDataを渡すだけなので、短めですが以下が理解できました。
- Workerクラスにデータを渡すときはandroidx.work.Dataオブジェクトを生成する
- DataはWorkRequestに格納する
- WorkerクラスでDataを取得するにはgetInputDataメソッドを呼び出す