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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:50:05