.NET 7.0 MAUI文件保存后需重启才可见的Android 8.1设备问题
问题
基于.NET 7.0 MAUI开发的应用,在Xiaomi Mi Note 10 Lite(Android 12)、Redmi Note 12(Android 14)设备上测试正常,但在NLS-MT37(Android 8.1)设备上出现异常:文件保存成功无报错,但通过USB连接PC或设备内置文件管理器均无法访问,重启设备后文件才正常可见。调试模式下该文件保存逻辑无错误或警告,已验证撤销存储权限时所有设备都会触发异常。
Android清单配置
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <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_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
简化后的文件保存代码
public async Task SaveData(){ Log.Information("Data save initiated by user."); try{ using (MemoryStream memoryStream = new MemoryStream()) using (StreamWriter writer = new StreamWriter(memoryStream, Encoding.Default)){ writer.WriteLine("header"); foreach (var line in lines) { writer.WriteLine($"write line info"); } writer.Flush(); memoryStream.Seek(0, SeekOrigin.Begin); #if ANDROID string downloadsDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath; var filePath = Path.Combine(downloadsDir, fileName); await File.WriteAllBytesAsync(filePath, memoryStream.ToArray(), cancellationTokenSource.Token); await App.Current.MainPage.DisplayAlert("alert title", "alert success info", "ok"); #endif } }catch(Exception exc) { //log exception and display error message } }
问题核心:该异常是否是旧版Android系统的Bug?问题出在哪里?
分析与解决方案
这个问题不是Android 8.1的Bug,而是媒体扫描器未主动刷新导致的文件可见性延迟。
问题原因
在Android 10(API 29)之前,应用直接写入公共存储目录(比如Downloads)后,系统不会自动触发媒体扫描器更新文件索引。PC通过MTP连接设备、内置文件管理器依赖媒体扫描器的索引来展示文件,所以刚保存的文件不会立即显示,直到设备重启(重启时系统会全量扫描存储)。而Android 12/14系统中,写入公共目录的逻辑已经做了优化,会自动通知媒体扫描器刷新,所以没有这个问题。
另外,代码中使用File.WriteAllBytesAsync直接操作文件,完成后没有通知系统媒体库更新文件的存在,这在旧版Android上就会出现可见性延迟。
解决办法
在Android平台的代码中,文件写入完成后,主动调用媒体扫描器来刷新文件索引,修改后的代码如下:
#if ANDROID string downloadsDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath; var filePath = Path.Combine(downloadsDir, fileName); await File.WriteAllBytesAsync(filePath, memoryStream.ToArray(), cancellationTokenSource.Token); // 新增:通知媒体扫描器刷新文件 var mediaScanIntent = new Android.Content.Intent(Android.Content.Intent.ActionMediaScannerScanFile); var fileUri = Android.Net.Uri.FromFile(new Java.IO.File(filePath)); mediaScanIntent.SetData(fileUri); Android.App.Application.Context.SendBroadcast(mediaScanIntent); await App.Current.MainPage.DisplayAlert("alert title", "alert success info", "ok"); #endif
额外说明
- 对于Android 10及以上,虽然系统会自动处理,但主动发送扫描广播也不会有副作用,兼容性更好。
- 确保已正确动态申请
WRITE_EXTERNAL_STORAGE权限(Android 8.1需要动态申请,不能仅依赖清单声明),你已验证权限撤销会触发异常,说明权限申请逻辑正常,但仍要确保保存文件前已获取到权限。
内容的提问来源于stack exchange,提问作者Aenye_Cerbin
相关产品推荐
相关产品推荐

