Android录音MediaRecorder.prepare()异常致start()崩溃求助
问题排查与解决办法
1. 存储权限缺失(最可能原因)
官方代码用的getExternalCacheDir()属于应用专属外部存储,不需要额外权限就能读写。但你改用Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)属于公共外部存储,需要对应权限:
- Android 6.0(API 23)到Android 9(API 28):需要在Manifest中声明
WRITE_EXTERNAL_STORAGE,并在运行时动态申请权限。 - Android 10(API 29)及以上:默认启用Scoped Storage,直接写入公共目录子文件夹会失败。你有两种选择:
- 改用MediaStore API来保存文件到公共音乐目录;
- 申请
MANAGE_EXTERNAL_STORAGE权限(但该权限需Google Play审核,仅适用于特殊场景); - 改用应用专属外部存储(比如
getExternalFilesDir(Environment.DIRECTORY_MUSIC)),无需额外权限,路径类似/Android/data/你的包名/files/Music/...。
2. 检查目录创建是否成功
你的代码调用了Dir.mkdirs()但未检查创建结果,若因权限或系统限制导致目录创建失败,后续写入必然出错。修改代码添加检查:
File Dir = new File(TempPath); if (!Dir.exists()){ boolean created = Dir.mkdirs(); if (!created) { Log.e(TAG, "Failed to create directory: " + TempPath); // 终止录制流程,避免后续崩溃 return; } }
3. 优化路径拼接方式
手动拼接路径容易出错,建议用File类构造方法来拼接:
// 替换原路径拼接逻辑 File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); File subDir = new File(musicDir, "Exotel/Media/Audio/Voice Messages/Audio Temp"); File outputFile = new File(subDir, "Exotel_Voice" + System.currentTimeMillis() + ".3gp"); String tempPath = outputFile.getAbsolutePath();
4. 捕获完整异常信息
当前仅打印异常消息,无法定位具体问题,建议打印完整堆栈:
try { recorder.prepare(); } catch (IOException e) { Log.e(TAG, "prepare() failed", e); // 打印完整异常堆栈 }
临时验证方案
若想快速定位问题,可先改用应用专属目录测试:
// 替换路径代码 File appMusicDir = getExternalFilesDir(Environment.DIRECTORY_MUSIC); File subDir = new File(appMusicDir, "Exotel/Media/Audio/Voice Messages/Audio Temp"); if (!subDir.exists()) { subDir.mkdirs(); } String tempPath = new File(subDir, "Exotel_Voice" + System.currentTimeMillis() + ".3gp").getAbsolutePath();
该路径无需额外权限,若能正常运行,说明问题出在公共存储的权限或Scoped Storage限制上。
内容的提问来源于stack exchange,提问作者Ritu
相关产品推荐
相关产品推荐

