Xamarin.Forms Android端Scoped Storage配置及Downloads目录下载实现
问题根因
Android 11(API 30)正式强制启用Scoped Storage机制:当应用targetSdkVersion ≥ 30时,配置的android:requestLegacyExternalStorage="true"参数会被系统直接忽略,即便应用申请了READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE危险权限,也无法通过传统文件路径API直接向公共Downloads目录写入文件;开发者选项中的存储兼容性开关,在应用targetSdk达标后也不会生效,这就是Access Denied错误的核心触发原因。
具体适配调整方案
基础配置优化
- 保留
android:requestLegacyExternalStorage="true"配置即可,该参数仅对Android 10(API29)及以下版本生效,用于兼容低版本设备的传统存储访问逻辑,对Android 11及以上版本无负面影响。 - 调整权限申请逻辑:仅当设备系统版本为Android 10及以下时,才申请存储读写权限、走传统文件写入流程;Android 11及以上版本,往公共Downloads目录写入应用自身创建的文件时,不需要申请任何外置存储读写危险权限,可直接跳过权限申请环节。
核心写入逻辑替换
彻底放弃通过GetExternalStoragePublicDirectory()获取绝对路径、再用File.WriteAllBytes()直接写文件的传统逻辑,对Android 11及以上版本改用MediaStore.Downloads集合接口完成文件写入,适配Xamarin/.NET环境的示例代码:
// Android 11+ 场景下的文件写入实现 var contentValues = new ContentValues(); // 设置保存的文件名 contentValues.Put(MediaStore.IMediaColumns.DisplayName, filename); // 设置文件MIME类型,PDF对应"application/pdf",xlsx对应"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" contentValues.Put(MediaStore.IMediaColumns.MimeType, "application/pdf"); // 指定文件保存到系统Downloads目录 contentValues.Put(MediaStore.Downloads.InterfaceConsts.RelativePath, Environment.DirectoryDownloads); // 向MediaStore插入文件记录,获取可操作的文件Uri var fileUri = ContentResolver.Insert(MediaStore.Downloads.ExternalContentUri, contentValues); // 通过Uri打开输出流,写入文件内容 using(var outputStream = ContentResolver.OpenOutputStream(fileUri)) { await sourceStream.CopyToAsync(outputStream); }
如果要简化代码分支,可对所有Android 10(API29)及以上版本统一走上述MediaStore写入逻辑,不需要额外依赖requestLegacyExternalStorage的兼容配置,适配稳定性更高。
现有业务代码修正
- 调整下载提示逻辑的触发位置:当前代码无论文件写入是否成功、是否抛出异常,都会直接弹出下载成功的提示,需要把成功提示逻辑挪到文件写入完成的分支,异常分支增加错误提示与日志打印。
- 补充异常捕获的日志输出:当前catch块为空,所有异常都会被静默吞掉,建议把异常堆栈打印到日志中,方便定位写入环节的具体问题。
- 不需要申请
MANAGE_EXTERNAL_STORAGE全文件访问权限,走MediaStore写入Downloads目录的逻辑完全不需要这类高风险权限,也不会触发应用商店的审核拦截。
常见踩坑提示
- 不要尝试通过调整开发者选项的存储兼容开关解决Android 11的问题,只要应用targetSdk≥30,该开关对应用不生效。
- 不要依赖SAF文件选择器实现自动保存,MediaStore.Downloads接口不需要用户手动选择路径,即可直接完成文件写入到系统Downloads目录的流程。
内容的提问来源于stack exchange,提问作者Monica
相关产品推荐
相关产品推荐

