8.8 KiB
Applicable XR devices This guidance helps you build experiences for these types of XR devices. Learn about XR device types → Audio &
Display Glasses Learn about XR device types →
Just like on a phone, accessing sensitive hardware like the camera and microphone on audio glasses and display glasses requires explicit user consent. These are considered glasses-specific permissions, and your app must request them at runtime, even if it already has the corresponding permissions on the phone.
Declare the permissions in your app's manifest
Before requesting permissions, you must declare them in your app's manifest
file using the <uses-permission> element. This declaration remains the
same whether the permission is for a phone or a glasses-specific feature, but
you must still explicitly request it for glasses-specific hardware or
functionality.
<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>
Register the permissions launcher
To request permissions for audio glasses and display glasses, first you use the
ActivityResultLauncher with the ProjectedPermissionsResultContract
method to register the permissions launcher.
// Register the permissions launcher using the ProjectedPermissionsResultContract.
private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> =
registerForActivityResult(ProjectedPermissionsResultContract()) { results ->
if (results[Manifest.permission.CAMERA] == true) {
isPermissionDenied = false
initializeGlassesFeatures()
} else {
// Handle permission denial.
isPermissionDenied = true
}
}
Key points about the code
- The code creates an
ActivityResultLauncherusing theProjectedPermissionsResultContractmethod. The callback receives a map of permission names to their granted status. - You need to specify which permissions your app requires, such as
Manifest.permission.CAMERAorManifest.permission.RECORD_AUDIO.
Create the request function
Next, you'll create a function that uses your app's permissions launcher to request the permissions from the user at runtime.
private fun requestHardwarePermissions() {
val params = ProjectedPermissionsRequestParams(
permissions = listOf(Manifest.permission.CAMERA),
rationale = "Camera access is required to overlay digital content on your physical environment."
)
requestPermissionLauncher.launch(listOf(params))
}
Key points about the code
- The
requestHardwarePermissionsfunction builds aProjectedPermissionsRequestParamsobject. This object bundles the list of permissions your app needs and the user-facing rationale. Make the rationale clear and concise to explain why your app needs these permissions. - Calling
launchon the launcher triggers the permission request user flow. - Your app should handle both granted and denied results gracefully in the launcher's callback.
Create the permissions check function
Next, you'll create a function that can check whether the user has granted permissions to your app.
private fun hasCameraPermission(): Boolean {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED
}
Add the permission request logic
And lastly, create the logic that uses these functions to check for and request the permissions at runtime.
if (hasCameraPermission()) {
initializeGlassesFeatures()
} else {
requestHardwarePermissions()
}
Key points about the code
- If the user has already granted your app the required permissions, the
initializeGlassesFeaturesfunction is called to initialize your app's experience. This function is defined as part of your app's activity for AI glasses.
Understand the permission request user flow
When you launch a permission request using the
ProjectedPermissionsResultContract method, the system initiates a
coordinated user flow across both the glasses and the phone.
Important
Important: You should call the
ProjectedPermissionsResultContractmethod from anActivitydisplayed on the glasses. Don't use the standard Android permission APIs (such asrequestPermissionswithActivityResultLauncher<String>) in code running on the glasses. Doing so attempts to launch a non-interactable permission dialog on the glasses, breaking the user flow.
If your app already has an
Activitydisplayed on the phone, you should useActivity#requestPermissions(permissions, requestCode, deviceId), where thedeviceIdcomes from calling thegetDeviceIdmethod on theContextreturned by callingProjectedContext.createProjectedDeviceContext.
During the permissions user flow, here is what your app and the user can expect:
-
On the glasses : An activity appears on the projected device (glasses), instructing the user to look at their phone to continue.
Warning
Preview: Currently, the instructions and rationale provided by the system are not audible to the user. To provide an audible rationale to the user, we recommend using Text to Speech (TTS). For example:
tts?.speak("Please review the permission request on your host device", TextToSpeech.QUEUE_ADD, null, "permission_request")
-
On the phone : Concurrently, an activity launches on the host device (phone). This screen displays the rationale string you provided and gives the user the option to proceed or cancel.
-
On the phone : If the user accepts the rationale, a modified Android system permission dialog appears on the phone telling the user that they are granting the permission for the glasses (not the phone), and the user can formally grant or deny the permission.
-
Receiving the result : After the user makes their final choice, the activities on both the phone and glasses are dismissed. Your
ActivityResultLaunchercallback is then invoked with a map containing the granted status for each requested permission.