Android - 通过耳机播放音频
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2119060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - Getting audio to play through earpiece
提问by Donal Rafferty
I currently have code that reads a recording in from the devices mic using the AudioRecord class and then playing it back out using the AudioTrack class.
我目前有使用 AudioRecord 类从设备麦克风读取录音的代码,然后使用 AudioTrack 类播放它。
My problem is that when I play it out it plays via the speaker phone.
我的问题是,当我播放它时,它会通过免提电话播放。
I want it to play out via the ear piece on the device.
我希望它通过设备上的耳机播放。
Here is my code:
这是我的代码:
public class LoopProg extends Activity {
boolean isRecording; //currently not used
AudioManager am;
int count = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.setMicrophoneMute(true);
while(count <= 1000000){
Record record = new Record();
record.run();
count ++;
Log.d("COUNT", "Count is : " + count);
}
}
public class Record extends Thread{
static final int bufferSize = 200000;
final short[] buffer = new short[bufferSize];
short[] readBuffer = new short[bufferSize];
public void run() {
isRecording = true;
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int buffersize = AudioRecord.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize);
AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize, AudioTrack.MODE_STREAM);
am.setRouting(AudioManager.MODE_NORMAL,1, AudioManager.STREAM_MUSIC);
int ok = am.getRouting(AudioManager.ROUTE_EARPIECE);
Log.d("ROUTING", "getRouting = " + ok);
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
//am.setSpeakerphoneOn(true);
Log.d("SPEAKERPHONE", "Is speakerphone on? : " + am.isSpeakerphoneOn());
am.setSpeakerphoneOn(false);
Log.d("SPEAKERPHONE", "Is speakerphone on? : " + am.isSpeakerphoneOn());
atrack.setPlaybackRate(11025);
byte[] buffer = new byte[buffersize];
arec.startRecording();
atrack.play();
while(isRecording) {
arec.read(buffer, 0, buffersize);
atrack.write(buffer, 0, buffer.length);
}
arec.stop();
atrack.stop();
isRecording = false;
}
}
}
As you can see if the code I have tried using the AudioManager class and its methods including the deprecated setRouting method and nothing works, the setSpeakerphoneOn method seems to have no effect at all, neither does the routing method.
如您所见,我尝试使用 AudioManager 类及其方法(包括已弃用的 setRouting 方法)的代码是否有效,但 setSpeakerphoneOn 方法似乎根本没有效果,路由方法也没有效果。
Has anyone got any ideas on how to get it to play via the earpiece instead of the spaker phone?
有没有人对如何通过听筒而不是扬声器手机播放它有任何想法?
采纳答案by Piwaf
Just got it to work on 2.2. I still needed the In_Call setup which I don't really like but I'll deal with it for now. I was able to ditch the call routing stuff which is deprecated now. I found you definitely need the Modify_Audio_Settings
permission, no error without it but it the setSpeakerPhone
method just does nothing. Here is the mock up of the code I used.
刚刚让它在2.2上工作。我仍然需要我不太喜欢的 In_Call 设置,但我现在会处理它。我能够放弃现在已弃用的呼叫路由内容。我发现你肯定需要Modify_Audio_Settings
权限,没有它就没有错误,但它的setSpeakerPhone
方法什么都不做。这是我使用的代码的模型。
private AudioManager m_amAudioManager;
m_amAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
m_amAudioManager.setMode(AudioManager.MODE_IN_CALL);
m_amAudioManager.setSpeakerphoneOn(false);
回答by Jo?o Machete
Please use this code, works well:
请使用此代码,效果很好:
//PLAY ON EARPIECE
mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(false);
//PLAY ON SPEAKER
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
回答by Haisea
Misleaded by some answers here for quite a lot of time. I'm using Android 2.2. "audioManager.setSpeakerphoneOn(false);" is working.
被这里的一些答案误导了很长时间。我正在使用 Android 2.2。“audioManager.setSpeakerphoneOn(false);” 正在工作。
audioManager.setSpeakerphoneOn(false);
...
mediaPlayer.setDataSource(..);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mediaPlayer.prepare();
回答by Christopher Orr
There was some related discussion in this recent question:
Android - can I mute currently playing audio applications?
最近这个问题有一些相关的讨论:
Android - 我可以静音当前播放的音频应用程序吗?
Based on the AudioManager
source code, it seems that you must be in "call mode" before the setSpeakerphoneOn
method has any effect.
根据AudioManager
源代码,似乎您必须处于“调用模式”才能使该setSpeakerphoneOn
方法生效。
However, I recently saw an application that could seamlessly switch between earpiece and speakerphone while still showing the current stream as the "media" stream, so I would be interested in any further answers.
但是,我最近看到一个应用程序可以在听筒和免提电话之间无缝切换,同时仍将当前流显示为“媒体”流,因此我对任何进一步的答案感兴趣。
回答by Donal Rafferty
I appear to have got it working on 1.6.
我似乎已经让它在 1.6 上工作了。
So I said I'd post here how I done it.
所以我说我会在这里发布我是如何做到的。
To get it working in 1.6 I:
为了让它在 1.6 中工作,我:
Used the AudioManager
class to set setSpeakerphoneOn(false)
, I then used the Voice_Call_Stream
and add volume control to the Voice_Call_Stream
.
使用AudioManager
类来设置setSpeakerphoneOn(false)
,然后我使用了Voice_Call_Stream
并将音量控制添加到Voice_Call_Stream
.
The setSpeakerphoneOn(false)
method is used in onCreate()
of the activity and this appears to route to the headset, I then used a button and used the setSpeakerphoneOn(true)
method and the audio gets routed to the speaker.
该setSpeakerphoneOn(false)
方法用于onCreate()
活动,这似乎路由到耳机,然后我使用一个按钮并使用该setSpeakerphoneOn(true)
方法,音频被路由到扬声器。
The method only appears to work when it is used in onCreate()
for me and I haven't tested it extensively but for the moment it allows me to switch between headset and speaker on a 1.6 device
该方法仅在onCreate()
对我使用时才有效,我还没有对其进行广泛测试,但目前它允许我在 1.6 设备上的耳机和扬声器之间切换
回答by Achigo
public MediaPlayer m_mpSpeakerPlayer;
private AudioManager m_amAudioManager;
m_amAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// 從Receiver Earpiece發音
m_amAudioManager.setSpeakerphoneOn(false);
m_amAudioManager.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL);
Log.i(TAG, String.valueOf(m_amAudioManager.getRouting(AudioManager.ROUTE_EARPIECE)));
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
// 把聲音設定成從Earpiece出來
// 重點在這行,要把它設定為正在通話中
m_amAudioManager.setMode(AudioManager.MODE_IN_CALL);
// 開始放音樂
m_mpSpeakerPlayer.reset();
m_mpSpeakerPlayer.setDataSource("sdcard/receiver.mp3");
m_mpSpeakerPlayer.prepare();
m_mpSpeakerPlayer.start();
//最後再把它設定從Speaker放音,達成!
m_amAudioManager.setMode(AudioManager.MODE_NORMAL);
回答by Jonas Van der Aa
If the ear piece is connected to the phone with bluetooth (which I assume it is), have you tried calling AudioManager.setBluetoothScoOn(true)
?
如果耳机通过蓝牙连接到手机(我认为是),您是否尝试过拨打电话AudioManager.setBluetoothScoOn(true)
?
I've been through the Android reference and this is the only thing I could find that you didn't mention trying.
我已经阅读了 Android 参考资料,这是我唯一能找到的你没有提到尝试的事情。