ใช้บริบทที่คาดการณ์ไว้เพื่อเข้าถึงฮาร์ดแวร์แว่นตา AI

อุปกรณ์ XR ที่รองรับ
คำแนะนำนี้จะช่วยคุณสร้างประสบการณ์การใช้งานสำหรับอุปกรณ์ XR ประเภทต่างๆ
แว่นตา AI

หลังจากที่คุณได้ขอและได้รับสิทธิ์ที่จำเป็นแล้ว แอปของคุณ จะเข้าถึงฮาร์ดแวร์ของแว่นตา AI ได้ เคล็ดลับในการเข้าถึงฮาร์ดแวร์ของแว่นตา (แทนที่จะเป็นฮาร์ดแวร์ของโทรศัพท์) คือการใช้บริบทที่ฉายภาพ

มี 2 วิธีหลักๆ ในการรับบริบทที่ฉายภาพ ซึ่งขึ้นอยู่กับตำแหน่งที่โค้ดของคุณทำงาน

รับบริบทที่ฉายภาพหากโค้ดของคุณทำงานในกิจกรรมของแว่นตา AI

หากโค้ดของแอปทำงานจากภายในกิจกรรมของแว่นตา AI บริบทกิจกรรมของโค้ดเองจะเป็นบริบทที่ฉายภาพอยู่แล้ว ในสถานการณ์นี้ การเรียกใช้ภายในกิจกรรมนั้นจะเข้าถึงฮาร์ดแวร์ของแว่นตาได้อยู่แล้ว

รับบริบทที่ฉายภาพสำหรับโค้ดที่ทำงานในคอมโพเนนต์แอปโทรศัพท์

หากส่วนหนึ่งของแอปที่อยู่นอกกิจกรรมของแว่นตา AI (เช่น กิจกรรมของโทรศัพท์หรือบริการ) ต้องเข้าถึงฮาร์ดแวร์ของแว่นตา ส่วนนั้นจะต้องรับบริบทที่ฉายภาพอย่างชัดเจน โดยใช้เมธอด createProjectedDeviceContext() ดังนี้

@OptIn(ExperimentalProjectedApi::class)
private fun getGlassesContext(context: Context): Context? {
    return try {
        // From a phone Activity or Service, get a context for the AI glasses.
        ProjectedContext.createProjectedDeviceContext(context)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Failed to create projected device context", e)
        null
    }
}

ตรวจสอบความถูกต้อง

ใส่การเรียกใช้ createProjectedDeviceContext ไว้ใน ProjectedContext.isProjectedDeviceConnected ในขณะที่เมธอดนี้แสดงผลเป็น true บริบทที่ฉายภาพจะยังคงถูกต้องสำหรับอุปกรณ์ที่เชื่อมต่ออยู่ และกิจกรรมหรือบริการของแอปโทรศัพท์ (เช่น CameraManager) จะเข้าถึงฮาร์ดแวร์ของแว่นตา AI ได้

ล้างข้อมูลเมื่อตัดการเชื่อมต่อ

บริบทที่ฉายภาพจะเชื่อมโยงกับวงจรการทำงานของอุปกรณ์ที่เชื่อมต่ออยู่ ดังนั้นระบบจะทำลายบริบทที่ฉายภาพเมื่ออุปกรณ์ตัดการเชื่อมต่อ เมื่ออุปกรณ์ตัดการเชื่อมต่อ ProjectedContext.isProjectedDeviceConnected จะแสดงผลเป็น false แอปของคุณควรตรวจสอบการเปลี่ยนแปลงนี้และล้างบริการระบบ (เช่น CameraManager) หรือทรัพยากรที่แอปสร้างขึ้นโดยใช้บริบทที่ฉายภาพนั้น

เริ่มต้นใหม่เมื่อเชื่อมต่ออีกครั้ง

เมื่ออุปกรณ์แว่นตา AI เชื่อมต่ออีกครั้ง แอปของคุณจะรับอินสแตนซ์บริบทที่ฉายภาพอื่นได้โดยใช้ createProjectedDeviceContext() แล้ว เริ่มต้นบริการระบบหรือทรัพยากรใหม่โดยใช้บริบทที่ฉายภาพใหม่

เข้าถึงเสียงโดยใช้บลูทูธ

ปัจจุบัน แว่นตา AI จะเชื่อมต่อกับโทรศัพท์ของคุณเป็นอุปกรณ์เสียงบลูทูธมาตรฐาน ระบบรองรับทั้งโปรไฟล์ชุดหูฟังและโปรไฟล์ A2DP (Advanced Audio Distribution Profile) profiles การใช้แนวทางนี้จะช่วยให้แอป Android ที่รองรับอินพุตหรือเอาต์พุตเสียงทำงานบนแว่นตาได้ แม้ว่าแอปเหล่านั้นจะไม่ได้สร้างขึ้นเพื่อรองรับแว่นตาโดยเฉพาะ ในบางกรณี การใช้บลูทูธอาจเหมาะกับกรณีการใช้งานของแอปมากกว่าการเข้าถึงฮาร์ดแวร์ของแว่นตาโดยใช้บริบทที่ฉายภาพ

เช่นเดียวกับอุปกรณ์เสียงบลูทูธมาตรฐาน สิทธิ์ในการให้สิทธิ์ RECORD_AUDIO จะควบคุมโดยโทรศัพท์ ไม่ใช่แว่นตา

ถ่ายภาพด้วยกล้องของแว่นตา AI

หากต้องการถ่ายภาพด้วยกล้องของแว่นตา AI ให้ตั้งค่าและผูกกรณีการใช้งาน ImageCapture ImageCapture ของ CameraX กับกล้องของแว่นตาโดยใช้บริบทที่ถูกต้องสำหรับแอป

private fun startCameraOnGlasses(activity: ComponentActivity) {
    // 1. Get the CameraProvider using the projected context.
    // When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
    val projectedContext = try {
        ProjectedContext.createProjectedDeviceContext(activity)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "AI Glasses context could not be created", e)
        return
    }

    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 โดยใช้ บริบทอุปกรณ์ที่ฉายภาพ
  • ภายในขอบเขตของบริบทที่ฉายภาพ กล้องหลักของแว่นตา AI ซึ่งหันออกด้านนอกจะแมปกับ DEFAULT_BACK_CAMERA เมื่อเลือกกล้อง
  • การตรวจสอบก่อนการผูกจะใช้ cameraProvider.hasCamera(cameraSelector) เพื่อ ยืนยันว่ากล้องที่เลือกพร้อมใช้งานในอุปกรณ์ก่อนที่จะ ดำเนินการต่อ
  • ใช้ Camera2 Interop กับ Camera2CameraInfo เพื่ออ่าน CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP ที่อยู่เบื้องหลัง ซึ่งอาจมีประโยชน์สำหรับการตรวจสอบขั้นสูงเกี่ยวกับความละเอียดที่รองรับ
  • สร้าง ResolutionSelector ที่กำหนดเองเพื่อควบคุมความละเอียดของรูปภาพเอาต์พุต สำหรับ ImageCapture ได้อย่างแม่นยำ
  • สร้างกรณีการใช้งาน ImageCapture ที่กำหนดค่าด้วย ResolutionSelector ที่กำหนดเอง
  • ผูกกรณีการใช้งาน ImageCapture กับวงจรการทำงานของกิจกรรม ซึ่งจะจัดการการเปิดและปิดกล้องโดยอัตโนมัติตามสถานะของกิจกรรม (เช่น หยุดกล้องเมื่อกิจกรรมหยุดชั่วคราว)

หลังจากตั้งค่ากล้องของแว่นตา AI แล้ว คุณจะถ่ายภาพด้วยคลาส ImageCapture ของ CameraX ได้ โปรดดูเอกสารประกอบของ CameraX เพื่อเรียนรู้ เกี่ยวกับวิธีใช้ takePicture() เพื่อถ่ายภาพ

บันทึกวิดีโอด้วยกล้องของแว่นตา AI

หากต้องการบันทึกวิดีโอแทนที่จะถ่ายภาพด้วยกล้องของแว่นตา AI ให้แทนที่ ImageCapture คอมโพเนนต์ด้วยคอมโพเนนต์ VideoCapture ที่เกี่ยวข้อง และแก้ไขตรรกะการดำเนินการบันทึก

การเปลี่ยนแปลงหลักๆ ได้แก่ การใช้กรณีการใช้งานที่แตกต่างกัน การสร้างไฟล์เอาต์พุตที่แตกต่างกัน และการเริ่มการบันทึกโดยใช้วิธีการบันทึกวิดีโอที่เหมาะสม ดูข้อมูลเพิ่มเติมเกี่ยวกับ API VideoCapture และวิธีใช้ได้ใน เอกสารประกอบการบันทึกวิดีโอของ CameraX

ตารางต่อไปนี้แสดงความละเอียดและอัตราเฟรมที่แนะนำตามกรณีการใช้งานของแอป

กรณีการใช้งาน ความละเอียด อัตราเฟรม
การสื่อสารผ่านวิดีโอ 1280 x 720 15 FPS
คอมพิวเตอร์วิทัศน์ 640 x 480 10 FPS
การสตรีมวิดีโอ AI 640 x 480 1 FPS

เข้าถึงฮาร์ดแวร์ของโทรศัพท์จากกิจกรรมของแว่นตา AI

กิจกรรมของแว่นตา AI ยังเข้าถึงฮาร์ดแวร์ของโทรศัพท์ (เช่น กล้อง หรือไมโครโฟน) ได้ด้วยการใช้ createHostDeviceContext(context) เพื่อรับบริบทของอุปกรณ์โฮสต์ (โทรศัพท์)

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

เมื่อเข้าถึงฮาร์ดแวร์หรือทรัพยากรที่เฉพาะเจาะจงกับอุปกรณ์โฮสต์ (โทรศัพท์) ในแอปแบบไฮบริด (แอปที่มีทั้งประสบการณ์การใช้งานบนอุปกรณ์เคลื่อนที่และแว่นตา AI) คุณต้องเลือกบริบทที่ถูกต้องอย่างชัดเจนเพื่อให้แน่ใจว่าแอปจะเข้าถึงฮาร์ดแวร์ที่ถูกต้องได้

  • ใช้บริบท Activity จาก Activity ของโทรศัพท์หรือ ProjectedContext.createHostDeviceContext() เพื่อรับบริบทของโทรศัพท์
  • อย่าใช้ getApplicationContext() เนื่องจากบริบทของแอปพลิเคชัน อาจแสดงผลบริบทของแว่นตา AI อย่างไม่ถูกต้อง หากกิจกรรมของแว่นตาเป็น คอมโพเนนต์ที่เปิดตัวล่าสุด