Android MediaPlayer替代setAudioStreamType方法失效问题求助
解决Android targetSdk≥27时MediaPlayer听筒播放失效的问题
我来帮你搞定这个问题!这个坑我之前在适配高版本Android的时候也踩过,正好可以给你分享下正确的解决方案。
问题根源
你提到原来用MediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL)能正常走听筒,但升级targetSdk到27后就不行了——这是因为从Android 8.0(API26)开始,这个方法被官方彻底废弃了,系统不再保证它的兼容性。而你改用AudioAttributes后没生效,大概率是Usage类型设置错了,或者漏掉了关键的AudioManager模式配置。
正确的实现步骤
1. 配置正确的AudioAttributes
针对语音通话/听筒播放场景,必须用AudioAttributes.USAGE_VOICE_COMMUNICATION作为Usage类型,而不是你代码里写的USAGE_VOICE...(应该是拼写不全或者写错了)。ContentType设为CONTENT_TYPE_SPEECH是没问题的,这个是对的。
2. 配合AudioManager切换通话模式
很多高版本系统的设备,光设置AudioAttributes还不够,得主动把AudioManager的模式改成MODE_IN_COMMUNICATION,才能强制音频路由到听筒。
完整可运行的代码示例
// 获取系统音频管理实例 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); // 构建正确的AudioAttributes AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) // 核心:这个才是对应听筒的正确Usage .build(); // 初始化MediaPlayer MediaPlayer mediaPlayer = new MediaPlayer(); try { mediaPlayer.setAudioAttributes(audioAttributes); mediaPlayer.setDataSource("你的音频文件路径或者网络URL"); mediaPlayer.prepare(); // 切换到通话模式,确保音频走听筒 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); // 强制关闭扬声器(部分定制ROM可能需要这一步) audioManager.setSpeakerphoneOn(false); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } // 记得在播放完成后恢复AudioManager的正常模式,避免影响其他应用 mediaPlayer.setOnCompletionListener(mp -> { audioManager.setMode(AudioManager.MODE_NORMAL); mp.release(); });
额外要注意的点
- 权限:别忘了在
AndroidManifest.xml里添加修改音频设置的权限,不然可能会报错:<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> - 定制ROM兼容:有些国产定制ROM对音频路由有特殊处理,如果上面的代码还是不行,可以试试在调用
mediaPlayer.start()之前,先调用audioManager.setSpeakerphoneOn(false),再启动播放。 - 彻底抛弃旧方法:别再混用
setAudioStreamType和AudioAttributes了,高版本系统里混用会导致各种奇怪的兼容性问题,完全用新的AudioAttributes配置就好。
内容的提问来源于stack exchange,提问作者José Silva
相关产品推荐
相关产品推荐

