如同手機,存取音訊眼鏡和螢幕眼鏡上的相機和麥克風等敏感硬體時,必須獲得使用者的明確同意。這些權限視為眼鏡專屬權限,應用程式必須在執行階段要求這些權限,即使應用程式已在手機上取得相應權限,也必須這麼做。
在應用程式資訊清單中宣告權限
要求權限之前,您必須先使用 <uses-permission> 元素,在應用程式的資訊清單檔案中宣告權限。無論權限是針對手機或眼鏡專屬功能,這項聲明都相同,但您仍須明確要求眼鏡專屬硬體或功能權限。
<manifest ...>
<!-- Only declare permissions that your app actually needs. In this example,
we declare permissions for the camera. -->
<uses-permission android:name="android.permission.CAMERA"/>
<application ...>
...
</application>
</manifest>
要求眼鏡權限前
請詳閱「權限原則和工作流程」,確保您能為使用者提供最佳體驗,例如檢查使用者是否已授予應用程式所需的執行階段權限,以及應用程式是否應先向使用者顯示原因,再要求眼鏡專屬權限。
權限情境
在音訊和顯示型眼鏡上要求危險的執行階段權限時,可能會遇到以下情境:
- 從投影活動要求執行階段權限
- 透過手機活動要求執行階段權限
如要瞭解各個情境的詳細資訊,請參閱本指南的下列章節。
從投影活動要求執行階段權限
如要從投影活動要求音訊或顯示眼鏡的執行階段權限,請使用 ProjectedActivityCompat.requestPermissions 方法。
呼叫這個方法會觸發眼鏡和主機手機的協調使用者流程。
- 在智慧眼鏡上:系統會在智慧眼鏡上開啟投影的隨附活動,指示使用者查看手機,回應權限要求。
- 在手機上:手機螢幕上會顯示 Android 系統權限對話方塊。對話方塊會明確指出使用者是授予眼鏡權限,而非手機本身。使用者可以核准或拒絕要求。
以下範例說明如何從投影活動要求眼鏡權限:
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) private fun requestCameraPermission() { lifecycleScope.launch { try { ProjectedActivityCompat.requestPermissions( this@PermissionsFromProjectedActivity, arrayOf(Manifest.permission.CAMERA), // CAMERA_PERMISSION_REQUEST_CODE is a developer defined constant CAMERA_PERMISSION_REQUEST_CODE, ) } catch (e: IllegalStateException) { // Thrown when the projected system service can't be bound. Log.e(TAG, "Camera permission request failed: projected service unavailable.", e) } } }
程式碼重點
- 請使用
ProjectedActivityCompat.requestPermissions,而非標準的ActivityCompat方法。這個方法明確指定音訊和螢幕眼鏡的執行階段權限,而非主機手機。
處理權限結果
使用者在手機上回應權限對話方塊後,系統會叫用 onRequestPermissionsResult 回呼,將使用者的決定傳送至應用程式。
系統會自動關閉投影的隨附活動。如果是語音眼鏡,則會在音訊快訊播放完畢後啟動。在顯示眼鏡上,使用者回覆所有權限對話方塊後,就會發生這種情況。
如要處理回應,請在啟動權限要求的 Activity 執行個體中覆寫 onRequestPermissionsResult()。
下列程式碼片段說明如何處理回呼,並驗證使用者是否授予要求的權限:
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray, deviceId: Int, ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId) if (requestCode != CAMERA_PERMISSION_REQUEST_CODE) return val isCameraGranted = grantResults.getOrNull(permissions.indexOf(Manifest.permission.CAMERA)) == PackageManager.PERMISSION_GRANTED if (isCameraGranted) { initializeCameraFeatures() } else { onCameraPermissionDenied() } }
程式碼重點
- 使用
deviceId多載與onRequestPermissionsResult回呼,確保權限狀態正確對應至特定情境,例如音訊或顯示眼鏡,而非主機手機。 - 應用程式應妥善處理授權和拒絕結果。
在手機活動中要求執行階段權限
如果應用程式在手機活動中執行,但需要音訊或顯示眼鏡的權限 (例如讓使用者將影片串流切換至眼鏡的攝影機,以第一人稱視角觀看),請使用裝置專屬的 Activity#requestPermissions(permissions, requestCode,
deviceId) 方法要求權限:
// Request the projected permission from phone activity requestPermissions( arrayOf(Manifest.permission.CAMERA), // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant REQUEST_CODE_GLASSES_CAMERA, projectedDeviceId )
程式碼重點
- 如要指定音訊和螢幕眼鏡,請從使用
createProjectedDeviceContext建立的投影環境中取得適當的裝置 ID。呼叫requestPermissions方法時,請一併傳遞這個 ID。
處理權限結果
使用者回應手機上的權限對話方塊後,系統會叫用 onRequestPermissionsResult 回呼,將他們的決定傳送至應用程式。
如要處理回應,請在啟動權限要求的 Activity 執行個體中覆寫 onRequestPermissionsResult。
下列程式碼片段說明如何處理回呼,並驗證使用者是否授予要求的權限:
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray, deviceId: Int, ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId) if (requestCode != CAMERA_PERMISSION_REQUEST_CODE) return val isCameraGranted = grantResults.getOrNull(permissions.indexOf(Manifest.permission.CAMERA)) == PackageManager.PERMISSION_GRANTED if (isCameraGranted) { initializeCameraFeatures() } else { onCameraPermissionDenied() } }
程式碼重點
- 請使用
deviceId超載和onRequestPermissionsResult回呼,確保權限狀態正確對應至特定情境,例如音訊或顯示型眼鏡,而非主機手機。 - 應用程式應妥善處理授權和拒絕結果。