Conflict with XREAL
Purpose This page explains how to prevent runtime and build‑time conflicts between XREAL (formerly Nreal) and other Android XR platforms—especially Meta Quest—when building Unity projects. It covers two required tasks:
Pruning XREAL‑specific components from
AndroidManifest.xml
.Enabling / disabling the XREAL native plug‑ins by editing their .meta files at build time.
1 Modify AndroidManifest.xml
AndroidManifest.xml
Goal: Remove XREAL‑specific activities, services, receivers, and providers so that they are not registered in builds targeting other devices.
1.1 Sample Manifest (Meta Quest ± XREAL entries removed)
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<!-- Remove XREAL / Nreal query intent -->
<queries>
<intent tools:node="remove">
<action android:name="ai.nreal.nrsdk.network.type.server" />
</intent>
</queries>
<!-- … (other manifest sections) … -->
<application
android:label="@string/app_name"
android:icon="@mipmap/app_icon"
android:allowBackup="false">
<!-- … (other application sections) … -->
<!-- Remove Nreal activities -->
<activity android:name="ai.nreal.activitylife.NRXRActivity" tools:node="remove" />
<activity android:name="ai.nreal.activitylife.NRShadowActivity" tools:node="remove" />
<activity android:name="ai.nreal.activitylife.UnityPlayerActivity" tools:node="remove" />
<activity android:name="ai.nreal.activitylife.NRFakeActivity" tools:node="remove" />
<!-- Remove Nreal service -->
<service android:name="ai.nreal.sdk.MediaProjectionService" tools:node="remove" />
<!-- Remove XREAL receiver & provider -->
<receiver android:name="com.xreal.glassesdisplayplugevent.receiver.UsbAttachDetachReceiver" tools:node="remove" />
<provider android:name="com.xreal.glassesdisplayplugevent.provider.GlassesInitProvider" tools:node="remove" />
</application>
</manifest>
1.2 Checklist
Keep
xmlns:tools="http://schemas.android.com/tools"
on the<manifest>
element (required fortools:node="remove"
).Add every
<intent>
,<activity>
,<service>
,<receiver>
, and<provider>
line shown above inside your existing<application>
tag.If you maintain separate manifests per target device, apply these removals only in the non‑XREAL variants.
2 Configure XREAL Plug‑in Meta Files & Enable Libraries
2.1 When the XR plug‑in is not initialised
If your app launches but logcat shows “XR plugin not initialised”, run through this checklist before you build:
①
In XR Client Builder set Target Device = XREAL.
②
Open each *.aar.meta
file underLibrary/PackageCache/com.xreal.xr/.../
and confirm the YAML line enabled: 1
.
③
If any file still shows enabled: 0
, choose XRBuildKit ▸ Builder ▸ XR Client Builder → Configure & Build.This menu calls ConfigureXREALSupport(true)
which flips the flags automatically.
**Tip **Re‑run the menu after updating the XREAL package or regenerating
Library/
.
2.2 Goal
Enable the XREAL native plug‑ins only when building an XREAL APK, and disable them for every other Android target (Meta Quest, VIVE XR Elite, etc.). This prevents duplicate loaders or .so
collisions at runtime.
2.3 Editor Utility — XRClientBuilderWindow.cs
XRClientBuilderWindow.cs
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
#region === XREAL Support ===
/// <summary>
/// Toggle XREAL plug‑in *.meta* files between enabled / disabled.
/// </summary>
/// <param name="isXREAL">true → enable XREAL, false → disable.</param>
public static void ConfigureXREALSupport(bool isXREAL)
{
string packagePath = BuildUtility.GetPackagePath("com.xreal.xr");
string androidSettingsDir = Path.Combine(packagePath, "Runtime", "Plugins", "Android");
if (!Directory.Exists(androidSettingsDir))
{
Debug.LogError($"[XRClientBuilderWindow] not found path: {androidSettingsDir}");
return;
}
// Meta files to patch
string[] metaPaths =
{
Path.Combine(androidSettingsDir, "arm64-v8a", "libXREALXRPlugin.so.meta"),
Path.Combine(androidSettingsDir, "Glasses-Display-Plug-Event-2.3.7.aar.meta"),
Path.Combine(androidSettingsDir, "Log-Control-1.2.aar.meta"),
Path.Combine(androidSettingsDir, "nr_common.aar.meta"),
Path.Combine(androidSettingsDir, "nr_loader.aar.meta")
};
foreach (string file in metaPaths)
{
if (!File.Exists(file))
{
Debug.LogWarning($"[XRClientBuilderWindow] File not found: {file}");
continue;
}
string text = File.ReadAllText(file);
string pattern = @"(- first:\s+Android: Android\s+second:\s+enabled: )([01])";
string newValue = isXREAL ? "1" : "0";
string updatedText = Regex.Replace(text, pattern, m => m.Groups[1].Value + newValue, RegexOptions.Multiline);
if (text != updatedText)
{
File.WriteAllText(file, updatedText);
Debug.Log($"[XRClientBuilderWindow] Updated: {file} → enabled: {newValue}");
}
else
{
Debug.Log($"[XRClientBuilderWindow] No change needed: {file}");
}
}
AssetDatabase.Refresh();
}
#endregion
Comments are concise and in English, per code‑style guidelines.
2.4 Usage
// Build for XREAL
await ConfigureXREALSupport(true);
// Build for Meta Quest, VIVE XR Elite, etc.
await ConfigureXREALSupport(false);
Integrate the call as a pre‑build step in your custom pipeline or invoke it manually from XR Client Builder → Configure & Build.
2.5 Notes & Troubleshooting
Duplicate loaders or crashes usually indicate that one or more XREAL activities or services remain in AndroidManifest.xml plus the plug‑ins are still enabled. Double‑check both sections.
Always run
AssetDatabase.Refresh()
(or reopen the project) after patching.meta
files so Unity re‑imports the plug‑ins.If you maintain separate manifests per target, keep the plug‑ins disabled in every non‑XREAL variant to avoid SO collisions on unsupported devices.
For full device‑specific samples, explore Samples~/DeviceSettings/SampleDeviceSettings/Plugins/Android/ inside the XREAL package.
Last updated