1. 问题背景:为什么插入耳机后铃声不响了?
最近我在开发一个Android应用时遇到了一个奇怪的问题:来电铃声在插入耳机后突然从耳机播放,而不是像预期那样从扬声器外放。这个问题让我调试了好几个小时,最后发现根源竟然在AudioManager的StreamType选择上。
你可能也遇到过类似情况——明明代码看起来没问题,但音频播放行为就是不符合预期。特别是在使用SoundPool播放短音效时,如果StreamType选择不当,就会出现插入耳机后声音"消失"(其实是从耳机播放了)的尴尬局面。
我最初使用的代码是这样的:
public class IncomeRingUtil {
private SoundPool soundPool;
public void init(Context context) {
if (Build.VERSION.SDK_INT >= 21) {
SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(1);
AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.SREAM_MUSIC);
builder.setAudioAttributes(attrBuilder.build());
soundPool = builder.build();
} else {
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 5);
}
// 加载音频资源
}
}
这段代码在没接耳机的设备上运行得很好,但一旦插入耳机,铃声就跑到耳机里去了,用户很可能因此错过重要来电。
2. AudioManager StreamType完全解析
要理解这个问题,我们首先需要深入了解Android的音频流类型系统。AudioManager提供了多种StreamType,每种类型都有其特定的用途和行为特征。
2.1 主要StreamType类型及其特性
STREAM_MUSIC:这是最常用的音频流类型,用于音乐、游戏音效等多媒体播放。但有个重要特性:当插入耳机时,音频会自动路由到耳机输出。
STREAM_RING:专门用于电话铃声,它的设计初衷就是确保铃声始终从扬声器播放,即使用户插着耳机也不会改变这一行为。
STREAM_ALARM:闹钟音频流,和铃声类似,插入耳机时仍然会从扬声器播放,确保用户不会错过闹钟。
STREAM_NOTIFICATION:通知音效,行为与STREAM_RING类似,保证通知声音能被用户听到。
STREAM_VOICE_CALL:语音通话流,这是唯一可以通过代码动态切换输出设备的流类型,可以使用setSpeakerphoneOn()方法在听筒、扬声器和耳机之间切换。


5326

被折叠的 条评论
为什么被折叠?



