ウォッチフェイスの追加機能へのデータの公開

ウォッチフェイスの追加機能のデータソースは、ウォッチフェイスの追加機能に情報を公開し、ウォッチフェイスがレンダリングできるテキスト、画像、数値を供給します。

データソース サービスは SuspendingComplicationDataSourceService を拡張したものであり、有益な情報をユーザーのウォッチフェイスに直接提供します。

スタートガイド

アプリ モジュールに次の依存関係を追加します。

dependencies {
  implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1")
}

データソース サービスを作成する

追加機能のデータが必要な場合、アップデート リクエストが Wear OS システムによってデータソースに送信されます。システムからのアップデート リクエストに応答するために、データソースは SuspendingComplicationDataSourceService クラスの onComplicationRequest() メソッドを実装する必要があります。

Wear OS システムは、データソースからデータが必要になった場合、たとえばデータソースを使用している追加機能がアクティブになったとき、または一定の時間が経過したときに、onComplicationRequest() を呼び出します。

注: データソースがデータを提供すると、ウォッチフェイスは生の値を受信します。ウォッチフェイスは、表示用にデータをフォーマットする役割を担います。

次のコード スニペットは実装例です。

class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
        // Retrieve the latest info for inclusion in the data.
        val text = getLatestData()
        return shortTextComplicationData(text)
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, and title.
            .build()

    // ...
}

マニフェストの宣言と権限

Android システムがデータソースをデータソースとして扱えるようにするには、アプリ マニフェストに固有の宣言を含める必要があります。このセクションでは、データソースに必要な設定について説明します。

アプリのマニフェストでサービスを宣言し、アップデート リクエストのアクション インテント フィルタを追加します。Wear OS システムだけがプロバイダ サービスにバインドできるように、マニフェストで BIND_COMPLICATION_PROVIDER 権限を追加してサービスを保護する必要もあります。

さらに、service 要素に、単色の白いアイコンを提供する android:icon 属性を含めます。アイコンにはベクター型ドローアブルを使用することをおすすめします。アイコンはデータソースを表し、追加機能選択画面に表示されます。

次の例をご覧ください。

<service
    android:name=".snippets.complication.MyComplicationDataSourceService"
    android:exported="true"
    android:label="@string/my_complication_service_label"
    android:icon="@drawable/complication_icon"
    android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
    <intent-filter>
        <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
    </intent-filter>

    <!-- Supported types should be comma-separated, for example: "SHORT_TEXT,SMALL_IMAGE" -->
    <meta-data
        android:name="android.support.wearable.complications.SUPPORTED_TYPES"
        android:value="SHORT_TEXT" />
    <meta-data
        android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
        android:value="300" />

    <!-- Optionally, specify a configuration activity, where the user can configure your complication. -->
    <meta-data
        android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
        android:value="MY_CONFIG_ACTION" />

</service>

メタデータ要素

マニフェスト ファイルで、次のメタデータ要素を確認します。

  • android:name="android.support.wearable.complications.SUPPORTED_TYPES": データソースがサポートするウォッチフェイスの追加機能データのタイプを指定します。
  • android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS": システムがデータの更新をチェックする頻度を指定します。

UPDATE_PERIOD_SECONDS は、追加機能のデータ データソースがアクティブである場合、システムでデータのアップデートを確認する頻度を指定します。プッシュ アップデートを使用している場合など、追加機能に表示されている情報を定期的に更新する必要がない場合は、この値を 0 に設定します。

UPDATE_PERIOD_SECONDS0 に設定しない場合は、300(5 分)以上の値を使用する必要があります。デバイスの電池を長持ちさせるため、この値がシステムで定められた最短のアップデート周期となります。また、デバイスが「常に画面表示」モードである場合や、デバイスを着用していない場合は、アップデート リクエストの頻度が低くなることにご注意ください。

構成アクティビティの追加

必要に応じて、ユーザーが追加機能選択ツールから特定のデータソースを選択したときに表示される設定アクティビティをデータソースに含めることができます。たとえば、世界時計のデータソースには、ユーザーが表示する都市やタイムゾーンを選択できる設定アクティビティがあるかもしれません。

マニフェストの例には、PROVIDER_CONFIG_ACTION キーを含む meta-data 要素が含まれています。この要素の値は、設定アクティビティの起動に使用されるアクションです。

設定アクティビティを作成し、マニフェスト ファイルでそのアクションに一致するインテント フィルタを追加します。

<intent-filter>
    <action android:name="MY_CONFIG_ACTION" />
    <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

アクティビティは、アクティビティの onCreate() メソッド内のインテントから、構成しているコンプリケーション スロットの詳細を取得できます。

// Keys defined on ComplicationDataSourceService
val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1)
val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1)
val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)

構成アクティビティは、プロバイダと同じパッケージに格納する必要があります。また、データソースを設定すべきかどうかをシステムに伝えるために、RESULT_OKRESULT_CANCELED を返す必要があります。

setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration
finish()

プッシュ アップデートを使用する

アプリのマニフェストでアップデート周期を指定する代わりに、 ComplicationDataSourceUpdateRequester インスタンスを使用してアップデートを動的に開始できます。更新をリクエストするには、requestUpdate() を呼び出します。

注意: デバイスの電池を長持ちさせるため、ComplicationDataSourceUpdateRequester のインスタンスから requestUpdate() を呼び出す周期は平均 5 分よりも短くしないでください。

時間に依存する値を指定する

追加機能の中には、現在時刻に関連する値を表示するものがあります。現在の日付、次の打ち合わせまでの時間、別のタイムゾーンでの時刻などが該当します。

値を最新の状態に保つため、追加機能を 1 秒または 1 分ごとに更新しないでください。代わりに、時間依存テキストを使用して現在の日付や時間に対する相対値を指定します。次のクラスを使用すると、時間に依存する値を作成できます。

タイムライン データ

事前に定義された時間に一連の値を返すコンプリケーション データソースには、SuspendingTimelineComplicationDataSourceService を使用します。

たとえば、カレンダー アプリの「次の予定」データソースの場合、システムが次の予定を求めてデータソースを定期的にポーリングするのではなく、データソースがイベントのタイムラインを一度提供し、カレンダーが変更された場合にデータソースが更新を開始できます。これにより、システムへの負荷が最小限に抑えられ、コンプリケーションで正しいイベントがタイムリーに表示されます。

class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
        if (request.complicationType != ComplicationType.SHORT_TEXT) {
            return ComplicationDataTimeline(
                defaultComplicationData = NoDataComplicationData(),
                timelineEntries = emptyList()
            )
        }
        // Retrieve list of events from your own datasource / database.
        val events = getCalendarEvents()
        return ComplicationDataTimeline(
            defaultComplicationData = shortTextComplicationData("No event"),
            timelineEntries = events.map {
                TimelineEntry(
                    validity = TimeInterval(it.start, it.end),
                    complicationData = shortTextComplicationData(it.name)
                )
            }
        )
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, title etc
            .build()

    // ...
}

SuspendingTimelineComplicationDataSourceService の動作は次のとおりです。

  • 現在の時刻がタイムラインのエントリの開始時刻と終了時刻の範囲内にある場合、ウォッチフェイスはその値を使用します。
  • 現在の時刻がタイムラインのどのエントリにも該当しない場合は、デフォルト値が使用されます。たとえば、カレンダー アプリでは「予定なし」となります。
  • 現在時刻が複数のイベントの範囲内にある場合は、最も短いイベントが使用されます。

動的な値を指定する

Wear OS 4 以降では、プラットフォームで直接利用可能な値に基づいて頻繁に更新される値を表示できる追加機能もあります。ウォッチフェイスの追加機能でこの機能を提供するには、動的な値を受け入れる ComplicationData フィールドを使用します。プラットフォームはこれらの値を頻繁に評価、更新するため、ウォッチフェイスの追加機能のプロバイダを実行する必要はありません。

たとえば、 GoalProgressComplicationData の動的値フィールドや、任意の ComplicationText フィールドで使用できる DynamicComplicationText などがあります。これらの動的な値は、 androidx.wear.protolayout.expression ライブラリに基づいています。

プラットフォームは、次のような状況では動的な値を評価できません。