You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity构建Oculus时移除AndroidManifest中Wave XR权限方案咨询

Unity跨Vive/Oculus平台构建:移除Vive权限的最佳方案

针对你遇到的Vive权限导致Oculus APK无法上传的问题,以下是几个可自动化、易维护的解决方案:

方案1:自定义Manifest+权限移除标签(最直接)

利用Android Manifest合并工具的tools:node="remove"规则,直接在构建阶段剔除Vive权限:

  • 打开Project Settings -> Player -> Publishing Settings,勾选Custom Main Manifest,Unity会在Assets/Plugins/Android生成自定义Manifest文件
  • 在Manifest根节点添加tools命名空间:
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              package="你的项目包名">
    
  • 列出所有需要移除的Vive权限,每个权限标签添加tools:node="remove"属性:
    <uses-permission android:name="com.htc.vive.permission.RECORD_AUDIO" tools:node="remove" />
    <uses-permission android:name="com.htc.vive.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />
    <!-- 补充其他Vive相关权限 -->
    

构建时,Manifest合并工具会自动移除这些指定权限,无需手动干预。

方案2:Gradle模板批量处理(灵活适配多环境)

通过自定义Gradle模板,在构建流程中动态修改Manifest:

  • 勾选Custom Gradle Template,Unity生成Assets/Plugins/Android/mainTemplate.gradle文件
  • 编辑该文件,在android块中添加Manifest后处理逻辑,批量移除Vive权限:
    android {
        // 保留原有配置...
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                output.processManifest.doLast {
                    def manifestFile = output.processManifest.manifestOutputFile
                    def content = manifestFile.getText('UTF-8')
                    // 正则匹配并移除所有Vive前缀的权限
                    content = content.replaceAll('<uses-permission android:name="com\\.htc\\.vive\\..*?" />', '')
                    manifestFile.write(content, 'UTF-8')
                }
            }
        }
    }
    

该方案无需提前知晓所有权限名称,适合权限列表不固定的场景。

方案3:Editor脚本动态管理插件(最彻底)

通过Unity Editor脚本,在构建前临时禁用Vive插件,从根源避免权限被打包:

  • 创建Editor脚本,实现IPreprocessBuildWithReport和IPostprocessBuildWithReport接口:
    using UnityEditor;
    using UnityEditor.Build;
    using UnityEditor.Build.Reporting;
    using System.IO;
    
    public class PlatformPluginManager : IPreprocessBuildWithReport, IPostprocessBuildWithReport
    {
        public int callbackOrder => 100;
    
        private readonly string vivePluginDir = "Assets/Plugins/Android/ViveWave";
        private readonly string tempDir = "Assets/Plugins/Android/ViveWave_Temp";
    
        public void OnPreprocessBuild(BuildReport report)
        {
            // 判断当前是否为Oculus构建
            bool isOculusBuild = PlayerSettings.GetPlatformXREnabled(BuildTargetGroup.Android, UnityEditor.XR.XRDevice.Oculus);
            if (isOculusBuild && Directory.Exists(vivePluginDir))
            {
                if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true);
                Directory.Move(vivePluginDir, tempDir);
                AssetDatabase.Refresh();
            }
        }
    
        public void OnPostprocessBuild(BuildReport report)
        {
            // 无论构建成功与否,恢复Vive插件
            if (Directory.Exists(tempDir))
            {
                if (Directory.Exists(vivePluginDir)) Directory.Delete(vivePluginDir, true);
                Directory.Move(tempDir, vivePluginDir);
                AssetDatabase.Refresh();
            }
        }
    }
    

该方案彻底隔离Vive插件的Android资源,不会产生任何权限残留,且构建失败后仍能自动恢复文件位置。

方案对比

  • 方案1:操作简单,适合权限列表固定的场景
  • 方案2:无需修改Manifest,批量处理更灵活
  • 方案3:从根源解决问题,适合频繁跨平台构建的项目

内容的提问来源于stack exchange,提问作者Ewan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:15:49