オーディオ グラスとディスプレイ グラスのデバイス機能を実行時に確認

対象となる XR デバイス
このガイダンスは、次のようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
オーディオ&
ディスプレイ グラス

オーディオ グラスとディスプレイ グラスは、種類によって機能が異なります。さまざまな種類の AI デバイスをサポートする方法を計画したら、実行時にデバイスの機能をチェックして、ユーザーのデバイスに最適なエクスペリエンスを提供できます。

デバイスにディスプレイがあるかどうかを確認する

ディスプレイ グラスは、Jetpack Compose Glimmer で構築された UI を表示できます。次の例は、メガネデバイスにディスプレイがあるかどうかを確認する方法を示しています。

// Check device capabilities
val projectedDeviceController = ProjectedDeviceController.create(this@ProjectedMainActivity)
isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI)

表示状態の変更に対応する

ディスプレイ グラスでは、ディスプレイがタイムアウトしたり、ユーザーがディスプレイをオフにしたりできます。ディスプレイがオンかオフかにかかわらず実行されるアクティビティを設計するには、addPresentationModeChangedListener を使用して、ディスプレイの状態が変化したときに通知を受け取ります。表示状態に応じて、適切な量の音声情報が得られるようにアクティビティを調整できます。

ProjectedDisplayController.create(activity).addPresentationModeChangedListener {
    presentationModeFlags ->

    val areVisualsOff = !presentationModeFlags.hasPresentationMode(VISUALS_ON)
}

ディスプレイをオンのままにする

ディスプレイ グラスでは、addLayoutParamsFlags を使用して、画面をオンのままにし、画面がタイムアウトしないようにシステムにリクエストできます。

var projectedDisplayController = ProjectedDisplayController.create(activity)

projectedDisplayController.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

バッテリーの状態の変化をモニタリングする

接続されているオーディオ グラスまたはディスプレイ グラスのリアルタイムのバッテリー ステータスを追跡するには、ProjectedDeviceController が提供する addBatteryStateChangedListener メソッドを使用します。このリスナーは、バッテリー残量や充電状態が変化するたびにアプリに通知します。これにより、アプリのパフォーマンスの最適化、省電力モードの有効化、ユーザー インターフェースの更新が可能になります。

@OptIn(ExperimentalProjectedApi::class)
private var deviceController: ProjectedDeviceController? = null

private val batteryListener = { batteryState: BatteryState ->
    val batteryLevel = batteryState.batteryLevel
    val isCharging = batteryState.isCharging

    if (batteryLevel <= 15 && !isCharging) {
        switchToLowPowerMode()
    }

    updateBatteryUi(batteryLevel, isCharging)
}
// ...

@OptIn(ExperimentalProjectedApi::class)
private fun monitorBatteryStatus() {
    lifecycleScope.launch {
        try {
            if (deviceController == null) {
                deviceController = ProjectedDeviceController.create(this@PhoneMainActivity)
            }

            if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
                deviceController?.addBatteryStateChangedListener(coroutineContext, batteryListener)
            }
        } catch (e: Exception) {
            Log.e("BatteryMonitor", "Unexpected error: ${e.message}")
        }
    }
}

デバイスのモニタリングが完了したとき、またはコンポーネントが破棄されるときは、ProjectedDeviceController で close を呼び出して、基盤となるリソースを適切に解放します。

@OptIn(ExperimentalProjectedApi::class)
override fun onDestroy() {
    super.onDestroy()
    // Unregisters the active listeners
    deviceController?.close()
    deviceController = null
}

removeBatteryStateChangedListener を使用して、スコープが終了する前にリスナーの登録を明示的に解除することもできます。

@OptIn(ExperimentalProjectedApi::class)
override fun onPause() {
    super.onPause()
    // Explicitly unregister the listener when it is no longer needed
    deviceController?.removeBatteryStateChangedListener(batteryListener)
}