MAUI Android平台文件删除异常问题求助
MAUI Android 10+ 真机删除SD卡文件失效问题解决方案
问题概述
- 开发的MAUI应用可读取USB读卡器连接的SD卡中CSV格式日志,提取数据写入SQL并备份至云端,需删除SD卡上的日志文件
- 仅Android平台存在异常:模拟器中删除操作正常,但Android 10+(目标SDK31)真机上,代码执行后
File.Exists返回false,提示文件已删除,但SD卡上的文件实际仍存在 - 已在Manifest中配置相关权限,代码中也请求了用户权限,删除逻辑按微软文档编写,无异常抛出;已完成文件读取,将文件移至内部存储(如下载目录)后问题仍存在
已配置的Android权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <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" /> <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
核心删除逻辑代码
var ff1 = System.IO.File.ReadAllLines(csvorig); var csvlen= ff1.Length; if (csvlen < 300) // 每秒一行,少于300行判定为无效数据 { var nl = System.Environment.NewLine; var answ = await DisplayAlert(dbpath + nl + "Small file", "the file you've selected contains no flight" + nl + "prob cause = switching on avionics for < 5min " + nl + " file should be deleted", "DELETE", "ignore"); if (answ) { status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (status == PermissionStatus.Denied) { PermissionStatus status2=awaitPermissions.RequestAsync<Permissions.StorageWrite>(); } // 再次检查权限 status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (status == PermissionStatus.Denied) { await DisplayAlert("warn", "Sorry cannot grant permission \n you will need to delete this file using filemanager \n" + csvorig, "cancel"); return; } try { // 重置文件属性 File.SetAttributes(csvorig, FileAttributes.Normal); File.Delete(csvorig); } catch (Exception ee) { var m = ee.Message; await DisplayAlert("", m, "Cancel"); } if (File.Exists(csvorig)) { await DisplayAlert("warn", "failed to delete", "cancel"); } else { await DisplayAlert(csvorig, "has been deleted", "back"); } } }
解决方案
1. 清理并修正权限配置
- 移除重复的
MANAGE_EXTERNAL_STORAGE权限 - 删除无用/废弃权限:
READ_INTERNAL_STORAGE、WRITE_INTERNAL_STORAGE、MOUNT_UNMOUNT_FILESYSTEMS、MOUNT_FORMAT_FILESYSTEMS,这些权限要么已被Android废弃,要么普通应用无法获取 - 对于Android 10+,
WRITE_EXTERNAL_STORAGE已失效,需依赖MANAGE_EXTERNAL_STORAGE或存储访问框架(SAF)
2. 改用存储访问框架(SAF)执行删除
Android 10+的Scoped Storage限制下,直接通过文件路径操作可能无法真正修改外部存储文件,改用SAF通过文件URI执行删除:
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Q) { // 若通过FilePicker获取文件,优先使用FileResult中的FileUri var fileUri = Android.Net.Uri.Parse(csvorig); var resolver = Android.App.Application.Context.ContentResolver; // 执行删除操作 int rowsDeleted = resolver.Delete(fileUri, null, null); if (rowsDeleted > 0) { await DisplayAlert(csvorig, "已成功删除", "返回"); } else { await DisplayAlert("警告", "删除失败,请检查权限", "取消"); } }
如果是通过MAUI的FilePicker.PickAsync()获取文件,直接使用返回的FileResult.FileUri即可,无需手动转换路径。
3. 确保文件句柄完全释放
虽然ReadAllLines会自动关闭流,但显式使用using块可以确保文件句柄被释放,避免因文件占用导致删除失效:
string[] ff1; using (var stream = new FileStream(csvorig, FileMode.Open, FileAccess.Read)) using (var reader = new StreamReader(stream)) { ff1 = reader.ReadToEnd().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); } var csvlen = ff1.Length;
4. 正确检查MANAGE_EXTERNAL_STORAGE权限
Android 11+需要用户手动开启“访问所有文件”权限,代码中需单独检查并引导用户开启:
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.R) { if (!Android.OS.Environment.IsExternalStorageManager) { var intent = new Android.Content.Intent(Android.OS.Environment.ActionManageAppAllFilesAccessPermission); intent.SetData(Android.Net.Uri.Parse($"package:{Android.App.Application.Context.PackageName}")); intent.AddFlags(Android.Content.ActivityFlags.NewTask); Android.App.Application.Context.StartActivity(intent); await DisplayAlert("提示", "请开启“访问所有文件”权限以完成删除操作", "确定"); return; } }
内容的提问来源于stack exchange,提问作者john murray
相关产品推荐
相关产品推荐

