ユーザー操作を処理する

Glance は、Action クラスを介したユーザー操作の処理を簡素化します。Glance の Action クラスは、ユーザーが実行できるアクションを定義し、アクションに応じて実行するオペレーションを指定できます。GlanceModifier.clickable メソッドを使用して、任意のコンポーネントに Action を適用できます。

アプリ ウィジェットはリモート プロセス上で稼働するため、アクションは作成時に定義され、実行はリモート プロセスで行われます。ネイティブ RemoteViews では PendingIntents で行います。

このページでは、次の操作について説明します。

アクティビティを起動する

ユーザー操作でアクティビティを起動するには、GlanceModifier.clickable(..)修飾子を使用して、Button またはその他のコンポーザブルに actionStartActivity 関数を指定します。

actionStartActivity で次のいずれかを指定します。

  • ターゲット アクティビティ クラス
  • ComponentName
  • インテント

Glance は、アクションを指定されたターゲットとパラメータを含む PendingIntent に変換します。次の例では、ユーザーがボタンをクリックしたときに NavigationActivity が起動されます。

@Composable
fun MyContent() {
    // ..
    Button(
        text = "Go Home",
        onClick = actionStartActivity<MainActivity>()
    )
}

サービスを起動する

アクティビティの起動と同様に、actionStartService メソッドのいずれかを使用して、ユーザー操作でサービスを起動します。

actionStartService で次のいずれかを指定します。

  • ターゲット アクティビティ クラス
  • ComponentName
  • インテント

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Sync",
        onClick = actionStartService<SyncService>(
            isForegroundService = true // define how the service is launched
        )
    )
}

ブロードキャスト イベントを送信する

次のいずれかの actionSendBroadcast メソッドを使用して、ユーザー操作時にブロードキャスト イベントを送信します。

actionSendBroadcast で次のいずれかを指定します。

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Send",
        onClick = actionSendBroadcast<MyReceiver>()
    )
}

カスタム操作を実行する

Glance は、特定のターゲットを起動する代わりに、ラムダ アクションや actionRunCallback を使用して、ユーザー操作時の UI や状態の更新などのアクションを実行できます。

ラムダ アクションを実行する

ラムダ関数は、UI インタラクションへのコールバックとして使用できます。

たとえば、ラムダ関数を GlanceModifier.clickable 修飾子に渡します。

Text(
    text = "Submit",
    modifier = GlanceModifier.clickable {
        submitData()
    }
)

または、それをサポートするコンポーザブルの onClick パラメータに渡します。

Button(
    text = "Submit",
    onClick = {
        submitData()
    }
)

ActionCallback を実行する

または、actionRunCallback メソッドを使用して、ユーザー操作に対するアクションを実行します。そのためには、ActionCallback のカスタム実装を提供します。

@Composable
private fun MyContent() {
    // ..
    Image(
        provider = ImageProvider(R.drawable.ic_hourglass_animated),
        modifier = GlanceModifier.clickable(
            onClick = actionRunCallback<RefreshAction>()
        ),
        contentDescription = "Refresh"
    )
}

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // TODO implement
    }
}

ユーザーがクリックすると、指定された ActionCallbacksuspend onAction メソッドが呼び出され、定義済みのロジック(更新データのリクエスト)を実行します。

アクションの実行後にウィジェットを更新するには、新しいインスタンスを作成して update(..)を呼び出します。詳しくは、GlanceAppWidget の状態を管理するをご覧ください。

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // do some work but offset long-term tasks (e.g a Worker)
        MyAppWidget().update(context, glanceId)
    }
}

アクションにパラメータを指定する

アクションに追加情報を指定するには、ActionParameters API を使用して、入力された Key-Value ペアを作成します。たとえば、クリックされたデスティネーションを定義するには、次のようにします。

private val destinationKey = ActionParameters.Key<String>(
    NavigationActivity.KEY_DESTINATION
)

class MyAppWidget : GlanceAppWidget() {

    // ..

    @Composable
    private fun MyContent() {
        // ..
        Button(
            text = "Home",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "home")
            )
        )
        Button(
            text = "Work",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "work")
            )
        )
    }

    override suspend fun provideGlance(context: Context, id: GlanceId) {
        provideContent { MyContent() }
    }
}

その下には、アクティビティの起動に使用されるインテントにパラメータが含まれ、ターゲット アクティビティがそれを取得できるようになります。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val destination = intent.extras?.getString(KEY_DESTINATION) ?: return
        // ...
    }
}

パラメータは ActionCallback にも提供されます。定義済みの Parameters.Key を使用して、値を取得します。

class RefreshAction : ActionCallback {

    private val destinationKey = ActionParameters.Key<String>(
        NavigationActivity.KEY_DESTINATION
    )

    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        val destination: String = parameters[destinationKey] ?: return
        // ...
    }
}