Обрабатывать физический ввод с аудио- и видеоочков.

Поддерживаемые XR-устройства
Это руководство поможет вам создавать контент для таких устройств.
Аудио- и
видеоочки

Чтобы получать и обрабатывать данные, которые передаются в проецируемое действие приложения, или реализовать специальные функции сенсорной панели, используйте непрямые указатели. Чтобы узнать, как обрабатывать другие типы событий (например, действия камеры), ознакомьтесь с приведенными ниже разделами этого руководства.

Как обрабатывать действия камеры

Когда пользователь нажимает кнопку камеры на устройстве, система отправляет событие ввода в проецируемое приложение в виде действия ProjectedInputEvent.ProjectedInputAction.TOGGLE_APP_CAMERA. Ваше приложение может отслеживать это действие с помощью специального диспетчера:

@OptIn(ExperimentalProjectedApi::class)
class CameraActionInputSnippetActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Observe hardware camera action events when RESUMED
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.RESUMED) {
                withContext(Dispatchers.Default) {
                    try {
                        val projectedActivity = ProjectedActivityCompat.create(this@CameraActionInputSnippetActivity)
                        try {
                            projectedActivity.projectedInputEvents.collect { inputEvent ->
                                if (inputEvent.inputAction == TOGGLE_APP_CAMERA) {
                                    withContext(Dispatchers.Main) {
                                        onCameraActionTriggered()
                                    }
                                }
                            }
                        } finally {
                            projectedActivity.close()
                        }
                    } catch (e: CancellationException) {
                        throw e
                    } catch (e: Exception) {
                        Log.w("CameraActionSnippet", "ProjectedActivityCompat unavailable: ${e.message}")
                    }
                }
            }
        }

        setContent {
            GlimmerTheme {
                TouchpadInputSnippet(
                    onTap = { Log.i("CameraActionSnippet", "Touchpad tapped") }
                )
            }
        }
    }

    private fun onCameraActionTriggered() {
        Log.i("CameraActionSnippet", "Camera action button double-pressed!")
    }
}

Как проверить общие события движения

Используйте dispatchGenericMotionEvent, чтобы проверять общие события движения, которые передаются в спроецированную активность приложения. Общие события движения доставляются на границе активности и не требуют использования компонента Glimmer из Jetpack Compose.

MotionEvent может включать:

Не каждое значение имеет смысл для каждого действия. Прежде чем считать необработанное событие завершенным жестом, проверьте действие и источник.

class MotionGestureInputSnippetActivity : ComponentActivity() {

    override fun dispatchGenericMotionEvent(ev: MotionEvent): Boolean {
        val actionName = when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> "ACTION_DOWN" // First contact with the glasses touchpad
            MotionEvent.ACTION_MOVE -> "ACTION_MOVE" // Contact moving across the glasses touchpad
            MotionEvent.ACTION_UP -> "ACTION_UP"     // Contact lifted from the glasses touchpad
            else -> "ACTION_${ev.actionMasked}"
        }

        Log.d(
            "MotionGestureSnippet",
            "MotionEvent: action=$actionName x=${ev.x} y=${ev.y}"
        )

        // Delegate to super unless intentionally consuming the event
        return super.dispatchGenericMotionEvent(ev)
    }
}

Возвращайте значение true, только если действие намеренно использует событие. В противном случае возвращается значение super.dispatchGenericMotionEvent(ev), чтобы событие могло быть обработано обычным образом.

Как обрабатывать системный жест "Назад"

Если для экрана требуется настроить поведение при использовании жеста "Назад", ваше приложение должно обрабатывать его с помощью тех же API Android, которые используются для других действий, например OnBackPressedDispatcher и OnBackPressedCallback.

Жест пользователя зависит от типа очков:

  • На дисплее очков проведите вниз по сенсорной панели, чтобы выполнить системное действие "Назад".
  • На аудиоочках проведите пальцем назад по сенсорной панели, чтобы выполнить системное действие "Назад".

Зарегистрируйте обратный вызов кнопки "Назад", если текущий экран должен перехватывать нажатия этой кнопки, например чтобы закрыть оверлей или показать подтверждение выхода.

class BackGestureInputSnippetActivity : ComponentActivity() {

    private val backCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            onBackGestureReceived()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Register back gesture callback with Activity's onBackPressedDispatcher
        onBackPressedDispatcher.addCallback(this, backCallback)
    }

    private fun onBackGestureReceived() {
        Log.i("BackGestureSnippet", "System back gesture intercepted")
    }
}

Обратный вызов следует включить, только если активный экран должен перехватывать нажатие кнопки "Назад". Отключите или удалите обратный вызов, если для кнопки "Назад" нужно использовать системное поведение по умолчанию или поведение навигации.

Дальнейшие действия

После того как вы реализуете обработку входных данных для этих событий, вы можете узнать больше об обработке других типов входных событий в следующих разделах: