Android中GetExternalStoragePublicDirectory已弃用,如何获取公共外部文档目录?
获取Android公共外部Documents目录(.NET MAUI)
在Android 10(API 29)引入Scoped Storage后,原GetExternalStoragePublicDirectory方法被弃用,而GetExternalFilesDir返回的是应用私有外部存储目录,卸载后数据会被清除,不符合你的需求。以下是两种符合规范的解决方案:
一、官方推荐:使用Storage Access Framework(SAF)
SAF是Android官方推荐的访问公共存储的方式,通过让用户主动选择目录来获得访问权限,适配所有Android版本,且数据不会随应用卸载丢失。
实现步骤:
- 在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; }
- 在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及以上会失效,官方不推荐长期使用:
- 修改
AndroidManifest.xml的application标签:
<application android:requestLegacyExternalStorage="true" ...>
- 继续使用原方法(仅Android 10-12有效):
string dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).AbsolutePath;
总结
- 优先选择Storage Access Framework,符合Android最新存储规范,适配全版本,且数据安全不随应用卸载丢失。
- 过渡方案仅作为临时兼容手段,不建议长期依赖。
内容的提问来源于stack exchange,提问作者Neralem
相关产品推荐
相关产品推荐

