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

Android中GetExternalStoragePublicDirectory已弃用,如何获取公共外部文档目录?

获取Android公共外部Documents目录(.NET MAUI)

在Android 10(API 29)引入Scoped Storage后,原GetExternalStoragePublicDirectory方法被弃用,而GetExternalFilesDir返回的是应用私有外部存储目录,卸载后数据会被清除,不符合你的需求。以下是两种符合规范的解决方案:

一、官方推荐:使用Storage Access Framework(SAF)

SAF是Android官方推荐的访问公共存储的方式,通过让用户主动选择目录来获得访问权限,适配所有Android版本,且数据不会随应用卸载丢失。

实现步骤:

  1. 在Android项目的MainActivity中添加目录选择方法:
public static async Task<Android.Net.Uri?> OpenPublicDocumentsPicker()
{
    // 创建打开目录选择器的Intent
    var intent = new Intent(Intent.ActionOpenDocumentTree);
    intent.PutExtra("android.content.extra.SHOW_ADVANCED", true);
    
    // 指定默认打开公共Documents目录
    var defaultDocumentsUri = Android.Net.Uri.Parse("content://com.android.externalstorage.documents/document/primary%3ADocuments");
    intent.PutExtra(DocumentsContract.ExtraInitialUri, defaultDocumentsUri);
    
    // 启动选择器并等待结果
    var result = await MainActivity.Instance.StartActivityForResultAsync(intent, 1001);
    if (result.ResultCode == Result.Ok)
    {
        // 申请持久化访问权限,避免重启后权限丢失
        var persistFlags = ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission;
        MainActivity.Instance.ContentResolver.TakePersistableUriPermission(result.Data, persistFlags);
        return result.Data;
    }
    return null;
}
  1. 在MAUI共享代码中调用并读写文件:
// 唤起目录选择器,获取公共Documents目录的Uri
var documentsUri = await Android.App.MainActivity.OpenPublicDocumentsPicker();
if (documentsUri != null)
{
    // 写入文件示例:创建并写入test.txt
    var fileUri = DocumentsContract.BuildDocumentUriUsingTree(documentsUri, DocumentsContract.GetTreeDocumentId(documentsUri));
    fileUri = Android.Net.Uri.WithAppendedPath(fileUri, "test.txt");
    
    using var outputStream = Android.App.MainActivity.Instance.ContentResolver.OpenOutputStream(fileUri);
    using var writer = new StreamWriter(outputStream);
    await writer.WriteAsync("保存到公共Documents的内容");

    // 读取文件示例
    using var inputStream = Android.App.MainActivity.Instance.ContentResolver.OpenInputStream(fileUri);
    using var reader = new StreamReader(inputStream);
    var content = await reader.ReadToEndAsync();
}

二、过渡方案:使用Legacy外部存储(仅Android 10-12)

如果需要快速兼容旧逻辑,可在AndroidManifest.xml中启用遗留存储访问,但此方案在Android 13及以上会失效,官方不推荐长期使用:

  1. 修改AndroidManifest.xml的application标签:
<application android:requestLegacyExternalStorage="true" ...>
  1. 继续使用原方法(仅Android 10-12有效):
string dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).AbsolutePath;

总结

  • 优先选择Storage Access Framework,符合Android最新存储规范,适配全版本,且数据安全不随应用卸载丢失。
  • 过渡方案仅作为临时兼容手段,不建议长期依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:39:37