Gestire l'input fisico dagli occhiali audio e con display

Dispositivi XR applicabili
Queste indicazioni ti aiutano a creare esperienze per questi tipi di dispositivi XR.
Occhiali audio e
display

Per acquisire ed elaborare l'input dell'utente fornito all'attività proiettata della tua app o per implementare comportamenti personalizzati del touchpad, utilizza gli input del puntatore indiretto. Per gestire altri tipi di eventi (ad esempio l'azione della videocamera), consulta le sezioni seguenti di questa guida.

Gestire l'azione della videocamera

Ogni volta che un utente preme il pulsante della videocamera di un dispositivo, il sistema invia un evento di input all'attività proiettata della tua app come ProjectedInputEvent.ProjectedInputAction.TOGGLE_APP_CAMERA azione. La tua app può osservare questa azione utilizzando un dispatcher dedicato:

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

Esaminare gli eventi di movimento generici

Utilizza dispatchGenericMotionEvent per esaminare gli eventi di movimento generici forniti all'attività proiettata della tua app. Gli eventi di movimento generici vengono forniti al limite dell'attività e non richiedono un componente Jetpack Compose Glimmer con stato attivo.

Un MotionEvent può includere:

Non tutti i valori sono significativi per ogni azione. Esamina l'azione e l'origine prima di trattare un evento non elaborato come un gesto completato.

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

Restituisci true solo quando l'attività utilizza intenzionalmente l'evento. In caso contrario, restituisci super.dispatchGenericMotionEvent(ev) in modo che l'evento possa continuare tramite l'invio normale.

Gestire il gesto Indietro del sistema

Quando uno schermo richiede un comportamento Indietro personalizzato, la tua app deve gestire il gesto Indietro degli occhiali utilizzando le stesse API Android che utilizzi per altre attività, ad esempio OnBackPressedDispatcher e OnBackPressedCallback.

L'attivazione dall'utente dipende dal tipo di occhiali:

  • Sugli occhiali con display, lo scorrimento verso il basso sul touchpad esegue il gesto Indietro del sistema.
  • Sugli occhiali audio, lo scorrimento indietro sul touchpad esegue il gesto Indietro del sistema.

Registra un callback Indietro quando la schermata corrente deve intercettare Indietro, ad esempio chiudendo una sovrapposizione o mostrando una conferma di uscita.

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

Il callback deve essere abilitato solo quando la schermata attiva deve intercettare Indietro. Disattiva o rimuovi il callback quando il comportamento predefinito del sistema o di navigazione deve gestire Indietro.

Passaggi successivi

Dopo aver implementato la gestione dell'input per questi eventi, puoi scoprire di più sulla gestione di altri tipi di eventi di input nei seguenti argomenti: