如需捕获并处理传递到应用投影 activity 的用户输入,或实现自定义触控板行为,请使用间接指针输入。如需处理其他类型的事件(例如相机操作),请参阅本指南中的以下部分。
处理相机操作
每当用户按下设备的相机按钮时,系统都会将输入事件作为 ProjectedInputEvent.ProjectedInputAction.TOGGLE_APP_CAMERA 操作传递给应用的投影 activity。您的应用可以使用专用调度程序来观察此操作:
@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 检查传递到应用投影 activity 的通用动作事件。通用运动事件在 activity 边界处传递,不需要聚焦的 Jetpack Compose Glimmer 组件。
MotionEvent 可以包括:
- 一种屏蔽操作,例如
ACTION_DOWN、ACTION_MOVE或ACTION_UP。 - 指针坐标,例如
AXIS_X、AXIS_Y或AXIS_Z。 - 设备和来源信息,例如设备 ID 和来源。
并非每个值都对每项操作有意义。在将原始事件视为已完成的手势之前,检查操作和来源。
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) } }
仅当 activity 有意消耗事件时才返回 true。
否则,返回 super.dispatchGenericMotionEvent(ev),以便事件可以通过正常调度继续进行。
处理系统返回手势
当屏幕需要自定义返回行为时,您的应用应使用与其他 activity 相同的 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") } }
仅当活动屏幕应拦截返回时,才应启用回调。当默认系统或导航行为应处理返回时,停用或移除回调。
后续步骤
为这些事件实现输入处理后,您可以在以下主题中详细了解如何处理其他类型的输入事件:
- 如需详细了解界面输入,请参阅 Jetpack Compose Glimmer 中的焦点和处理间接指针输入。
- 对于投影的输入事件,请参阅
ProjectedActivityCompat、ProjectedInputEvent和ProjectedInputEvent.ProjectedInputAction。 - 如需了解平台输入和导航,请参阅
MotionEvent和提供自定义返回导航。