java - 为什么 SoundPool 不会自动路由到连接的耳机?
问题描述
我正在使用Android SoundPool类来通过我的应用播放 UI 声音。正如预期的那样,通过集成扬声器在安卓设备上进行测试时,声音可以完美播放。但是,当我连接耳机时会出现问题。
当我将有线耳机连接到安卓设备时,声音不会路由到这些耳机。它将通过手机的集成扬声器继续播放。蓝牙耳机的问题仍然存在。
为确保我的耳机和设备正常工作:
- 我确保我的耳机已正确路由到其他应用程序。例如,我通过 Spotify 上的耳机播放音乐,然后返回到我的应用程序,音频切换到通过集成扬声器播放。
- 我在多个 android 设备上进行了测试,结果相同。
我的印象是音频路由将在我的应用程序范围之外自动处理。Android 开发者网站有一个关于处理音频的部分,但是它没有提到任何关于在设备连接时手动路由音频的内容。
SoundPool 实施
这是在名为 SoundManager 的类中设置我的 SoundPool 的相关代码。
我使用了单例实现,这样我就可以从不同的活动中引用这个类,而不必每次都创建一个新实例。
/*
Audio Settings
*/
private final int MAX_STREAMS = 1;
private final int SRC_QUALITY = 1;
private final int STREAM_TYPE = AudioAttributes.USAGE_MEDIA;
/*
Audio Attributes
*/
private final int ATT_USAGE = AudioAttributes.USAGE_GAME;
private final int ATT_FLAG = AudioAttributes.FLAG_AUDIBILITY_ENFORCED;
private final int ATT_CONTENT = AudioAttributes.CONTENT_TYPE_SONIFICATION;
private SoundManager() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(ATT_USAGE)
.setFlags(ATT_FLAG)
.setContentType(ATT_CONTENT)
.build();
soundPlayer = new SoundPool.Builder()
.setMaxStreams(MAX_STREAMS)
.setAudioAttributes(audioAttributes)
.build();
} else {
soundPlayer = new SoundPool(MAX_STREAMS, STREAM_TYPE, SRC_QUALITY);
}
this.audioManager = (AudioManager) appActivity.getSystemService(Context.AUDIO_SERVICE);
appActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
/*
Singleton implementation.
*/
public static synchronized SoundManager get(Context context, AppCompatActivity activity) {
if (soundManager == null) {
soundManager = new SoundManager(context, activity);
}
return soundManager;
}
/* Play A Loaded Clip */
public void play(SoundElement element) {
if (existsInLoadedClips(element)) {
int localId = element.getLocalId();
float volume = getVolume();
soundPlayer.play(localId, volume, volume,
PRIORITY, LOOP, RATE);
}
}
这不是整个类,而是与我的 SoundPool 实例交互的所有部分。
流类型
我认为问题的可能根源是流类型:
private final int STREAM_TYPE = AudioAttributes.USAGE_MEDIA;
private final int ATT_USAGE = AudioAttributes.USAGE_GAME;
但是,无论我使用哪种流类型,问题都仍然存在。
音量控制流
其次,我认为音量控制流与问题有关:
appActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
但是,我也无法通过更改它找到解决方案。
将问题简化为基础
为了消除问题的可能来源,我只使用 SoundPool 对象和准系统 UI设置了一个新项目。
使用以下代码,可以使用任何声音文件重新创建问题:
Button myBtn;
SoundPool soundPlayer;
/*
Audio Settings
*/
private final int MAX_STREAMS = 1;
private final int SRC_QUALITY = 1;
private final int STREAM_TYPE = AudioAttributes.USAGE_GAME;
/*
Audio Attributes
*/
private final int ATT_USAGE = AudioAttributes.USAGE_GAME;
private final int ATT_FLAG = AudioAttributes.FLAG_AUDIBILITY_ENFORCED;
private final int ATT_CONTENT = AudioAttributes.CONTENT_TYPE_SONIFICATION;
/*
Playback Settings
*/
private final int PRIORITY = 1;
private final int LOOP = 0;
private final int RATE = 1;
int clipId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Create Our SoundPool Object */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(ATT_USAGE)
.setFlags(ATT_FLAG)
.setContentType(ATT_CONTENT)
.build();
soundPlayer = new SoundPool.Builder()
.setMaxStreams(MAX_STREAMS)
.setAudioAttributes(audioAttributes)
.build();
} else {
soundPlayer = new SoundPool(MAX_STREAMS, STREAM_TYPE, SRC_QUALITY);
}
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
/*Find Button & Load A Clip */
myBtn = (Button) findViewById(R.id.button);
myBtn.setOnClickListener(new ButtonListener());
this.clipId = loadClip();
}
public int loadClip() {
String fileName = "your_audio_file";
String resourceFolder = "raw";
int resId = this.getResources().getIdentifier(
fileName, resourceFolder, this.getPackageName());
int localId = soundPlayer.load(this, resId, 1);
return localId;
}
private void playSound() {
soundPlayer.play(clipId, 1, 1,
PRIORITY, LOOP, RATE);
}
private class ButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
playSound();
}
}
在这个简单的示例中,当按下按钮并连接耳机时,音频剪辑仍将仅通过我的 android 设备的集成扬声器播放。
我似乎无法找到这个问题的根源。任何帮助将不胜感激。让我知道是否可以提供有关代码或问题的更多详细信息。我试图包含我认为相关的所有内容,但可能需要更多信息。
解决方案
推荐阅读
- react-native - 在 componentDidMount 加载场景需要很长时间
- r - 与先前的值总和
- reactjs - How to apply async react redux middleware
- javascript - 如何创建一个检查图像是否相同并返回结果的函数
- ios - How to get full display name for locale
- node.js - Nodejs Bull queue not connecting to Azure
- coconut - 如何使用柯里化?
- apache-kafka - How to align my consumer to consume 2 depending topics
- python - H2OAutoML 在训练步骤中抛出 libgomp 异常
- c++ - QSpinBox and QDoubleSpinBox do not call method on valueChanged