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
相关产品推荐
相关产品推荐

