要求並取得必要權限後,應用程式就能存取 AI 眼鏡硬體。如要存取眼鏡的硬體 (而非手機的硬體),請使用投影環境。
視程式碼的執行位置而定,取得預測內容的方式主要有兩種:
如果程式碼是在 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 (藍牙立體聲音訊傳輸規範)設定檔。採用這種做法後,即使 Android 應用程式並非專為眼鏡打造,只要支援音訊輸入或輸出,就能在眼鏡上運作。在某些情況下,使用藍牙可能比透過投影環境存取眼鏡硬體更適合應用程式的用途。
與任何標準藍牙音訊裝置一樣,授予RECORD_AUDIO權限是由手機控管,而非眼鏡。
使用 AI 眼鏡的相機拍攝影像
如要使用 AI 眼鏡的相機拍攝圖片,請設定並繫結 CameraX 的 ImageCapture use case 至眼鏡的相機,並為應用程式使用正確的內容:
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的輸出圖片解析度。 - 建立已設定自訂
ResolutionSelector的ImageCapture用途。 - 將
ImageCapture用例繫結至活動的生命週期。系統會根據活動狀態自動管理攝影機的開啟和關閉 (例如在活動暫停時停止攝影機)。
設定 AI 眼鏡的相機後,即可使用 CameraX 的 ImageCapture 類別擷取圖片。請參閱 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內容或ProjectedContext.createHostDeviceContext()取得手機內容。Activity - 請勿使用
getApplicationContext(),因為如果眼鏡活動是最近啟動的元件,應用程式內容可能會錯誤傳回 AI 眼鏡的內容。