.NET MAUI(.NET 8 Android)无法读取旧版本应用数据咨询
原因分析
- Scoped Storage 强制限制:Android 10(API 29)及以上引入的Scoped Storage机制,默认禁止应用直接访问公共外部存储中不属于自身创建的文件。旧Xamarin应用若在公共目录(如根目录、Downloads等)创建文件夹,.NET MAUI(默认遵循Scoped Storage)无权限直接读取这些文件。
- 文件权限与路径映射差异:旧Xamarin应用创建的文件可能设置了私有权限位(如
rw-------),或存储在应用专属外部存储的旧路径下,而.NET MAUI的文件访问API路径映射逻辑与Xamarin不同,导致无法识别。 - 迁移操作权限缺失:启动时将旧文件夹复制/移动到公共Documents目录的操作,若未通过Scoped Storage授权,会导致复制后的文件依然没有正确的访问权限。
解决方法
情况1:旧文件存储在应用专属外部存储
这类目录是Android为每个应用分配的私有外部存储区(如/storage/emulated/0/Android/data/[包名]/files/),同一包名的新旧应用共享此目录,无需额外权限:
- 在.NET MAUI中通过以下方式访问:
var externalFilesDir = Platform.CurrentActivity.GetExternalFilesDir(null); var oldFolderPath = Path.Combine(externalFilesDir.AbsolutePath, "旧文件夹名"); - 若已将旧文件夹复制到公共Documents目录,需通过存储访问框架(SAF) 请求用户授权:
- 触发SAF选择器让用户选择归档文件夹:
var intent = new Intent(Intent.ActionOpenDocumentTree); Platform.CurrentActivity.StartActivityForResult(intent, 1001); - 在
OnActivityResult中获取授权Uri并持久化权限:protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 1001 && resultCode == Result.Ok) { var treeUri = data.Data; Platform.CurrentActivity.ContentResolver.TakePersistableUriPermission( treeUri, Intent.FlagsGrantReadUriPermission | Intent.FlagsGrantWriteUriPermission ); // 后续通过ContentResolver访问文件 } }
- 触发SAF选择器让用户选择归档文件夹:
情况2:旧文件存储在公共外部存储
有两种可选方案:
- 方案A:申请MANAGE_EXTERNAL_STORAGE权限(仅适用于Android 10-12,Android 13+需特殊审核)
- 在
AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - 在代码中请求权限:
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.R) { if (!Environment.IsExternalStorageManager) { var intent = new Intent(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission); intent.SetData(Android.Net.Uri.Parse($"package:{Application.Context.PackageName}")); Platform.CurrentActivity.StartActivity(intent); } }
- 在
- 方案B:使用SAF迁移文件(推荐,符合Android 13+规范)
通过SAF让用户选择旧文件夹,将文件迁移到.NET MAUI的应用专属存储或SAF授权目录,避免依赖特殊权限。
额外注意事项
- 确保新旧应用包名完全一致,否则应用专属存储目录会不同,无法直接访问。
- 复制/移动文件时,使用Android的
ContentResolver或File类需确保权限正确,避免文件复制不完整或权限丢失。
内容的提问来源于stack exchange,提问作者user11500484
相关产品推荐
相关产品推荐

