У разных моделей аудио- и видеоочков разные возможности. После того как вы спланируете поддержку разных типов устройств с ИИ, вы можете проверять возможности устройства во время выполнения, чтобы обеспечить наилучшее взаимодействие с устройством пользователя.
Проверьте, есть ли у устройства экран
На видеоочках можно показывать интерфейсы, созданные с помощью Jetpack Compose Glimmer. В следующем примере показано, как проверить, есть ли у очков дисплей:
// 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)
Отслеживание изменений состояния батареи
Чтобы отслеживать уровень заряда подключенных аудио- или видеоочков в реальном времени, используйте метод addBatteryStateChangedListener, предоставляемый ProjectedDeviceController. Этот прослушиватель уведомляет приложение об изменении уровня заряда батареи или состояния зарядки, позволяя оптимизировать производительность приложения, включить режимы энергосбережения или обновить пользовательский интерфейс.
@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}") } } }
Когда вы закончите отслеживать устройство или когда ваш компонент будет уничтожен, вызовите close для ProjectedDeviceController, чтобы правильно освободить базовые ресурсы.
@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) }