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

Unity 2021+Android 11多应用共享公共目录文件权限问题求助

解决方案:Android 11下Unity多应用共享公共目录文件/跨应用通信

一、解决当前文件共享权限问题

1. 正确获取公共Download目录路径

不要硬编码SD卡路径,改用Android原生API获取标准公共目录,避免路径适配问题:

private string GetPublicDownloadPath()
{
    if (Application.platform != RuntimePlatform.Android) return "";
    
    using (AndroidJavaClass environmentClass = new AndroidJavaClass("android.os.Environment"))
    {
        using (AndroidJavaObject downloadDir = environmentClass.CallStatic<AndroidJavaObject>(
            "getExternalStoragePublicDirectory", 
            environmentClass.GetStatic<string>("DIRECTORY_DOWNLOADS")))
        {
            return downloadDir.Call<string>("getAbsolutePath");
        }
    }
}

// 替换原GlobalPath定义
private string GlobalPath => Path.Combine(GetPublicDownloadPath(), fileName);

2. 手动申请MANAGE_EXTERNAL_STORAGE权限

Android 11中该权限为特殊权限,无法自动授予,必须引导用户到系统设置页面开启:

// 检查权限是否已授予
public bool HasManageStoragePermission()
{
    if (Application.platform != RuntimePlatform.Android) return true;
    
    using (AndroidJavaClass environmentClass = new AndroidJavaClass("android.os.Environment"))
    {
        return environmentClass.CallStatic<bool>("isExternalStorageManager");
    }
}

// 跳转至系统设置页面开启权限
public void RequestManageStoragePermission()
{
    if (Application.platform != RuntimePlatform.Android) return;
    
    using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    {
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        using (AndroidJavaObject intent = new AndroidJavaObject(
            "android.content.Intent", 
            "android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION"))
        {
            intent.Call<AndroidJavaObject>("setData", 
                new AndroidJavaObject("android.net.Uri", "package:" + currentActivity.Call<string>("getPackageName")));
            currentActivity.Call("startActivity", intent);
        }
    }
}

在Start方法中先做权限检查,未授予则引导用户:

private void Start()
{
    if (!HasManageStoragePermission())
    {
        RequestManageStoragePermission();
        return;
    }
    LoadFromFile();
}

3. 设置文件全局可读可写权限

AppA创建文件后默认仅自身可访问,需手动修改文件权限,让其他应用能读写:
在AddToFile方法写完文件后添加:

// 设置文件为所有用户可读可写
if (Application.platform == RuntimePlatform.Android)
{
    using (AndroidJavaObject file = new AndroidJavaObject("java.io.File", GlobalPath))
    {
        file.Call<bool>("setReadable", true, false); // 参数2为false表示开放给所有用户
        file.Call<bool>("setWritable", true, false);
    }
}

二、无需特殊权限的跨应用信息传输方案

若不想依赖MANAGE_EXTERNAL_STORAGE权限(Google审核可能受限),可选择以下合规方案:

1. FileProvider共享文件

  • 两个应用都在AndroidManifest中配置FileProvider,指定允许共享的目录
  • AppA生成文件后,通过FileProvider生成content://格式的Uri,分享给AppB
  • AppB通过ContentResolver访问该Uri对应的文件
  • 符合Android 11的Scoped Storage规范,无需特殊存储权限

2. 自定义Content Provider

  • AppA实现Content Provider,暴露文件的创建、读取、修改接口
  • 在AndroidManifest中注册Provider并设置android:exported="true"(或配置权限管控访问范围)
  • AppB通过ContentResolver调用Provider接口实现数据交互
  • 适合结构化数据或需要权限控制的场景

3. 共享UserId(仅限同签名应用)

  • 两个应用在AndroidManifest中设置相同的android:sharedUserId="com.your.shared.id"
  • 必须使用同一签名密钥打包
  • 可直接访问对方的私有文件目录,或通过全局SharedPreferences存储小体量数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:31:23