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

.NET MAUI(.NET 8 Android)无法读取旧版本应用数据咨询

原因分析
  1. Scoped Storage 强制限制:Android 10(API 29)及以上引入的Scoped Storage机制,默认禁止应用直接访问公共外部存储中不属于自身创建的文件。旧Xamarin应用若在公共目录(如根目录、Downloads等)创建文件夹,.NET MAUI(默认遵循Scoped Storage)无权限直接读取这些文件。
  2. 文件权限与路径映射差异:旧Xamarin应用创建的文件可能设置了私有权限位(如rw-------),或存储在应用专属外部存储的旧路径下,而.NET MAUI的文件访问API路径映射逻辑与Xamarin不同,导致无法识别。
  3. 迁移操作权限缺失:启动时将旧文件夹复制/移动到公共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) 请求用户授权:
    1. 触发SAF选择器让用户选择归档文件夹:
      var intent = new Intent(Intent.ActionOpenDocumentTree);
      Platform.CurrentActivity.StartActivityForResult(intent, 1001);
      
    2. 在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访问文件
          }
      }
      

情况2:旧文件存储在公共外部存储

有两种可选方案:

  • 方案A:申请MANAGE_EXTERNAL_STORAGE权限(仅适用于Android 10-12,Android 13+需特殊审核)
    1. 在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" />
      
    2. 在代码中请求权限:
      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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:35:13