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

Unity中通过AndroidJavaClass申请Android11+外部存储权限求助

Unity Android 11+ 申请全文件访问权限解决方案

你的代码存在两个核心问题:

  1. ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 是Android 11(API 30)新增的静态常量字段,不是方法,不能用Call<String>调用,必须用GetStatic<String>获取。
  2. 直接用Context的Java类调用startActivity是错误的,必须使用当前活跃的Unity PlayerActivity实例来启动Intent。

以下是完整的解决步骤:

第一步:配置AndroidManifest.xml

在Unity项目的Plugins/Android目录下的AndroidManifest.xml中添加以下配置:

<!-- 申请Android 11+全文件访问权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<!-- 兼容Android 10及以下版本的存储访问逻辑 -->
<application android:requestLegacyExternalStorage="true">
    <!-- 保留原有application标签内的其他配置 -->
</application>

第二步:编写C#权限处理代码

替换你原来的代码,使用以下完整实现:

using UnityEngine;
using UnityEngine.Android;
using System.Collections;

public class StoragePermissionHandler : MonoBehaviour
{
    public UnityEngine.UI.Text myConsole;

    // 调用此方法触发权限申请
    public void RequestStoragePermission()
    {
        if (Application.platform != RuntimePlatform.Android)
            return;

        int androidSDKVersion = GetAndroidSDKVersion();
        // Android 10及以下版本,用Unity原生权限申请
        if (androidSDKVersion < 30)
        {
            if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
            {
                Permission.RequestUserPermission(Permission.ExternalStorageWrite);
            }
            else
            {
                myConsole.text += "已拥有存储权限\n";
            }
            return;
        }

        // Android 11+,先检查是否已有权限
        if (HasManageExternalStoragePermission())
        {
            myConsole.text += "已拥有全文件访问权限\n";
            return;
        }

        // 跳转至系统权限设置页
        try
        {
            AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
            
            AndroidJavaClass settingsClass = new AndroidJavaClass("android.provider.Settings");
            string action = settingsClass.GetStatic<string>("ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION");
            
            AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", action);
            intent.Call<AndroidJavaObject>("setData", AndroidJavaObject.Parse("package:" + Application.identifier));
            
            currentActivity.Call("startActivity", intent);
            StartCoroutine(CheckPermissionAfterUserAction(2f));
        }
        catch (System.Exception e)
        {
            myConsole.text += "权限申请出错:" + e.ToString() + "\n";
        }
    }

    // 检查是否已获取全文件访问权限
    private bool HasManageExternalStoragePermission()
    {
        AndroidJavaClass environmentClass = new AndroidJavaClass("android.os.Environment");
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        
        return environmentClass.CallStatic<bool>("isExternalStorageManager");
    }

    // 获取当前Android系统SDK版本
    private int GetAndroidSDKVersion()
    {
        AndroidJavaClass buildVersionClass = new AndroidJavaClass("android.os.Build$VERSION");
        return buildVersionClass.GetStatic<int>("SDK_INT");
    }

    // 用户操作权限设置后,延迟检查权限状态
    private IEnumerator CheckPermissionAfterUserAction(float delay)
    {
        yield return new WaitForSeconds(delay);
        
        if (HasManageExternalStoragePermission())
        {
            myConsole.text += "用户已授予全文件访问权限\n";
        }
        else
        {
            myConsole.text += "用户拒绝了全文件访问权限\n";
        }
    }
}

代码说明

  • 版本区分:自动适配Android 10及以下、Android 11+的不同权限逻辑
  • 正确的上下文获取:使用UnityPlayer.currentActivity作为启动Intent的上下文,避免空指针或无效调用
  • 权限状态检查:通过Android原生APIisExternalStorageManager()判断权限是否已授予
  • 操作后状态确认:跳转至设置页后延迟检查权限,确保能捕获用户的操作结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:25:19