Unity开发Android游戏如何申请文件系统操作权限?
解决Unity安卓游戏文件操作权限失效问题
核心问题分析
你只申请了ExternalStorageRead权限,但文件创建/编辑需要读写权限同时授权;另外安卓10(API 29)及以上的Scoped Storage机制,以及安卓13+的权限拆分规则,都会导致传统权限申请逻辑失效。
解决方案分步实施
1. 修正权限申请代码,同时申请读写权限
单独申请读权限不足以支持写操作,需要同时申请读写,并监听权限回调:
using UnityEngine; using System.IO; public class FilePermissionManager : MonoBehaviour { void Start() { CheckAndRequestPermissions(); } void CheckAndRequestPermissions() { bool hasReadPerm = UnityEngine.Android.Permission.HasUserPermission(UnityEngine.Android.Permission.ExternalStorageRead); bool hasWritePerm = UnityEngine.Android.Permission.HasUserPermission(UnityEngine.Android.Permission.ExternalStorageWrite); if (!hasReadPerm || !hasWritePerm) { // 批量申请读写权限 UnityEngine.Android.Permission.RequestUserPermissions(new string[] { UnityEngine.Android.Permission.ExternalStorageRead, UnityEngine.Android.Permission.ExternalStorageWrite }); } else { // 权限已就绪,执行文件操作 ExecuteFileOperations(); } } // 监听权限申请后的焦点变化,重新检查权限 private void OnApplicationFocus(bool hasFocus) { if (hasFocus) { CheckAndRequestPermissions(); } } void ExecuteFileOperations() { // 示例:创建文件夹和文件 string targetDir = Path.Combine(Application.externalStoragePath, "MyGameFiles"); Directory.CreateDirectory(targetDir); string targetFile = Path.Combine(targetDir, "test.txt"); File.WriteAllText(targetFile, "测试内容"); Debug.Log("文件操作完成:" + targetFile); } }
2. 配置AndroidManifest.xml权限声明
在Assets/Plugins/Android目录下创建/修改AndroidManifest.xml,确保权限和适配项正确:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.YourCompany.YourGame"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 安卓10(API29)适配:绕过Scoped Storage临时兼容 --> <application android:requestLegacyExternalStorage="true"> <!-- 保留Unity自动生成的其他application配置 --> </application> </manifest>
3. 安卓11+(API30)及以上的特殊权限处理
安卓11开始强制Scoped Storage,若需访问任意外部文件,需申请MANAGE_EXTERNAL_STORAGE权限(该权限需用户手动在系统设置开启):
void CheckManageStoragePermission() { if (Application.platform == RuntimePlatform.Android && UnityEngine.Android.AndroidSDKVersion >= 30) { string managePerm = "android.permission.MANAGE_EXTERNAL_STORAGE"; if (!UnityEngine.Android.Permission.HasUserPermission(managePerm)) { // 申请权限,或直接跳转至应用设置页让用户手动开启 UnityEngine.Android.Permission.RequestUserPermission(managePerm); Application.OpenURL($"package:{Application.identifier}/settings"); } } }
4. 推荐:使用应用私有存储(无需权限)
如果不需要让用户在外部访问文件,优先使用Application.persistentDataPath,这是应用私有目录,无需申请任何权限:
string privateDir = Path.Combine(Application.persistentDataPath, "PrivateFiles"); Directory.CreateDirectory(privateDir); string privateFile = Path.Combine(privateDir, "private_test.txt"); File.WriteAllText(privateFile, "私有存储内容");
排查要点
- 检查测试设备是否拦截了权限弹窗(部分厂商的安全软件会默认拦截)。
- 确认Unity Player Settings中的安卓API等级(Minimum/Target API Level)与测试设备系统版本匹配。
- 安卓13+操作媒体文件时,需替换为
READ_MEDIA_IMAGES/READ_MEDIA_AUDIO等细分权限,而非传统外部存储权限。
内容的提问来源于stack exchange,提问作者Voyduzzz
相关产品推荐
相关产品推荐

