在 Android 中将耳机插入耳机插孔时通过内置扬声器播放音频
Audio through built-in speakers when earphones are plugged in headphone jack in Android
在我的应用程序中,有一张卡 Reader 使用 devices.Now 的音频插孔,我的问题是当卡 Reader 是时,我想从内置扬声器发出声音在设备的耳机插孔中完好无损。
以下是我试过的代码:
1) 使用反射方法
Class audioSystemClass;
try {
audioSystemClass = Class
.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod(
"setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
// back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
final float maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
} catch (ClassNotFoundException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (NoSuchMethodException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (IllegalArgumentException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (InvocationTargetException e) {
Log.e("Test", e.toString());
e.printStackTrace();
}
2) 使用 setMode 方法
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.setSpeakerphoneOn(true);
float maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_RING);
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
但这两个代码仅在那些具有默认 FM 应用程序的设备中是 运行。 但我希望在所有设备中都具有此功能。
请分享您的经验!!
您的第二种方法 setMode 适用于带有默认 Fm 播放器的手机。
但是对于没有默认 FM 的设备,我尝试了以下代码:
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(true);
此代码适用于没有默认 Fm 的手机 player.I 使用带有 Oxygen OS 的 OnePlus 设备并且运行良好。希望这有帮助。
或者,如果您将 SoundPool 初始化为 STREAM_VOICE_CALL,如:
SoundPool spool = new SoundPool(1,AudioManager.STREAM_VOICE_CALL, 0)
那么你的音频也应该通过你上面提到的任何方式路由到扬声器。我试过了,即使没有默认的 FM,它也能在手机上工作。
在这里,我启动了一个 SoundPool 并加载了一个蜂鸣声。
SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_VOICE_CALL, 0);
soundPool
.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool,
int sampleId, int status) {
loaded = true;
}
});
soundID = soundPool.load(ApplicationChexology.getContext(), R.raw.beep_single, 1);
现在,加载声音后,我将 AudioManager 设置为 MODE_IN_COMMUNICATION 并播放声音。播放声音后,将音频管理器的模式设置为 MODE_NORMAL。
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);
float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
if (loaded)
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
Timer timer = new Timer();
TimerTask delayedThreadStartTask = new TimerTask() {
@Override
public void run() {
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}};
timer.schedule(delayedThreadStartTask, 500);
在我的应用程序中,有一张卡 Reader 使用 devices.Now 的音频插孔,我的问题是当卡 Reader 是时,我想从内置扬声器发出声音在设备的耳机插孔中完好无损。
以下是我试过的代码:
1) 使用反射方法
Class audioSystemClass;
try {
audioSystemClass = Class
.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod(
"setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
// back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
final float maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
} catch (ClassNotFoundException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (NoSuchMethodException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (IllegalArgumentException e) {
Log.e("Test", e.toString());
e.printStackTrace();
} catch (InvocationTargetException e) {
Log.e("Test", e.toString());
e.printStackTrace();
}
2) 使用 setMode 方法
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.setSpeakerphoneOn(true);
float maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_RING);
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
但这两个代码仅在那些具有默认 FM 应用程序的设备中是 运行。 但我希望在所有设备中都具有此功能。
请分享您的经验!!
您的第二种方法 setMode 适用于带有默认 Fm 播放器的手机。
但是对于没有默认 FM 的设备,我尝试了以下代码:
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(true);
此代码适用于没有默认 Fm 的手机 player.I 使用带有 Oxygen OS 的 OnePlus 设备并且运行良好。希望这有帮助。
或者,如果您将 SoundPool 初始化为 STREAM_VOICE_CALL,如:
SoundPool spool = new SoundPool(1,AudioManager.STREAM_VOICE_CALL, 0)
那么你的音频也应该通过你上面提到的任何方式路由到扬声器。我试过了,即使没有默认的 FM,它也能在手机上工作。
在这里,我启动了一个 SoundPool 并加载了一个蜂鸣声。
SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_VOICE_CALL, 0);
soundPool
.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool,
int sampleId, int status) {
loaded = true;
}
});
soundID = soundPool.load(ApplicationChexology.getContext(), R.raw.beep_single, 1);
现在,加载声音后,我将 AudioManager 设置为 MODE_IN_COMMUNICATION 并播放声音。播放声音后,将音频管理器的模式设置为 MODE_NORMAL。
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);
float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
if (loaded)
soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
Timer timer = new Timer();
TimerTask delayedThreadStartTask = new TimerTask() {
@Override
public void run() {
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}};
timer.schedule(delayedThreadStartTask, 500);