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:

  1. Pruning XREAL‑specific components from AndroidManifest.xml.

  2. Enabling / disabling the XREAL native plug‑ins by editing their .meta files at build time.


1 Modify 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

  1. Keep xmlns:tools="http://schemas.android.com/tools" on the <manifest> element (required for tools:node="remove").

  2. Add every <intent>, <activity>, <service>, <receiver>, and <provider> line shown above inside your existing <application> tag.

  3. 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:

Step
Action

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

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