استخدام سياق مُتوقّع للوصول إلى أجهزة نظارات الذكاء الاصطناعي

أجهزة XR المعنيّة
تساعدك هذه الإرشادات في إنشاء تجارب لهذه الأنواع من أجهزة الواقع الممتد.
نظارات AI Glasses

بعد طلب الأذونات اللازمة والحصول عليها، يمكن لتطبيقك الوصول إلى أجهزة نظارات الذكاء الاصطناعي. للوصول إلى أجهزة النظارات (بدلاً من أجهزة الهاتف)، يجب استخدام سياق معروض.

هناك طريقتان أساسيتان للحصول على سياق متوقّع، وذلك حسب مكان تنفيذ الرمز البرمجي:

الحصول على سياق متوقّع إذا كان الرمز البرمجي يعمل في نشاط نظارات الذكاء الاصطناعي

إذا كان رمز تطبيقك يعمل من داخل نشاط نظارات الذكاء الاصطناعي، سيكون سياق النشاط الخاص به سياقًا معروضًا. في هذا السيناريو، يمكن للمكالمات التي يتم إجراؤها ضمن هذا النشاط الوصول إلى أجهزة النظارات.

الحصول على سياق مسقط إذا كان الرمز البرمجي يعمل في أحد مكونات تطبيق الهاتف

إذا كان جزء من تطبيقك خارج نطاق نشاط نظارات الذكاء الاصطناعي (مثل نشاط على الهاتف أو خدمة) يحتاج إلى الوصول إلى أجهزة النظارات، يجب أن يحصل صراحةً على سياق معروض. لإجراء ذلك، استخدِم طريقة createProjectedDeviceContext():

// From a phone Activity, get a context for the AI glasses
try {
    val glassesContext = ProjectedContext.createProjectedDeviceContext(this)
    // Now use glassesContext to access glasses' system services
} catch (e: IllegalStateException) {
    // Projected device was not found
}

التحقّق من الصلاحية

بعد إنشاء السياق المتوقّع، راقِب ProjectedContext.isProjectedDeviceConnected. على الرغم من أنّ هذه الطريقة تعرض true، يظل السياق المعروض صالحًا للجهاز المتصل، ويمكن لتطبيق الهاتف أو الخدمة (مثل CameraManager) الوصول إلى أجهزة نظارات الذكاء الاصطناعي.

تنظيف البيانات عند قطع الاتصال

يرتبط السياق المعروض بدورة حياة الجهاز المتصل، لذا يتم إتلافه عند قطع اتصال الجهاز. عندما ينقطع اتصال الجهاز، تعرض الدالة ProjectedContext.isProjectedDeviceConnected القيمة false. يجب أن يستجيب تطبيقك لهذا التغيير وأن يزيل أي خدمات نظام (مثل CameraManager) أو موارد أنشأها تطبيقك باستخدام سياق العرض هذا.

إعادة التهيئة عند إعادة الاتصال

عند إعادة توصيل نظارات الذكاء الاصطناعي، يمكن لتطبيقك الحصول على مثيل آخر للسياق المعروض باستخدام createProjectedDeviceContext()، ثم إعادة تهيئة أي خدمات أو مراجع للنظام باستخدام السياق المعروض الجديد.

الوصول إلى الصوت باستخدام البلوتوث

في الوقت الحالي، يتم توصيل نظارات الذكاء الاصطناعي بهاتفك كجهاز صوت عادي يعمل بالبلوتوث. يتوافق الجهاز مع كل من سمّاعة الرأس وملفات A2DP (نمط توزيع الصوت المتقدّم). يتيح استخدام هذه الطريقة تشغيل أي تطبيق Android متوافق مع إدخال الصوت أو إخراجه على النظارات، حتى إذا لم يتم تصميمه خصيصًا ليتوافق مع النظارات. في بعض الحالات، قد يكون استخدام البلوتوث خيارًا أفضل لحالة استخدام تطبيقك كبديل للوصول إلى أجهزة النظارات باستخدام سياق معروض.

كما هو الحال مع أي جهاز صوتي عادي يتضمّن بلوتوث، يتم التحكّم في إذن منح الإذن RECORD_AUDIO من خلال الهاتف وليس النظارات.

التقاط صورة باستخدام كاميرا النظارات الذكية المستندة إلى الذكاء الاصطناعي

لالتقاط صورة باستخدام كاميرا النظارات الذكية المستندة إلى الذكاء الاصطناعي، يجب إعداد حالة استخدام ImageCapture CameraX وربطها بكاميرا النظارات باستخدام السياق الصحيح لتطبيقك:

private fun startCamera() {
    // Get the CameraProvider using the projected context.

    val cameraProviderFuture = ProcessCameraProvider.getInstance(
        ProjectedContext.createProjectedDeviceContext(this)
    )

    cameraProviderFuture.addListener({
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Select the camera. When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    
        // Check for the presence of a camera before initializing the ImageCapture use case.
       if (!cameraProvider.hasCamera(cameraSelector)) {
            Log.w(TAG, "The selected camera is not available.")
            return@addListener
        }

        // Get supported streaming resolutions.
        val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
        val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
        val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)

        // 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()

        // 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, 30)
        val captureRequestOptions = CaptureRequestOptions.Builder()
                .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,fpsRange)
                .build()

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

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

            // 4. Bind use cases to camera
            cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageCapture)

        } catch(exc: Exception) {
            // This catches exceptions like IllegalStateException if use case binding fails
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

النقاط الرئيسية حول الرمز

  • يحصل على مثيل من ProcessCameraProvider باستخدام سياق الجهاز المتوقّع.
  • ضمن نطاق السياق المتوقّع، تتوافق الكاميرا الأساسية الخارجية في نظارات الذكاء الاصطناعي مع DEFAULT_BACK_CAMERA عند اختيار كاميرا.
  • يستخدم فحص الربط المسبق cameraProvider.hasCamera(cameraSelector) للتأكّد من توفّر الكاميرا المحدّدة على الجهاز قبل المتابعة.
  • يستخدم Camera2 Interop مع Camera2CameraInfo لقراءة CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP الأساسي، وهو ما قد يكون مفيدًا لإجراء عمليات تحقّق متقدّمة من درجات الدقة المتوافقة.
  • تم إنشاء ResolutionSelector مخصّص للتحكّم بدقة في درجة دقة الصورة الناتجة عن ImageCapture.
  • تنشئ هذه الطريقة ImageCapture حالة استخدام تم ضبطها باستخدام ResolutionSelector مخصّص.
  • يربط هذا الإجراء حالة استخدام ImageCapture بدورة حياة النشاط. تتولّى هذه الفئة إدارة فتح الكاميرا وإغلاقها تلقائيًا استنادًا إلى حالة النشاط (على سبيل المثال، إيقاف الكاميرا مؤقتًا عند إيقاف النشاط مؤقتًا).

بعد إعداد كاميرا نظارات الذكاء الاصطناعي، يمكنك التقاط صورة باستخدام الفئة ImageCapture في CameraX. راجِع مستندات CameraX للتعرّف على كيفية استخدام takePicture() من أجل التقاط صورة.

تسجيل فيديو باستخدام كاميرا النظارات الذكية المستندة إلى الذكاء الاصطناعي

لالتقاط فيديو بدلاً من صورة باستخدام كاميرا نظارات الذكاء الاصطناعي، استبدِل المكوّنات ImageCapture بمكوّنات VideoCapture المقابلة وعدِّل منطق تنفيذ عملية الالتقاط.

تتضمّن التغييرات الرئيسية استخدام حالة استخدام مختلفة، وإنشاء ملف إخراج مختلف، وبدء عملية الالتقاط باستخدام طريقة تسجيل الفيديو المناسبة. لمزيد من المعلومات حول واجهة برمجة التطبيقات VideoCapture وكيفية استخدامها، يُرجى الاطّلاع على مستندات التقاط الفيديو في CameraX.

يعرض الجدول التالي درجة الدقة وعدد اللقطات في الثانية المقترَحة استنادًا إلى حالة استخدام تطبيقك:

حالة الاستخدام درجة الدقة عدد اللقطات في الثانية
التواصل عبر الفيديو ‫‎1280 x 720 ‫15 لقطة في الثانية
الرؤية الحاسوبية 640 x 480 10 لقطات في الثانية
بث الفيديو من إنشاء الذكاء الاصطناعي 640 x 480 لقطة واحدة في الثانية

الوصول إلى أجهزة الهاتف من خلال نشاط نظارات الذكاء الاصطناعي

يمكن أيضًا لنشاط نظارات الذكاء الاصطناعي الوصول إلى أجهزة الهاتف (مثل الكاميرا أو الميكروفون) باستخدام createHostDeviceContext(context) للحصول على سياق الجهاز المضيف (الهاتف):

// From an AI glasses Activity, get a context for the phone
val phoneContext = ProjectedContext.createHostDeviceContext(this)
// Now use phoneContext to access the phone's hardware

عند الوصول إلى أجهزة أو مراجع خاصة بالجهاز المضيف (الهاتف) في تطبيق مختلط (تطبيق يتضمّن تجارب على الأجهزة الجوّالة ونظارات الذكاء الاصطناعي)، عليك اختيار السياق الصحيح بشكلٍ صريح للتأكّد من أنّ تطبيقك يمكنه الوصول إلى الأجهزة الصحيحة:

  • استخدِم سياق Activity من الهاتف Activity أو ProjectedContext.createHostDeviceContext() للحصول على سياق الهاتف.
  • لا تستخدِم getApplicationContext() لأنّ سياق التطبيق قد يعرض بشكل غير صحيح سياق نظارات الذكاء الاصطناعي إذا كان نشاط النظارات هو المكوّن الذي تم إطلاقه مؤخرًا.