LoginSignup
4
4

More than 3 years have passed since last update.

いまさらWorkManager〜基本編⑤(Workerクラスにデータを渡す)〜

Posted at

はじめに

この記事で説明した通り、様々な機能を活用していきましょう。
Workerクラスに何かしらの情報(データ)を引き渡したいといったこともあるでしょう。
その様な場合にも対応する機能が存在します。
今回はデータの渡し方を説明します。

動作環境

この記事の動作環境は以下のとおりです。

  • Android Studio:3.3
  • Kotln:1.3.11
  • Open JDK:1.8
  • compileSdkVersion:28
  • targetSdkVersion:28
  • minSdkVersion:19

目標

Workerクラスにデータを渡す!

完成イメージ

この記事では、下記のアプリで動作確認を行っています。

概要

Workerにデータを渡すにはWorkRequestに格納して渡すことになります。
詳細な説明の前にイメージを確認しておきます。

Dataの渡し方.png

説明

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はテンプレートで作成された状態から変更していないため、省略します。

build.gradle

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"

}
activity_main.xml
<?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>
MyWoker.kt
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()
    }
}
MainActivity.kt
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メソッドを呼び出す
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4