Android 13升级后Unity应用权限弹窗异常问题求助
问题解决:Android 13下Unity应用恢复下载文件夹文件访问权限
问题原因
Android 13(API 33)对存储权限做了拆分,原有的READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限会被系统自动映射为媒体权限(如图片、视频访问权限),这就是你看到权限弹窗变成媒体权限的核心原因。同时requestLegacyExternalStorage属性仅对Android 10/11有效,在Android 13上已失效。
解决方案
1. 修正Manifest配置
移除过时的存储权限,保留并正确配置全存储访问权限:
<?xml version="1.0" encoding="utf-8"?> <!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN--> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools"> <!-- 保留全存储访问权限,添加忽略编译警告属性 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <application> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> </manifest>
2. 正确申请全存储访问权限
MANAGE_EXTERNAL_STORAGE属于特殊权限,无法通过Unity常规权限API申请,需跳转至系统设置让用户手动授权:
using UnityEngine; using Android.Content; public class StoragePermissionHandler : MonoBehaviour { void Start() { CheckManageStoragePermission(); } void CheckManageStoragePermission() { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); var packageManager = currentActivity.Call<AndroidJavaObject>("getPackageManager"); string permission = "android.permission.MANAGE_EXTERNAL_STORAGE"; // 检查权限是否已授予 int status = packageManager.Call<int>("checkPermission", permission, Application.identifier); if (status != 0) // 0代表权限已授予 { // 跳转至应用权限设置页面 Intent intent = new Intent(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission); intent.SetData(Android.Net.Uri.Parse("package:" + Application.identifier)); currentActivity.Call("startActivity", intent); } } } }
3. 合规替代方案:使用存储访问框架(SAF)
如果你的应用不符合Google Play对MANAGE_EXTERNAL_STORAGE权限的审核要求(仅允许文件管理器、备份类应用使用),可以用SAF让用户主动选择下载文件夹,无需特殊权限:
using UnityEngine; using Android.Content; using Android.Net; public class SAFDownloadAccess : MonoBehaviour { private const int REQUEST_PICK_FOLDER = 1001; public void OpenDownloadFolderPicker() { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); // 创建选择文件夹的Intent Intent intent = new Intent(Intent.ActionOpenDocumentTree); // 默认指向下载文件夹(可选) var environment = new AndroidJavaClass("android.os.Environment"); var downloadDir = environment.CallStatic<AndroidJavaObject>("getExternalStoragePublicDirectory", environment.GetStatic<string>("DIRECTORY_DOWNLOADS")); Uri downloadUri = Android.Net.Uri.FromFile(downloadDir); intent.PutExtra("android.provider.extra.INITIAL_URI", downloadUri); currentActivity.Call("startActivityForResult", intent, REQUEST_PICK_FOLDER); } } // 需通过Unity的Android回调处理选择结果,可借助AndroidJavaProxy实现 }
关键注意事项
- Android 13强制推行分区存储,普通应用默认仅能访问自身沙盒和媒体文件,访问公共下载文件夹的非媒体文件必须使用上述两种方案之一。
MANAGE_EXTERNAL_STORAGE权限在Google Play审核中限制严格,若你的应用核心功能不需要全存储访问,优先使用SAF方案避免审核被拒。
内容的提问来源于stack exchange,提问作者PaulineB
相关产品推荐
相关产品推荐

