טיפול בקלט פיזי ממשקפיים עם אודיו ותצוגה

מכשירי XR שנתמכים
ההנחיות האלה יעזרו לכם ליצור חוויות למכשירי XR מהסוגים הבאים.
משקפי אודיו ו
תצוגה

כדי לתעד ולעבד קלט של משתמשים שמועבר אל הפעילות המוקרנת של האפליקציה, או כדי להטמיע התנהגויות מותאמות אישית של לוח המגע, משתמשים בקלט עקיף של מצביע. כדי לטפל בסוגים אחרים של אירועים (כמו פעולת המצלמה), אפשר לעיין בקטעים הבאים במדריך הזה.

טיפול בפעולת המצלמה

בכל פעם שמשתמש לוחץ על לחצן המצלמה במכשיר, המערכת מעבירה אירוע קלט לפעילות המוקרנת של האפליקציה כפעולה של ProjectedInputEvent.ProjectedInputAction.TOGGLE_APP_CAMERA. האפליקציה יכולה לעקוב אחרי הפעולה הזו באמצעות dispatcher ייעודי:

@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.

התנועה של המשתמש תלויה בסוג המשקפיים:

  • במשקפיים עם תצוגה, החלקה למטה על משטח המגע מבצעת את תנועת החזרה של המערכת.
  • במשקפי שמע, החלקה אחורה בלוח המגע מבצעת את תנועת המערכת 'חזרה'.

צריך לרשום קריאה חוזרת (callback) של חזרה אם המסך הנוכחי צריך ליירט את הפעולה 'חזרה', למשל כדי לסגור שכבת-על או להציג אישור יציאה.

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

צריך להפעיל את הקריאה החוזרת רק כשהמסך הפעיל צריך ליירט את הפעולה 'חזרה'. משביתים או מסירים את הקריאה החוזרת (Callback) כשצריך להשתמש בהתנהגות ברירת המחדל של המערכת או של הניווט כדי לטפל בפעולת החזרה.

השלבים הבאים

אחרי שמטמיעים את הטיפול בקלט עבור האירועים האלה, אפשר לקרוא מידע נוסף על טיפול בסוגים אחרים של אירועי קלט בנושאים הבאים: