常時オンアプリとシステムのアンビエント モード

ユーザーがスマートウォッチを使用しなくなった場合、Wear OS はアクティブなアプリの省電力モードへの移行を自動的に処理します。これを、システムの「常に画面表示モード」と呼びます。ユーザーがスマートウォッチを操作すると、次のいずれかの条件が満たされた場合にアプリが再開されます。

  • ユーザー インタラクションが一定の期間内(タイムアウト前)に発生する。
  • アプリが進行中のアクティビティを宣言して開始している。

たとえば、ランニング中に心拍数とペースを確認する場合のような特定のユースケースでは、システムの常に画面表示モードで表示する内容を制御することもできます。常に画面表示モードとインタラクティブ モードの両方で実行される Wear OS アプリは、常時オンアプリと呼ばれます。

アプリを常に表示すると電池寿命に影響するため、この機能をアプリに追加する場合は電池寿命への影響を考慮してください。

プロジェクトを構成する

常に画面表示モードをサポートする手順は次のとおりです。

  1. ウェアラブル アプリの作成と実行ページの設定に基づいて、プロジェクトを作成または更新します。
  2. (Wear OS 4 以前でのみ必要)Android マニフェスト ファイルに WAKE_LOCK 権限を追加します。
<uses-permission android:name="android.permission.WAKE_LOCK" android:maxSdkVersion="33"/>

常時オンモードを有効にする

Wear OS 6 以降、targetSdkVersion が 36 以上に設定されているアプリは、デフォルトで常時オンになります。 これらのアプリは、システムのアンビエント モード中に、構成なしで一定の期間表示されます。 アプリの targetSdkVersion が 36 未満の場合、またはアプリを Wear OS 5 以前で実行する必要がある場合は、AmbientLifecycleObserver クラスを使用してアプリを常時オンにします。

AmbientLifecycleObserver クラスを使用して常に画面表示モードのイベントに反応する

アプリで AmbientLifecycleObserver クラスを使用して、常に画面表示モードのイベントに直接対応することもできます。

  1. 次の例のように、 AmbientLifecycleObserver.AmbientLifecycleCallback インターフェースを実装します。この段階では各メソッドは空ですが、このガイドの後半では「常に画面表示モード」の開始と終了の視覚効果に加える必要がある変更について詳しく説明します。

    Kotlin

    val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback {
        override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
        // ... Called when moving from interactive mode into ambient mode.
        }
    
        override fun onExitAmbient() {
        // ... Called when leaving ambient mode, back into interactive mode.
        }
    
        override fun onUpdateAmbient() {
        // ... Called by the system in order to allow the app to periodically
        // update the display while in ambient mode. Typically the system will
        // call this every 60 seconds.
        }
    }
  2. AmbientLifecycleObserver を作成し、オブザーバーを登録します。通常、Wear OS 用 Compose を使用している場合は、onCreate() またはトップレベル コンポーザブルで使用して、アクティビティのライフサイクル全体で常時オン動作を有効にできるようにします。

    Kotlin

    private val ambientObserver = AmbientLifecycleObserver(activity, callback)
    
    override fun onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      lifecycle.addObserver(observer)
    
      // ...
    }
  3. 常時オン動作が不要になったら、removeObserver() を呼び出してオブザーバーを削除します。たとえば、アクティビティの onDestroy() メソッドで呼び出します。

TimeText ウィジェットを使用して時刻のテキストを更新する

Wear OS 6 以降、TimeText ウィジェットはアンビエント モードに対応しています。アプリで常に画面表示モード中に時刻のテキストを 1 分に 1 回更新する必要がある場合は、AmbientLifecycleObserver を使用せずに TimeText ウィジェットを使用するだけです。

常時オンアプリをバックグラウンドに移動できる

Wear OS 5 以降、常時オンアプリは、アンビエント モードで一定の時間が経過するとバックグラウンドに移動します。ユーザーはシステム設定でタイムアウトを構成できます。

常時オンのアプリで、音楽の再生やワークアウト セッションなど、進行中のユーザー タスクに関する情報を表示する場合は、タスクが終了するまで進行中のアクティビティを表示しておく必要があります。そのためには、Ongoing Activity API を使用して、常時アクティブなアクティビティにリンクされた進行中の通知を投稿します。

システムが進行中のアクティビティを認識するには、進行中の通知のタップ インテントを常時アクティブなアクティビティに指すようにする必要があります。次のコード スニペットを参照してください。

// Create a pending intent that point to your always-on activity
val touchIntent =
    PendingIntent.getActivity(
        context,
        0,
        Intent(context, MyAlwaysOnActivity::class.java),
        PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )

val notificationBuilder =
    NotificationCompat.Builder(this, CHANNEL_ID)
    // ...
    .setOngoing(true)

val ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
    // ...
    .setTouchIntent(touchIntent)
    .build()

ongoingActivity.apply(applicationContext)

notificationManager.notify(
    NOTIFICATION_ID,
    notificationBuilder.build()
)

アンビエント モードでのユーザー エクスペリエンスを変更する

デフォルトでは、常時オンを実装しても、スマートウォッチが「常に画面表示モード」になったときの画面の外観は変わりません。この動作を変更するには、AmbientLifecycleCallback のメソッドをオーバーライドします。

バッテリーを節約するには、次のようにします。

  • 明るいピクセルを減らします。「常に画面表示モード」では重要な情報のみを表示することを検討し、インタラクティブ モードに入ったときに詳細な情報を表示します。
  • 画面の 85% 以上を黒くして、塗りつぶしを削除し、ボタンと大きなアイコンにはアウトラインを使用します。
  • 機能しないブランドや背景画像など、余分な情報を表示しないでください。
  • アクティブ モードと常に表示状態のモードで要素の位置を同じにし、常に時刻を表示します。
  • 更新頻度が低くなるようコンテンツを調整します。たとえば、タイマーを秒単位ではなく分単位で表示します。
  • 距離や時間など、頻繁に更新される英数字のコンテンツのプレースホルダ UI を削除または表示します。
  • カウントダウン リングやメディア セッションなど、頻繁に更新される進行状況インジケーターを削除します。
  • 常にオンのモードに入るときに、ユーザーがアプリの設定画面や設定画面にいた場合は、代わりにアプリでより関連性の高い画面を表示することを検討してください。
  • onEnterAmbient() に渡される AmbientDetails オブジェクトで、次のようにします。
    • deviceHasLowBitAmbient が設定されている場合、可能であればアンチ エイリアスを無効にします。
    • burnInProtectionRequired が設定されている場合、表示を定期的にシフトし、白く塗りつぶされた領域がないようにします。
  • アンビエント モード中に連続アニメーションを実行しないでください。Wear OS 5.1 以降では、アンビエント モード中にアニメーターの実行が停止することがあります。

途切れのないディスプレイのチェックリスト

デバイスがさまざまな状態に移行するときに、ディスプレイを最大限に制御したい場合があります。たとえば、ワークアウト アプリがワークアウト中にディスプレイにウォッチフェイスが表示されないようにしたい場合などです。このような場合は、次の操作を行います。

  1. AmbientLifecycleObserver.AmbientLifecycleCallback インターフェースを実装します。
  2. デバイスがシステム アンビエント モードのときに使用する新しい低電力のレイアウトを作成します。
  3. ワークアウトの期間中は、進行中のアクティビティを実装します。

これを実現する方法の例については、GitHub の Compose ベースの エクササイズ サンプルをご覧ください。このサンプルでは、Horologist ライブラリの AmbientAware コンポーザブルを使用しています。