หลังจากขอและได้รับสิทธิ์ที่จำเป็นแล้ว แอปจะ เข้าถึงฮาร์ดแวร์แว่นตา 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 } }
ตรวจสอบความถูกต้อง
หลังจากสร้างบริบทที่คาดการณ์แล้ว ให้ตรวจสอบ
ProjectedContext.isProjectedDeviceConnected แม้ว่าวิธีนี้จะแสดงผลเป็น
true แต่บริบทที่คาดการณ์ไว้จะยังคงใช้ได้กับอุปกรณ์ที่เชื่อมต่อ และกิจกรรมบนแอปหรือบริการของแอปโทรศัพท์ (เช่น CameraManager) จะเข้าถึงฮาร์ดแวร์ของแว่นตา AI ได้
ล้างข้อมูลเมื่อยกเลิกการเชื่อมต่อ
บริบทที่คาดการณ์จะเชื่อมโยงกับวงจรของอุปกรณ์ที่เชื่อมต่อ ดังนั้นระบบจะทำลายบริบทเมื่ออุปกรณ์ตัดการเชื่อมต่อ เมื่ออุปกรณ์ยกเลิกการเชื่อมต่อ ProjectedContext.isProjectedDeviceConnected จะแสดงผลเป็น false แอปของคุณ
ควรรอรับการเปลี่ยนแปลงนี้และล้างบริการของระบบ (เช่น CameraManager) หรือทรัพยากรที่แอปสร้างขึ้นโดยใช้บริบทที่ฉายนั้น
เริ่มต้นใหม่เมื่อเชื่อมต่ออีกครั้ง
เมื่ออุปกรณ์แว่นตา AI เชื่อมต่ออีกครั้ง แอปจะรับอินสแตนซ์บริบทที่ฉายอีกรายการได้โดยใช้ createProjectedDeviceContext() จากนั้น
เริ่มต้นบริการหรือทรัพยากรของระบบอีกครั้งโดยใช้บริบทที่ฉายใหม่
เข้าถึงเสียงโดยใช้บลูทูธ
ปัจจุบันแว่นตา AI จะเชื่อมต่อกับโทรศัพท์เป็นอุปกรณ์เสียงบลูทูธมาตรฐาน ทั้งชุดหูฟังและโปรไฟล์ A2DP (Advanced Audio Distribution Profile) รองรับการใช้งาน การใช้วิธีนี้จะช่วยให้แอป Android ใดก็ตามที่ รองรับอินพุตหรือเอาต์พุตเสียงทำงานบนแว่นตาได้ แม้ว่าจะไม่ได้สร้างขึ้นเพื่อรองรับแว่นตาโดยเฉพาะก็ตาม ในบางกรณี การใช้บลูทูธอาจเหมาะกับ Use Case ของแอปมากกว่า เพื่อเป็นทางเลือกแทนการเข้าถึงฮาร์ดแวร์ของแว่นตา โดยใช้บริบทที่ฉาย
เช่นเดียวกับอุปกรณ์เสียงบลูทูธมาตรฐานอื่นๆ โทรศัพท์จะเป็นตัวควบคุมสิทธิ์ในการให้สิทธิ์
RECORD_AUDIO ไม่ใช่แว่นตา
ถ่ายภาพด้วยกล้องของแว่นตา AI
หากต้องการบันทึกรูปภาพด้วยกล้องของแว่นตา AI ให้ตั้งค่าและเชื่อมโยงImageCapture Use Case ของ 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 - เชื่อมโยง Use Case
ImageCaptureกับวงจรกิจกรรม ซึ่งจะจัดการการเปิดและปิดกล้องโดยอัตโนมัติตามสถานะของกิจกรรม (เช่น หยุดกล้องเมื่อกิจกรรมหยุดชั่วคราว)
หลังจากตั้งค่ากล้องของแว่นตา AI แล้ว คุณจะถ่ายภาพด้วยคลาส ImageCapture ของ CameraX ได้ โปรดดูเอกสารประกอบของ CameraX เพื่อดูข้อมูล
เกี่ยวกับการใช้ takePicture() เพื่อจับภาพ
บันทึกวิดีโอด้วยกล้องของแว่นตา AI
หากต้องการบันทึกวิดีโอแทนรูปภาพด้วยกล้องของแว่นตา AI ให้แทนที่
คอมโพเนนต์ ImageCapture ด้วยคอมโพเนนต์ VideoCapture ที่เกี่ยวข้อง
และแก้ไขตรรกะการดำเนินการจับภาพ
การเปลี่ยนแปลงหลักๆ ได้แก่ การใช้กรณีการใช้งานอื่น การสร้างไฟล์เอาต์พุตอื่น และการเริ่มการจับภาพโดยใช้วิธีการบันทึกวิดีโอที่เหมาะสม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ VideoCapture API และวิธีใช้ได้ที่
เอกสารประกอบการจับภาพวิดีโอของ 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 อย่างไม่ถูกต้อง หากกิจกรรมบนแว่นตาเป็นคอมโพเนนต์ที่เปิดตัวล่าสุด