Verificar os recursos do dispositivo durante a execução para óculos de áudio e óculos de tela

Dispositivos XR relevantes
Estas orientações ajudam você a criar experiências para esses tipos de dispositivos XR.
Óculos com áudio e
tela

Os diferentes tipos de óculos com áudio e com tela têm recursos distintos. Depois de planejar como você vai oferecer suporte a diferentes tipos de dispositivos de IA, verifique os recursos do dispositivo no momento da execução para oferecer a melhor experiência ao usuário.

Verificar se um dispositivo tem uma tela

Os óculos com tela podem mostrar interfaces criadas com o Jetpack Compose Glimmer. O exemplo abaixo mostra como verificar se um dispositivo de óculos tem uma tela:

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

Reagir a mudanças de estado da tela

Em óculos com tela, ela pode expirar ou o usuário pode desativá-la. Para criar atividades que são executadas independentemente de a tela estar ligada ou desligada, use addPresentationModeChangedListener para receber notificações quando o estado da tela mudar. É possível ajustar a atividade para a quantidade adequada de informações de áudio, dependendo do estado da tela.

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

    val areVisualsOff = !presentationModeFlags.hasPresentationMode(VISUALS_ON)
}

Deixe a tela ligada

Em óculos com tela, você pode solicitar que o sistema mantenha a tela ligada e evite que ela expire usando addLayoutParamsFlags.

var projectedDisplayController = ProjectedDisplayController.create(activity)

projectedDisplayController.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

Monitorar mudanças no estado da bateria

Para acompanhar o status da bateria em tempo real de óculos de áudio ou de tela conectados, use o método addBatteryStateChangedListener fornecido pelo ProjectedDeviceController. Esse listener notifica o app sempre que o nível de bateria ou o estado de carregamento muda, permitindo otimizar o desempenho do app, ativar modos de economia de energia ou atualizar a interface do usuário.

@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}")
        }
    }
}

Quando terminar de monitorar o dispositivo ou quando o componente estiver sendo destruído, chame close no ProjectedDeviceController para liberar os recursos subjacentes corretamente.

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

Também é possível cancelar o registro de um listener explicitamente antes do fim do escopo usando removeBatteryStateChangedListener.

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