অডিও ও ডিসপ্লে গ্লাস থেকে ফিজিক্যাল ইনপুট ম্যানেজ করা

প্রযোজ্য 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 গ্লিমার কম্পোনেন্ট প্রয়োজন হয় না।

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 ব্যবহার করে glasses ব্যাক জেসচার হ্যান্ডেল করতে হবে, যেমন 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")
    }
}

কলব্যাক তখনই চালু করা উচিত যখন অ্যাক্টিভ স্ক্রিনকে ব্যাক ইন্টারসেপ্ট করতে হবে। ডিফল্ট সিস্টেম বা নেভিগেশন আচরণ 'ফিরে যান' হ্যান্ডেল করার কথা থাকলে, কলব্যাক বন্ধ করুন বা সরিয়ে দিন।

পরবর্তী ধাপ

এইসব ইভেন্টের জন্য ইনপুট হ্যান্ডেল করার পরে, আপনি নিম্নলিখিত বিষয়গুলি থেকে অন্যান্য ধরনের ইনপুট ইভেন্ট হ্যান্ডেল করা সম্পর্কে আরও জানতে পারবেন: