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

Android部分音频加载异常:‘File not found’及加载卡顿问题

问题原因分析

1. 部分文件触发“File not found”提示

  • Scoped Storage 路径兼容问题:Android 10(API 29)及以上采用Scoped Storage机制,通过文件选择器获取的Uri无法直接转换为真实的本地文件路径,直接用File(audioPath).exists()会返回false,触发该提示。
  • 权限缺失:未正确申请或授予存储读取权限(Android 13+需READ_MEDIA_AUDIO,低版本需READ_EXTERNAL_STORAGE),导致应用无法访问目标音频文件。
  • 路径传递错误:从文件选择器获取路径时逻辑出错,传递了无效的路径字符串,导致File对象无法定位到真实文件。

2. 6.5MB MP3加载弹窗持续显示不消失

  • 成功分支未关闭弹窗:原代码中,当loadAudio和loadVisualizer执行成功且无异常时,未调用closeProcessDiaglog(),导致弹窗一直处于显示状态。
  • 耗时操作阻塞主线程:loadAudio和loadVisualizer属于耗时操作(读取音频文件、解析音频数据),直接在主线程执行会阻塞UI线程,不仅弹窗无法关闭,还可能引发ANR(应用无响应)。
  • 异常捕获不完整:如果SoundController内部出现未被Exception覆盖的异常(如某些RuntimeException子类),会导致流程中断,无法触发弹窗关闭逻辑。

解决办法

针对“File not found”问题

  1. 适配Scoped Storage
    避免直接依赖本地文件路径,改用ContentResolver读取音频文件。如果SoundController支持,可直接传递Uri并通过输入流加载:

    // 示例:从文件选择器返回的Uri获取输入流
    InputStream inputStream = getContentResolver().openInputStream(selectedUri);
    // 让SoundController支持通过InputStream加载音频
    mSoundController.loadAudio(inputStream);
    
  2. 确保权限正确配置

    • 在Manifest中添加权限声明:
      <!-- Android 12及以下版本 -->
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      <!-- Android 13+版本 -->
      <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
      
    • 在用户选择文件前,动态申请并确认权限已授予。
  3. 修正文件名截取逻辑
    不要用固定长度截取文件名,改用lastIndexOf('.')处理,避免因文件名含多个点或后缀长度不符导致的后续逻辑错误:

    String s = audioFile.getName();
    int dotIndex = s.lastIndexOf('.');
    mFileName = dotIndex != -1 ? s.substring(0, dotIndex) : s;
    

针对弹窗不消失问题

  1. 补充成功分支的弹窗关闭逻辑
    在try块执行完成后添加弹窗关闭调用:

    try {
        mSoundController.loadAudio(audioFile.getAbsolutePath());
        mSoundController.loadVisualizer(visualizerView, false);
        mSoundController.loadVisualizer(visualizerReverseView, true);
        // 加载成功后关闭弹窗
        closeProcessDiaglog();
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), "Cannot load audio file", Toast.LENGTH_SHORT).show();
        closeProcessDiaglog();
    }
    
  2. 将耗时操作移至子线程
    使用子线程执行加载逻辑,避免阻塞主线程,完成后切换回主线程更新UI:

    showProcessDialog();
    new Thread(() -> {
        try {
            mSoundController.loadAudio(audioFile.getAbsolutePath());
            mSoundController.loadVisualizer(visualizerView, false);
            mSoundController.loadVisualizer(visualizerReverseView, true);
            // 回到主线程关闭弹窗
            runOnUiThread(this::closeProcessDiaglog);
        } catch (Exception e) {
            runOnUiThread(() -> {
                Toast.makeText(getApplicationContext(), "Cannot load audio file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                closeProcessDiaglog();
            });
        }
    }).start();
    
  3. 完善异常捕获范围
    检查SoundController的loadAudio和loadVisualizer方法,确保所有可能的异常都被抛出或内部处理,避免未捕获异常导致流程中断。


内容的提问来源于stack exchange,提问作者DannyRoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:01:05