Xử lý dữ liệu đầu vào thực từ kính phát âm thanh và kính có màn hình

Các thiết bị XR được hỗ trợ
Hướng dẫn này giúp bạn xây dựng các trải nghiệm cho những loại thiết bị XR sau.
Kính âm thanh và
kính hiển thị

Để ghi lại và xử lý hoạt động đầu vào của người dùng được gửi đến hoạt động được chiếu của ứng dụng hoặc để triển khai các hành vi tuỳ chỉnh của bàn di chuột, hãy sử dụng dữ liệu đầu vào của con trỏ gián tiếp. Để xử lý các loại sự kiện khác (chẳng hạn như thao tác camera), hãy xem các phần sau trong hướng dẫn này.

Xử lý thao tác camera

Bất cứ khi nào người dùng nhấn nút camera của thiết bị, hệ thống sẽ gửi một sự kiện đầu vào đến hoạt động được chiếu của ứng dụng dưới dạng một thao tác ProjectedInputEvent.ProjectedInputAction.TOGGLE_APP_CAMERA. Ứng dụng của bạn có thể theo dõi thao tác này bằng một trình điều phối chuyên dụng:

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

Kiểm tra các sự kiện chuyển động chung

Sử dụng dispatchGenericMotionEvent để kiểm tra các sự kiện chuyển động chung được gửi đến hoạt động dự kiến của ứng dụng. Các sự kiện chuyển động chung được gửi tại ranh giới hoạt động và không yêu cầu thành phần Jetpack Compose Glimmer được lấy tiêu điểm.

MotionEvent có thể bao gồm:

Không phải giá trị nào cũng có ý nghĩa đối với mọi hành động. Kiểm tra hành động và nguồn trước khi coi một sự kiện thô là một cử chỉ hoàn tất.

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

Chỉ trả về true khi hoạt động cố ý sử dụng sự kiện. Nếu không, hãy trả về super.dispatchGenericMotionEvent(ev) để sự kiện có thể tiếp tục thông qua quy trình gửi thông thường.

Xử lý cử chỉ Quay lại của hệ thống

Khi màn hình cần có hành vi tuỳ chỉnh cho thao tác quay lại, ứng dụng của bạn nên xử lý cử chỉ Quay lại trên kính bằng cách sử dụng cùng các API Android mà bạn dùng cho các hoạt động khác, chẳng hạn như OnBackPressedDispatcherOnBackPressedCallback.

Cử chỉ của người dùng phụ thuộc vào loại kính:

  • Trên kính hiển thị, thao tác vuốt xuống trên bàn di chuột sẽ thực hiện cử chỉ Quay lại của hệ thống.
  • Trên kính phát âm thanh, thao tác vuốt về phía sau trên bàn di chuột sẽ thực hiện cử chỉ Quay lại của hệ thống.

Đăng ký một lệnh gọi lại về thao tác quay lại khi màn hình hiện tại cần chặn thao tác Quay lại, chẳng hạn như đóng lớp phủ hoặc hiện thông báo xác nhận thoát.

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

Bạn chỉ nên bật lệnh gọi lại khi màn hình đang hoạt động cần chặn nút Quay lại. Tắt hoặc xoá lệnh gọi lại khi hành vi mặc định của hệ thống hoặc hành vi điều hướng sẽ xử lý thao tác Quay lại.

Các bước tiếp theo

Sau khi triển khai tính năng xử lý dữ liệu đầu vào cho các sự kiện này, bạn có thể tìm hiểu thêm về cách xử lý các loại sự kiện đầu vào khác trong các chủ đề sau: