오디오 및 디스플레이 글라스의 실제 입력 처리

적용 가능한 XR 기기
이 가이드에서는 이러한 유형의 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를 사용하여 앱의 프로젝션된 활동에 전달되는 일반 모션 이벤트를 검사합니다. 일반 모션 이벤트는 활동 경계에서 전달되며 포커스가 맞춰진 Jetpack Compose Glimmer 구성요소가 필요하지 않습니다.

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)를 반환합니다.

시스템 뒤로 동작 처리

화면에 맞춤 뒤로 동작이 필요한 경우 앱은 다른 활동에 사용하는 것과 동일한 Android API(예: 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")
    }
}

콜백은 활성 화면에서 뒤로를 가로채야 하는 경우에만 사용 설정해야 합니다. 기본 시스템 또는 탐색 동작에서 뒤로를 처리해야 하는 경우 콜백을 사용 중지하거나 삭제합니다.

다음 단계

이러한 이벤트의 입력 처리를 구현한 후 다음 주제에서 다른 유형의 입력 이벤트 처리에 관해 자세히 알아볼 수 있습니다.