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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:12:14