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

Android端MAUI.Audio播放外部存储音频遇System.IO.FileNotFoundException

解决Android平台MAUI.Audio播放外部存储音频的FileNotFoundException问题

1. 错误核心:用错了文件读取API

你当前调用的FileSystem.OpenAppPackageFileAsync是专门读取应用包内置资源的API,完全不适合访问外部存储文件,这就是传外部路径会报找不到文件的根本原因。

2. 正确解决步骤

步骤1:补全权限配置(适配不同Android版本)

你已有的权限配置对Android 12及以下有效,但Android 13+读取音频需要READ_MEDIA_AUDIO权限,在AndroidManifest.xml里补充:

<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:maxSdkVersion="33" />

保留原有配置:

<application... android:requestLegacyExternalStorage="true" .../>   
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

步骤2:主动请求运行时权限

MAUI不会自动申请权限,播放前必须检查并请求:

using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.ApplicationModel.Permissions;

private async Task<bool> CheckAndRequestPermissions()
{
    PermissionStatus status;
    if (DeviceInfo.Platform == DevicePlatform.Android)
    {
        // 根据Android版本选择对应权限
        if (DeviceInfo.Version.Major >= 13)
        {
            status = await Permissions.CheckStatusAsync<Permissions.Media>();
        }
        else
        {
            status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
        }

        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync(DeviceInfo.Version.Major >=13 ? typeof(Permissions.Media) : typeof(Permissions.StorageRead));
            if (status != PermissionStatus.Granted)
            {
                // 权限被拒,可在此给用户弹提示
                return false;
            }
        }
    }
    return true;
}

步骤3:用正确方式读取外部存储文件

直接用File.OpenRead获取外部文件流,再创建播放器:

public IAudioPlayer? audioPlayer;
public async void PlaySong()
{
    // 先确认权限已获取
    bool hasPermission = await CheckAndRequestPermissions();
    if (!hasPermission) return;

    string audioPath = "/storage/emulated/0/Music/mymusic.mp3";
    // 先判断文件是否存在
    if (!File.Exists(audioPath))
    {
        // 文件不存在,提示用户检查路径
        return;
    }

    if (audioPlayer == null)
    {
        using var audioStream = File.OpenRead(audioPath);
        audioPlayer = AudioManager.Current.CreatePlayer(audioStream);
        audioPlayer.Play();
    }
}

3. 额外提醒

  • 避免硬编码路径:/storage/emulated/0/不是所有Android设备的通用外部存储路径,建议用媒体库API获取音乐文件路径,减少适配问题。
  • 及时释放资源:播放器不再使用时,调用audioPlayer.Dispose()释放资源,防止内存泄漏。
  • Android 12+适配:requestLegacyExternalStorage在Android 12及以上失效,若要兼容更高版本,建议使用Scoped Storage或MediaStore API访问文件。

内容的提问来源于stack exchange,提问作者Никита Черепанов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:11:03