使用投影情境存取 AI 眼鏡硬體

適用 XR 裝置
這份指南可協助您為這類 XR 裝置打造體驗。
AI 眼鏡

要求並取得必要權限後,應用程式就能存取 AI 眼鏡硬體。如要存取眼鏡的硬體 (而非手機的硬體),請使用投影環境

視程式碼的執行位置而定,取得預測內容的方式主要有兩種:

如果程式碼是在 AI 眼鏡活動中執行,可以取得預測的內容

如果應用程式的程式碼是從 AI 眼鏡活動中執行,則其活動環境本身就是投影環境。在這種情況下,該活動內發出的呼叫已可存取智慧眼鏡的硬體。

如果程式碼是在手機應用程式元件中執行,請取得預估的內容

如果應用程式的某個部分 (例如手機活動或服務) 位於 AI 眼鏡活動之外,且需要存取眼鏡的硬體,就必須明確取得投影環境。如要這麼做,請使用 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) 可以存取 AI 眼鏡硬體。

中斷連線時清除

投影的內容會繫結至連線裝置的生命週期,因此裝置中斷連線時,投影內容就會遭到刪除。裝置中斷連線時,ProjectedContext.isProjectedDeviceConnected 會傳回 false。應用程式應監聽這項變更,並清除應用程式使用該投影內容建立的任何系統服務 (例如 CameraManager) 或資源。

重新連線時重新初始化

AI 眼鏡裝置重新連線後,應用程式可以使用 createProjectedDeviceContext() 取得另一個投影內容執行個體,然後使用新的投影內容重新初始化任何系統服務或資源。

透過藍牙存取音訊

目前 AI 眼鏡會以標準藍牙音訊裝置的形式連線至手機。支援耳機和 A2DP (藍牙立體聲音訊傳輸規範)設定檔。採用這種做法後,即使 Android 應用程式並非專為眼鏡打造,只要支援音訊輸入或輸出,就能在眼鏡上運作。在某些情況下,使用藍牙可能比透過投影環境存取眼鏡硬體更適合應用程式的用途。

與任何標準藍牙音訊裝置一樣,授予RECORD_AUDIO權限是由手機控制,而非眼鏡。

使用 AI 眼鏡的相機拍攝影像

如要使用 AI 眼鏡的相機拍攝圖片,請設定並繫結 CameraX 的 ImageCapture use case 至眼鏡的相機,並為應用程式使用正確的內容:

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))
}

程式碼重點

設定 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) 取得主機裝置 (手機) 的環境資訊,藉此存取手機的硬體 (例如相機或麥克風):

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

在混合式應用程式 (同時包含行動裝置和 AI 眼鏡體驗的應用程式) 中存取主機裝置 (手機) 專屬的硬體或資源時,您必須明確選取正確的環境,確保應用程式可以存取正確的硬體: