অডিও গ্লাস ও ডিসপ্লে গ্লাসে হার্ডওয়্যার অ্যাক্সেস করতে প্রজেক্ট করা কন্টেক্সট ব্যবহার করা

প্রযোজ্য XR ডিভাইস
এইসব XR ডিভাইসের জন্য অভিজ্ঞতা তৈরি করতে এই নির্দেশিকা আপনাকে সাহায্য করে।
অডিও ও
ডিসপ্লে গ্লাস

প্রয়োজনীয় অনুমতি চেয়ে নেওয়ার পরে তা মঞ্জুর করা হলে, আপনার অ্যাপ অডিও গ্লাস বা ডিসপ্লে গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে পারবে। গ্লাসের হার্ডওয়্যার (ফোনের হার্ডওয়্যারের পরিবর্তে) অ্যাক্সেস করার মূল চাবিকাঠি হল প্রজেক্ট করা প্রসঙ্গ ব্যবহার করা।

প্রজেক্টেড প্রসঙ্গ পাওয়ার দুটি প্রাথমিক উপায় আছে, এটি নির্ভর করে আপনার কোড কোথায় এক্সিকিউট হচ্ছে তার উপর:

আপনার কোড কোনও প্রজেক্টেড অ্যাক্টিভিটিতে রান করলে, প্রজেক্ট করা প্রসঙ্গ পান

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

ফোন অ্যাপ কম্পোনেন্টে রান করা কোডের জন্য প্রজেক্ট করা প্রসঙ্গ পাওয়া

আপনার প্রোজেক্ট করা অ্যাক্টিভিটি (যেমন, ফোন অ্যাক্টিভিটি বা পরিষেবা) ছাড়া অ্যাপের কোনও অংশকে গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে হলে, সেটিকে অবশ্যই প্রোজেক্ট করা কনটেক্সট পেতে হবে। এটি করতে, createProjectedDeviceContext পদ্ধতি ব্যবহার করুন:

@RequiresApi(Build.VERSION_CODES.BAKLAVA)
@OptIn(ExperimentalProjectedApi::class, ExperimentalCoroutinesApi::class)
private fun monitorProjectedConnectivity(activity: ComponentActivity) {
    activity.lifecycleScope.launch {
        // Before creating a projected context, check to see if the projected device is connected.
        // While this method returns true, the projected context remains valid.
        ProjectedContext.isProjectedDeviceConnected(activity, coroutineContext)
            .collectLatest { isConnected ->
                if (isConnected) {
                    // From a phone Activity or Service, get a context for the audio and display glasses.
                    // Re-initialize on reconnect: Obtain another context instance.
                    val projectedContext = try {
                        ProjectedContext.createProjectedDeviceContext(activity)
                    } catch (e: IllegalStateException) {
                        Log.e(TAG, "Failed to create projected context", e)
                        return@collectLatest
                    }

                    // Use the projectedContext to initialize system services (e.g., CameraManager).
                    Log.i(TAG, "Projected device connected. Initializing hardware...")
                } else {
                    // The projected context is destroyed when the device disconnects.
                    // Clean up on disconnect: Listen for 'false' and release resources.
                    Log.i(TAG, "Projected device disconnected. Cleaning up hardware resources...")
                }
            }
    }
}

বৈধ কিনা চেক করা

ProjectedContext.isProjectedDeviceConnected-এর মধ্যে createProjectedDeviceContext কলটি র‍্যাপ করুন। এই পদ্ধতি true রিটার্ন করলেও, কানেক্ট করা ডিভাইসের জন্য প্রজেক্ট করা প্রসঙ্গ বৈধ থাকে এবং আপনার ফোন অ্যাপ অ্যাক্টিভিটি বা পরিষেবা (যেমন CameraManager) AI গ্লাস হার্ডওয়্যার অ্যাক্সেস করতে পারে।

ডিসকানেক্ট হলে ক্লিন-আপ করা

প্রজেক্ট করা প্রসঙ্গ কানেক্ট করা ডিভাইসের লাইফসাইকেলের সাথে যুক্ত থাকে, তাই ডিভাইস ডিসকানেক্ট হয়ে গেলে এটি ধ্বংস হয়ে যায়। ডিভাইস ডিসকানেক্ট হয়ে গেলে, ProjectedContext.isProjectedDeviceConnected false রিটার্ন করে। আপনার অ্যাপকে এই পরিবর্তনের ব্যাপারে শুনতে হবে এবং কোনও সিস্টেম পরিষেবা (যেমন, একটি CameraManager) বা রিসোর্স যা আপনার অ্যাপ সেই প্রজেক্ট করা কন্টেক্সট ব্যবহার করে তৈরি করেছে, তা ক্লিন-আপ করতে হবে।

আবার কানেক্ট করার সময় আবার চালু করা

গ্লাস আবার কানেক্ট করলে, আপনার অ্যাপ createProjectedDeviceContext ব্যবহার করে আরেকটি প্রজেক্ট করা কনটেক্সট ইনস্ট্যান্স পেতে পারে এবং তারপরে নতুন প্রজেক্ট করা কনটেক্সট ব্যবহার করে যেকোনও সিস্টেম পরিষেবা বা রিসোর্স আবার ইনিশিয়ালাইজ করতে পারে।

গ্লাসের মাইক্রোফোন দিয়ে অডিও রেকর্ড করা

দুটি আলাদা আলাদা পদ্ধতি ব্যবহার করে আপনি গ্লাস থেকে অডিও রেকর্ড করতে পারবেন:

রেকর্ডিং পদ্ধতি বেছে নিন

আপনি কোন পদ্ধতি বেছে নেবেন তা নির্ভর করে আপনার হাই-ফিডেলিটি, XR-নির্দিষ্ট অডিও প্রসেসিং বা স্ট্যান্ডার্ড ব্লুটুথ অডিও ইনপুট প্রয়োজন কিনা তার উপর।

রেকর্ডিংয়ের পদ্ধতি মাইক্রোফোন অ্যাক্সেস করা সাধারণ ব্যবহার

প্রোজেক্ট করা প্রসঙ্গ

একাধিক মাইক্রোফোন

প্রজেক্ট করা প্রসঙ্গ ব্যবহার করে রেকর্ড করলে, আপনার অ্যাপ গ্লাস থেকে একাধিক মাইক্রোফোন এবং এর বিশেষ হার্ডওয়্যার ফিচার অ্যাক্সেস করতে পারে, যেমন:

  • XR-নির্দিষ্ট স্প্যাশিয়ালাইজেশন।
  • উন্নত ডিনয়েজিং।
  • ভয়েস সেপারেশন যা পরিধানকারীর ভয়েসকে আলাদা করে।
  • মাল্টি-ডিভাইস এনভায়রনমেন্টে রেকর্ডিং অ্যাক্সেস বজায় রাখুন, এমনকি গ্লাস অ্যাক্টিভ ব্লুটুথ ডিভাইস না থাকলেও।

ব্লুটুথ HFP

সিঙ্গেল মাইক্রোফোন

তৎক্ষণাৎ, বক্সের বাইরেই মানানসই হওয়ার জন্য ব্লুটুথ হ্যান্ডস-ফ্রি প্রোফাইলের (HFP) উপর নির্ভর করে। এই মোডে, সাধারণ হেডসেট এবং অ্যাডভান্সড অডিও ডিস্ট্রিবিউশন প্রোফাইল (A2DP) প্রোফাইল ব্যবহার করে গ্লাসটি ফোনের সাথে কানেক্ট করে, যা সাধারণ ব্লুটুথ পেরিফেরালের মতো কাজ করে।

আপনার অ্যাপ যদি আগে থেকেই স্ট্যান্ডার্ড ব্লুটুথ রেকর্ডিংয়ের জন্য ডিজাইন করা হয়ে থাকে, তাহলে কোনও XR-নির্দিষ্ট ক্ষমতা ইন্টিগ্রেট না করেই গ্লাস থেকে অডিও রেকর্ড করতে আপনি এই পদ্ধতি ব্যবহার করতে পারবেন।

প্রজেক্ট করা কন্টেক্সট ব্যবহার করে অডিও রেকর্ড করা

প্রজেক্ট করা কন্টেক্সট ব্যবহার করে অডিও রেকর্ড করতে, প্রথমে প্রয়োজনীয় রানটাইম অনুমতির অনুরোধ করুন এবং তারপরে নিম্নলিখিত বিভাগে বর্ণিত AudioRecord API ব্যবহার করে অডিও রেকর্ড করুন।

রানটাইম অনুমতির জন্য অনুরোধ করা

গ্লাসে একাধিক মাইক্রোফোন অ্যাক্সেস করতে, আপনাকে অবশ্যই প্রজেক্ট করা ডিভাইসের জন্য বিশেষভাবে অডিও অনুমতির অনুরোধ করতে হবে। ব্যবহারকারী তার মোবাইল ডিভাইসে আপনার অ্যাপের জন্য যে স্ট্যান্ডার্ড, ফোন-স্কোপড RECORD_AUDIO অনুমতি দিয়েছেন তা যথেষ্ট নয়।

অনুমতির অনুরোধ করতে এইসব ধাপ অনুসরণ করুন:

  1. আপনার অ্যাপের ম্যানিফেস্ট ফাইলে RECORD_AUDIO অনুমতি ঘোষণা করুন।
  2. আপনার কোড কোথায় এক্সিকিউট হচ্ছে তার উপর নির্ভর করে, নিম্নলিখিত পদ্ধতিগুলির মধ্যে কোনও একটিতে প্রজেক্টেড-ডিভাইস-স্কোপড অনুমতির অনুরোধ করুন:

প্রজেক্ট করা কনটেক্সট সহ AudioRecord ইনিশিয়ালাইজ করা

হোস্ট ফোনের পরিবর্তে গ্লাস থেকে অডিও রেকর্ড করা হচ্ছে কিনা তা নিশ্চিত করতে, প্রজেক্ট করা ডিভাইস কনটেক্সটের সাথে আপনাকে অবশ্যই AudioRecord অবজেক্ট অ্যাসোসিয়েট করতে হবে।

নিচে দেওয়া কোডটি AudioRecord.Builder ব্যবহার করে এবং setContext পদ্ধতিতে projectedDeviceContext পাস করে:

// Initialize AudioRecord with projected device context
val audioRecord = AudioRecord.Builder()
    .setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
    .setAudioFormat(audioFormat)
    .setBufferSizeInBytes(bufferSize)
    // pass in the projected device context
    .setContext(projectedDeviceContext)
    .build()

audioRecord.startRecording()

কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট
  • আপনার নির্দিষ্ট ব্যবহারের ক্ষেত্রে অডিও প্রসেসিং কাস্টমাইজ করতে, আপনি অডিও সোর্সকে CAMCORDER, VOICE_RECOGNITION, VOICE_COMMUNICATION বা UNPROCESSED হিসেবে সেট করতে পারেন।

    যেমন, আপনার ব্যবহারের ক্ষেত্রে অটোমেটিক নয়েজ কমানোর প্রয়োজন হলে বা পরিধানকারীর ভয়েস আলাদা করার প্রয়োজন হলে VOICE_COMMUNICATION ব্যবহার করুন। VOICE_RECOGNITION-কে অ্যাকোস্টিক ইকো ক্যান্সেলেশন (AEC) দিয়ে প্রসেস করা হয়, যা রেকর্ডিং চলাকালীন একই সাথে অডিও প্লেব্যাক হলে সহায়ক হতে পারে। এবং আপনার যদি অপরিবর্তিত, কাঁচা অডিওর প্রয়োজন হয়, তাহলে UNPROCESSED বা CAMCORDER বেছে নিন।

  • গ্লাসের সাথে মানানসই কিনা তা নিশ্চিত করতে, audioFormat অবজেক্টকে ১৬kHz-এর স্যাম্পেল রেট এবং মোনো বা স্টিরিও (CHANNEL_IN_MONO বা CHANNEL_IN_STEREO ব্যবহার করে) চ্যানেল কনফিগারেশন নির্ধারণ করতে হবে।

  • AudioRecord অবজেক্ট তৈরি করার জন্য ন্যূনতম বাফার সাইজ নির্ধারণ করতে AudioRecord.getMinBufferSize() ব্যবহার করুন। তবে, গ্লাস থেকে অডিও ড্রপ প্রতিরোধ করতে, আপনাকে সম্পূর্ণ বাফার পূরণ হওয়ার জন্য অপেক্ষা করার পরিবর্তে, ছোট, ঘন ঘন চ্যাঙ্ক (আদর্শভাবে ২০ms স্লাইস) থেকে পড়তে হবে।

ব্যবহারের পরে পরিষ্কার করা

আপনার অ্যাপের আর মাইক্রোফোন প্রয়োজন না হলে অথবা অ্যাক্টিভিটি বন্ধ হয়ে গেলে, AudioRecord অবজেক্টে stop ও release কল করুন।

রেকর্ড করার আগে রানটাইম অনুমতি চেক করা

startRecording নম্বরে কল করার আগে, প্রজেক্ট করা প্রসঙ্গ ব্যবহার করে যাচাই করুন যে ব্যবহারকারী গ্লাসের জন্য মাইক্রোফোন সংক্রান্ত অনুমতি দিয়েছেন কিনা।

ব্লুটুথ HFP ব্যবহার করে অডিও রেকর্ড করা

Bluetooth HFP ব্যবহার করে অডিও রেকর্ড করতে, প্রথমে প্রয়োজনীয় রানটাইম পারমিশনের অনুরোধ করুন এবং তারপরে AudioManager API ব্যবহার করে অডিও রেকর্ড করুন, যেমন নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে।

অনুমতির জন্য অনুরোধ করা

যেকোনও স্ট্যান্ডার্ড ব্লুটুথ অডিও ডিভাইসের মতো, RECORD_AUDIO, BLUETOOTH_CONNECT এবং অন্যান্য সম্পর্কিত অনুমতিগুলি ফোন দ্বারা নিয়ন্ত্রিত হয়, কানেক্ট করা ডিভাইস (যেমন অডিও গ্লাস বা ডিসপ্লে গ্লাস) দ্বারা নয়।

অনুমতির অনুরোধ করতে এইসব ধাপ অনুসরণ করুন:

  1. আপনার অ্যাপের ম্যানিফেস্ট ফাইলে নিম্নলিখিত অনুমতি ঘোষণা করুন:

  2. স্ট্যান্ডার্ড Android অনুমতি ফ্লো ব্যবহার করে রানটাইমে RECORD_AUDIO ও BLUETOOTH_CONNECT, দুটি অনুমতির জন্যই অনুরোধ করুন।

অডিও রাউট করতে AudioManager ব্যবহার করা

ব্যবহারকারী আপনার অ্যাপকে প্রয়োজনীয় রানটাইম অনুমতি দেওয়ার পরে, ব্লুটুথ HFP-এর মাধ্যমে অডিও রাউট করতে, TYPE_BLUETOOTH_SCO-এ কমিউনিকেশন ডিভাইস সেট করতে AudioManager API ব্যবহার করুন। এটি সিস্টেমকে ব্লুটুথ পেরিফেরাল থেকে অডিও রিট্রিভ করার নির্দেশ দেয়।

val audioManager = context.getSystemService(AudioManager::class.java) ?: return
val devices = audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)
val hfpDevice = devices.find { it.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO }

hfpDevice?.let { device ->
    val audioRecord = AudioRecord.Builder()
        .setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
        .setAudioFormat(audioFormat)
        .setBufferSizeInBytes(bufferSize)
        .build()

    // Route recording to the Bluetooth device
    audioRecord.setPreferredDevice(device)
    audioManager.setCommunicationDevice(device)

    audioRecord.startRecording()

গ্লাসের ক্যামেরা দিয়ে ছবি ক্যাপচার করা

গ্লাসের ক্যামেরা দিয়ে ছবি ক্যাপচার করতে, আপনার অ্যাপের জন্য সঠিক কন্টেক্সট ব্যবহার করে গ্লাসের ক্যামেরায় CameraX-এর ImageCapture ব্যবহারের কেস সেট-আপ ও বাইন্ড করুন:

private fun startCameraOnGlasses(activity: ComponentActivity) {
    activity.lifecycleScope.launch {
        // Before creating a projected context, check to see if the projected device is connected.
        ProjectedContext.isProjectedDeviceConnected(activity, coroutineContext)
            .collectLatest { isConnected ->
                if (isConnected) {
                    // 1. Get the CameraProvider using the projected context.
                    // When using the projected context, DEFAULT_BACK_CAMERA maps to the audio and display glasses' camera.
                    val projectedContext = try {
                        ProjectedContext.createProjectedDeviceContext(activity)
                    } catch (e: IllegalStateException) {
                        Log.e(TAG, "Projected context could not be created", e)
                        return@collectLatest
                    }

                    val cameraProviderFuture = ProcessCameraProvider.getInstance(projectedContext)

                    cameraProviderFuture.addListener({
                        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
                        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

                        // 2. Check for the presence of a camera.
                        if (!cameraProvider.hasCamera(cameraSelector)) {
                            Log.w(TAG, "The selected camera is not available.")
                            return@addListener
                        }

                        // 3. Query supported streaming resolutions using Camera2 Interop.
                        val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
                        val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
                        val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(
                            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
                        )

                        // 4. Define the resolution strategy.
                        val targetResolution = Size(1920, 1080)
                        val resolutionStrategy = ResolutionStrategy(
                            targetResolution,
                            ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER
                        )
                        val resolutionSelector = ResolutionSelector.Builder()
                            .setResolutionStrategy(resolutionStrategy)
                            .build()

                        // 5. If you have other continuous use cases bound, such as Preview or ImageAnalysis,
                        // you can use  Camera2 Interop's CaptureRequestOptions to set the FPS
                        val fpsRange = Range(30, 60)
                        val captureRequestOptions = CaptureRequestOptions.Builder()
                            .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange)
                            .build()

                        // 6. Initialize the ImageCapture use case with options.
                        val imageCapture = ImageCapture.Builder()
                            // Optional: Configure resolution, format, etc.
                            .setResolutionSelector(resolutionSelector)
                            .build()

                        try {
                            // Unbind use cases before rebinding.
                            cameraProvider.unbindAll()

                            // Bind use cases to camera using the Activity as the LifecycleOwner.
                            cameraProvider.bindToLifecycle(
                                activity,
                                cameraSelector,
                                imageCapture
                            )
                        } catch (exc: Exception) {
                            Log.e(TAG, "Use case binding failed", exc)
                        }
                    }, ContextCompat.getMainExecutor(activity))
                }
            }
    }
}

কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট

  • ProcessCameraProvider-এর একটি ইনস্ট্যান্স পায়, যা প্রজেক্ট করা ডিভাইস কনটেক্সট ব্যবহার করে।
  • প্রজেক্ট করা কনটেক্সটের স্কোপের মধ্যে, গ্লাসের প্রাথমিক, বাইরের দিকে পয়েন্ট করা ক্যামেরা, কোনও ক্যামেরা বেছে নেওয়ার সময় DEFAULT_BACK_CAMERA-এর সাথে ম্যাপ করে।
  • প্রি-বাইন্ডিং চেক cameraProvider.hasCamera(cameraSelector) ব্যবহার করে যাচাই করে যে বেছে নেওয়া ক্যামেরাটি ডিভাইসে উপলভ্য আছে কিনা তারপরেই প্রসেসটি এগিয়ে নিয়ে যাওয়া হয়।
  • Camera2CameraInfo-এর সাথে Camera2 Interop ব্যবহার করে আন্ডারলায়িং CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP পড়ে, যা কাজ করে এমন রেজোলিউশনের ক্ষেত্রে উন্নত চেক করার জন্য কাজে লাগতে পারে।
  • ResolutionSelector কাস্টমাইজ করা হয়েছে যাতে ImageCapture-এর জন্য আউটপুট ইমেজ রেজোলিউশন নিখুঁতভাবে কন্ট্রোল করা যায়।
  • ImageCapture ব্যবহার করার এমন একটি কেস তৈরি করে যা কাস্টম ResolutionSelector-এর সাথে কনফিগার করা হয়।
  • অ্যাক্টিভিটির লাইফসাইকেলের সাথে ImageCapture ব্যবহারের কেসকে বাইন্ড করে। এটি অ্যাক্টিভিটির স্টেট (যেমন, অ্যাক্টিভিটি পজ করা হলে ক্যামেরা বন্ধ করা) অনুযায়ী ক্যামেরা খোলা ও বন্ধ করা অটোমেটিক ম্যানেজ করে।
  • সিঙ্গেল-স্ট্রিম হার্ডওয়্যারের জন্য কনফিগার করা: গ্লাস ক্যামেরার পাইপলাইন একবারে একটি অ্যাক্টিভ স্ট্রিমের মধ্যে সীমাবদ্ধ। ImageCapture একা বাউন্ড থাকলে, CameraX ডিফল্ট হিসেবে ফোকাস ও মিটারের জন্য একটি ইন্টার্নাল রিপিটিং স্ট্রিম (MeteringRepeating) অ্যাটাচ করে, যার ফলে সিঙ্গেল-স্ট্রিম পাইপলাইন স্টল হয়ে যায়। প্রিভিউ স্ট্রিম ছাড়াই ImageCapture অটোমেটিক বাইন্ড করতে, বাধ্য হয়ে রিপিট করা স্ট্রিম বন্ধ করুন setRepeatingStreamForced(false) CameraXConfig.Builder সেট করে (যেমন, আপনার Application ক্লাসে CameraXConfig.Provider প্রয়োগ করে অথবা ইনিশিয়ালাইজেশনের আগে ProcessCameraProvider কনফিগার করে)।

গ্লাসের ক্যামেরা সেট-আপ করার পরে, আপনি CameraX-এর ImageCapture ক্লাস ব্যবহার করে ছবি ক্যাপচার করতে পারবেন। ছবি ক্যাপচার করার জন্য takePicture ব্যবহার করার বিষয়ে জানতে CameraX-এর ডকুমেন্টেশন দেখুন।

গ্লাসের ক্যামেরা দিয়ে ভিডিও ক্যাপচার করা

গ্লাসের ক্যামেরা দিয়ে ছবি তোলার পরিবর্তে ভিডিও ক্যাপচার করতে, সংশ্লিষ্ট VideoCapture কম্পোনেন্ট দিয়ে ImageCapture কম্পোনেন্ট পাল্টে দিন এবং ক্যাপচার এক্সিকিউশন লজিক পরিবর্তন করুন।

প্রধান পরিবর্তনগুলির মধ্যে রয়েছে, আলাদা আলাদা ব্যবহারের ক্ষেত্র ব্যবহার করা, আলাদা আউটপুট ফাইল তৈরি করা এবং উপযুক্ত ভিডিও রেকর্ডিং পদ্ধতি ব্যবহার করে ক্যাপচার শুরু করা। VideoCapture API এবং এটি কীভাবে ব্যবহার করতে হয় সেই সম্পর্কে আরও তথ্য পেতে, CameraX-এর ভিডিও ক্যাপচার ডকুমেন্টেশন দেখুন।

নিচের টেবিলে আপনার অ্যাপের ব্যবহারের কেস অনুযায়ী সাজেস্ট করা রেজোলিউশন ও ফ্রেম রেট দেখানো হয়েছে:

ব্যবহারের উদাহরণ রেজোলিউশন ফ্রেম রেট
ভিডিও কমিউনিকেশন ১২৮০ x ৭২০ ১৫ FPS
কম্পিউটার ভিশন ৬৪০ x ৪৮০ ১০ FPS
AI ভিডিও স্ট্রিমিং ৬৪০ x ৪৮০ ১ FPS

প্রজেক্ট করা অ্যাক্টিভিটি থেকে ফোনের হার্ডওয়্যার অ্যাক্সেস করা

এছাড়াও, প্রজেক্ট করা অ্যাক্টিভিটি, createHostDeviceContext(context) ব্যবহার করে ফোনের হার্ডওয়্যার (যেমন ক্যামেরা বা মাইক্রোফোন) অ্যাক্সেস করতে পারে, যাতে হোস্ট ডিভাইসের (ফোন) কনটেক্সট পাওয়া যায়:

@OptIn(ExperimentalProjectedApi::class)
private fun getPhoneContext(activity: ComponentActivity): Context? {
    return try {
        // From a projected Activity, get a context for the phone.
        ProjectedContext.createHostDeviceContext(activity)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Failed to create host device context", e)
        null
    }
}

হাইব্রিড অ্যাপে (মোবাইল ও গ্লাস দুটি অভিজ্ঞতা আছে এমন অ্যাপ) হোস্ট ডিভাইসের (ফোন) জন্য নির্দিষ্ট হার্ডওয়্যার বা রিসোর্স অ্যাক্সেস করার সময়, আপনার অ্যাপ যাতে সঠিক হার্ডওয়্যার অ্যাক্সেস করতে পারে তা নিশ্চিত করতে আপনাকে অবশ্যই সঠিক কনটেক্সট বেছে নিতে হবে:

  • ফোনের Activity কনটেক্সট Activity অথবা ProjectedContext.createHostDeviceContext ব্যবহার করে ফোনের কনটেক্সট পান।
  • getApplicationContext ব্যবহার করবেন না, কারণ প্রজেক্ট করা অ্যাক্টিভিটি যদি সবচেয়ে সম্প্রতি লঞ্চ করা কম্পোনেন্ট হয়, তাহলে অ্যাপ্লিকেশন কনটেক্সট ভুল করে গ্লাসের কনটেক্সট রিটার্ন করতে পারে।