Projected Hardware
Android (Google)OfficialCreated by Google LLCDistributed by Android (Google)
- Skill
- Tool integration
- Software development
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides the necessary patterns for Android developers to interact with hardware components on connected XR devices, such as audio and display glasses. It focuses on the use of ProjectedContext to manage device lifecycles, handle hardware-specific permissions, and ensure stable connections between the host phone and the wearable hardware.
What it does
- Explains how to obtain and use a ProjectedContext for hardware access.
- Provides patterns for monitoring connection states between the host phone and XR glasses.
- Outlines the requirements for declaring and requesting runtime permissions for glasses hardware.
- Details how to manage resource lifecycles based on device availability and connection status.
- Offers guidance on integrating with system services like CameraManager for glasses-specific hardware.
When to use it
- When developing Android applications that need to access cameras or microphones on connected XR eyewear.
- When you need to implement robust connection monitoring to handle device disconnects or removal.
- When you need to manage runtime permissions specifically for projected XR hardware.
- When your app needs to distinguish between phone-based hardware and connected glasses-based hardware.
Advantages
- Ensures stable hardware interaction by leveraging the official ProjectedContext lifecycle management.
- Provides clear patterns for handling the dynamic nature of wearable device connectivity.
- Helps developers correctly implement Android runtime permissions for XR-specific hardware.
Usage examples
- “How do I access the camera on connected audio glasses in my Android app?”
- The skill provides the implementation pattern using ProjectedContext to initialize system services like CameraManager specifically for the connected glasses.
- “How can I tell if the user is currently wearing their display glasses?”
- The skill explains how to use the XR Device Availability API to monitor Lifecycle.State and determine if the device is active, inactive, or disconnected.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/android/projected-hardware/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip projected-hardware.zip -d .agents/skills
Documentation by Google LLC
Prerequisites
You must use a
compileSdkof 36 or higher.
Connection and lifecycle management
Intelligent eyewear hardware is only accessible while the glasses are connected
to the host phone. Monitor connection state and manage resource lifecycles using
ProjectedContext. You must read
Understand projected activities and projected contexts to understand
how to get a projected context and how to manage its lifecycle.
Request glasses hardware permissions
Hardware permissions and opt-in : You must read Request hardware permissions to understand how to declare camera and microphone runtime permissions in the Android Manifest file, request runtime permissions in different scenarios, and handle permission results.
Glasses hardware access and capabilities
Camera capture and CameraX : You must read Capture an image with the glasses' camera to understand the implementation patterns for capturing a photo with the glasses' camera using a
ProjectedContext.
Files
- ATTRIBUTION.mdAdded by AutoGineer957 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md2.0 KiB
- references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md25.9 KiB
- references/android/develop/xr/jetpack-xr-sdk/glasses/check-availability.md4.7 KiB
- references/android/develop/xr/jetpack-xr-sdk/glasses/support-different-types.md8.3 KiB
- references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md9.1 KiB
references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md
<br />
Applicable XR devices This guidance helps you build experiences for these types of XR devices. Learn about XR device types → Image: untitled Audio &
Display Glasses Learn about XR device types →
<br />
Just like on a phone, accessing sensitive hardware like the camera 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>Before requesting glasses permissions
Review the permission principles and workflows to make sure you provide the best experience for your users, like checking whether the user has already granted the runtime permissions your app requires and whether your app should show a rationale to the user before requesting glasses-specific permissions.
Permission scenarios
There are different scenarios you might encounter when requesting dangerous runtime permissions on audio and display glasses:
Request runtime permissions from a projected activity
Request runtime permissions from a phone activity
See the following sections in this guide for details about each scenario.
Request runtime permissions from a projected activity
To request runtime permissions for audio or display glasses from a projected
activity, use the ProjectedActivityCompat.requestPermissions method.
Calling this method triggers a coordinated user flow across both the glasses and the host phone.
On the glasses: The system opens a projected companion activity on the glasses, instructing the user to check their phone to respond to the permission request.
On the phone: An Android system permission dialog appears on the phone screen. The dialog explicitly indicates that the user is granting the permission for the glasses rather than the phone itself. The user can then grant or deny the request.
The following example shows how to request glasses permissions from a projected activity:
@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)
}
}
}<br />
Key points about the code
Use
ProjectedActivityCompat.requestPermissionsinstead of the standardActivityCompatmethod. This method explicitly targets the runtime permissions for audio and display glasses rather than the host phone.
Handle the permission results
Once the user responds to the permission dialog on the phone, their decision is
delivered to your app by invoking the onRequestPermissionsResult
callback.
The system closes the projected companion activity automatically. On audio glasses, this occurs after the audio alert finishes playing. On display glasses, it happens after the user responds to all the permission dialogs.
To handle the response, override onRequestPermissionsResult() within the
Activity instance that initiated the permission request.
The following code snippet shows how to handle the callback and verify whether the user granted the requested permissions:
@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()
}
}<br />
Key points about the code
Use the
deviceIdoverload with theonRequestPermissionsResultcallback to ensure the permission status is correctly mapped to the specific context, such as the audio or display glasses rather than the host phone.Your app should handle both granted and denied results gracefully.
Request runtime permissions in a phone activity
If your app is running in a phone activity but requires permissions for audio or
display glasses---for example, to let a user switch a video stream to the glasses'
camera for a first-person point of view---request the permissions using the
device-specific Activity#requestPermissions(permissions, requestCode, deviceId) method:
// 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
)<br />
Key points about the code
To target audio and display glasses, obtain the appropriate device ID from a projected context that you've created using
createProjectedDeviceContext. Pass this ID with your call to therequestPermissionsmethod.
Handle the permission results
Once the user responds to the permission dialog on the phone, their decision is
delivered to your app by invoking the onRequestPermissionsResult
callback.
To handle the response, override onRequestPermissionsResult within the
Activity instance that initiated the permission request.
The following code snippet shows how to handle the callback and verify whether the user granted the requested permissions:
@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()
}
}<br />
Key points about the code
Use the
deviceIdoverload with theonRequestPermissionsResultcallback to ensure the permission status is correctly mapped to the specific context, such as the audio or display glasses rather than the host phone.Your app should handle both granted and denied results gracefully.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Google LLC
- Publisher
- Android (Google) (Official)
- Distributed by
- Android (Google)
- Source
- android/skills · xr/projected-hardware · commit bf68e2d
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.txt)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Google LLC or Android (Google).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download projected-hardware.zip