Get started with OpenXR for Android XR

Applicable XR devices
This guidance helps you build experiences for these types of XR devices.
XR Headsets
Wired XR Glasses

Before you start building with supported OpenXR extensions or with a supported engine, review the manifest configuration and permission requirements in the following sections to make sure your app is configured for XR development.

Configure your app's manifest file

As with other Android app projects, your Android XR app must have an AndroidManifest.xml file with specific manifest settings. The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play. See the app manifest overview guide for more information.

For XR differentiated apps, your manifest file must contain the following elements and attributes:

PROPERTY_XR_ACTIVITY_START_MODE property

The android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE" property lets the system know that an activity should be launched in a specific mode when the activity is started.

This property has the following values:

  • XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED (OpenXR only)

XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED

Apps built with OpenXR launch in Full Space and must use XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED start mode. Unmanaged Full Space signals to Android XR the app uses OpenXR.


<manifest ... >

   <application ... >
       <property
           android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
           android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED" />
       <activity
           android:name="com.example.myapp.MainActivity" ... >

           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
               <category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
           </intent-filter>
       </activity>
   </application>
</manifest>

The android:name="android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED" property indicates that the application should be launched with a specific type of boundary. Your app needs to specify XR_BOUNDARY_TYPE_LARGE if it's designed to let users move around their physical space. Specifying XR_BOUNDARY_TYPE_NO_RECOMMENDATION provides no recommendations for the type of safety boundary, so the system uses the type that is already in use.

<manifest ... >

   <application ... >
       <property
           android:name="android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED"
           android:value="XR_BOUNDARY_TYPE_LARGE" />
   </application>
</manifest>

Spatial container properties

If your app uses the XR_EXT_spatial_container extension (introduced in Spatial API Level 4) to present content in bounded 3D volumes or 2D panels in addition to full immersive views, you can declare the following manifest properties at the <activity> or <application> level to provide launch hints to the runtime:

  • org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES: Specifies the bounds modes used by the activity, separated by |.

    Valid values are:

    • "2d_panel"
    • "bounded"
    • "immersive"
  • org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE: Specifies the initial bounds mode of the activity when launched.

    Valid values are:

    • XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE_BOUNDED
    • XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE_IMMERSIVE
    • XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE_UNDEFINED
<manifest ... >

   <application ... >
       <activity
           android:name="com.example.myapp.MainActivity" ... >
           <property
               android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES"
               android:value="bounded|immersive" />
           <property
               android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE"
               android:value="XR_SPATIAL_CONTAINER_INITIAL_BOUNDS_MODE_BOUNDED" />
       </activity>
   </application>
</manifest>

<uses-native-library> OpenXR

OpenXR applications must declare the use of the native OpenXR library to successfully load its runtime. Without this declaration, the runtime fails to load.

<manifest ... >

    <application ... >

    <uses-native-library android:name="libopenxr.google.so" android:required="false" />

       <activity
           android:name="com.example.myapp.MainActivity" ... >

           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
        </activity>
    </application>
</manifest>

PackageManager features for XR apps

When you distribute apps through the Google Play Store, you can specify required hardware or software features in the app manifest. The uses-feature element allows the Play Store to appropriately filter apps shown to users.

The following features are specific to XR-differentiated apps.

android.software.xr.api.openxr

Apps that target the Android XR platform and are built with OpenXR or Unity must include this feature in the app manifest with the android:required attribute set to true.

Apps that use the Android XR Extensions Package for Unity version 1.0.0 or higher or the Unity OpenXR: Android XR Package version 0.5.0-exp.1 or higher don't have to add this element manually to the app manifest. These two packages will inject this element into the app manifest for you.

Devices may specify a version for this feature, which indicates the highest version of OpenXR supported by the device. The higher 16 bits represent the major number, and the lower 16 bits represent the minor number. For example, to specify OpenXR version 1.1, the value would be set to "0x00010001".

Apps can use the feature version to indicate a minimum version of OpenXR that the app requires. For example, if your app requires OpenXR version 1.1 support, declare the following feature:

<uses-feature android:name="android.software.xr.api.openxr"
    android:version="0x00010001"
    android:required="true" />

android.software.xr.api.spatial

OpenXR apps that require extensions introduced in a specific Android XR Spatial API version can declare the android.software.xr.api.spatial feature with android:version set to the minimum required Spatial API level (such as "1", "2", "3", or "4"). See Build with supported OpenXR extensions to check the Spatial API version required for each extension.

<!-- Indicates that the app requires Android XR Spatial API Level 4 or higher. -->
<uses-feature android:name="android.software.xr.api.spatial"
    android:version="4"
    android:required="true" />

android.hardware.xr.input.controller

This feature indicates that the app requires input from a high precision, 6DoF (degrees of freedom) motion controller to function correctly. If your app supports controllers and can't function without them, set the value to true. If your app supports controllers but can operate without them, set it to false.

<!-- Sets android:required to true, indicating that your app can't function on devices without controllers. -->
<uses-feature android:name="android.hardware.xr.input.controller" android:required="true" />

android.hardware.xr.input.hand_tracking

This flag indicates that the app requires high fidelity hand tracking to function correctly, including position, orientation, and velocity of joints in the user's hand. If your app supports hand tracking and can't function without it, set the value to true. If your app supports hand tracking, but can operate without it, set it to false.

<!-- Sets android:required to true, indicating that your app can't function on devices without hand tracking. -->
<uses-feature android:name="android.hardware.xr.input.hand_tracking" android:required="true" />

android.hardware.xr.input.eye_tracking

This flag indicates that the app requires high-fidelity eye tracking for input to function correctly. If your app supports eye tracking for input and can't function without it, set the value to true. If your app supports eye tracking for input, but can operate without it, set it to false.

<!-- Sets android:required to true, indicating that your app can't function on devices without eye tracking. -->
<uses-feature android:name="android.hardware.xr.input.eye_tracking" android:required="true" />

android.hardware.xr.input.face_tracking

This flag indicates that the app requires face tracking hardware to function correctly. If your app supports face tracking and can't function without it, set the value to true. If your app supports face tracking, but can operate without it, set it to false.

<!-- Sets android:required to true, indicating that your app can't function on devices without face tracking. -->
<uses-feature android:name="android.hardware.xr.input.face_tracking" android:required="true" />

android.hardware.location.gps

This flag indicates that the app uses precise GPS location on the device, such as when using geospatial OpenXR extensions (XR_ANDROID_geospatial and XR_ANDROID_geospatial_anchor). Set android:required to true if your app can't function without GPS hardware, or false if it can operate without it.

<uses-feature android:name="android.hardware.location.gps" android:required="false" />

Understand permissions for OpenXR

Many OpenXR extensions access privacy-sensitive sensor data and capabilities. To use these extensions, your app must both declare the required <uses-permission> elements in its AndroidManifest.xml file and request dangerous permissions at runtime before calling the corresponding OpenXR functions.

<manifest ... >
    <!-- Example dangerous permissions required by specific OpenXR extensions -->
    <uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />
    <uses-permission android:name="android.permission.HAND_TRACKING" />
    ...
</manifest>

The following table summarizes the dangerous Android permissions required by supported OpenXR extensions on Android XR. For full details on XR permissions across all SDKs, see Understand permissions for XR.

Permission

Capabilities

OpenXR extensions

android.permission.EYE_TRACKING_COARSE

Low-precision eye pose, status, and orientation (such as for avatars).

android.permission.EYE_TRACKING_FINE

High-precision eye gaze for selection, input, interactions, and eye-tracked foveated rendering.

android.permission.FACE_TRACKING

Tracking facial blend shapes and rendering facial expressions.

android.permission.RECORD_AUDIO

Audio input for audio-driven face tracking data sources.

android.permission.HAND_TRACKING

Tracking hand joint poses, velocities, aim state, and hand mesh representation.

android.permission.BODY_TRACKING

Tracking body joint poses and skeleton proportions.

android.permission.SCENE_UNDERSTANDING_COARSE

Plane tracking, object tracking, image/marker/QR code tracking, anchors, persistence, raycasting against trackables, light estimation, and passthrough meshes.

android.permission.SCENE_UNDERSTANDING_FINE

Depth textures, scene meshing, cubemap light estimation, depth raycasting, and spatial annotations.

android.permission.ACCESS_FINE_LOCATION

Precise Earth-relative location and orientation for Geospatial tracking and anchors.

Next steps

Now that you've finished configuring your app's manifest and reviewing important information, explore ways that you can build with OpenXR: