2010-01-22 261 views
32

我目前使用AudioRecord类从设备麦克风中读取录音,然后使用AudioTrack类将其播放出去。Android - 通过听筒播放音频

我的问题是,当我播放它通过扬声器电话播放。

我希望它通过设备上的耳塞播放。

这里是我的代码:

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; 
     } 
    } 
} 

正如你可以看到,如果代码中,我使用AudioManager类及其方法,包括弃用setRouting方法并没有什么作品试过了,setSpeakerphoneOn方法似乎没有任何效果根本没有路由方法。

有没有人有任何想法如何让它通过耳机而不是spaker手机玩?

回答

27

上耳机和扬声器之间切换工作刚刚在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); 
+0

在设置为IN_CALL之前,您是否需要将音频设置回初始状态?像这样:int currAudioMode = audioManager.getMode(); \t \t \t \t \t \t audioManager.setMode(AudioManager.MODE_IN_CALL); \t \t \t audioManager.setSpeakerphoneOn(actionData.speakerOn); \t \t \t \t \t \t audioManager.setMode(currAudioMode); – Muzikant 2011-06-16 09:04:28

+0

我将其重新设置为MODE_NORMAL以重新打开扬声器电话。因此,上面的代码关闭扬声器并路由到听筒,下面的代码路径可以回到扬声器的默认设置。 'm_amAudioManager.setMode(AudioManager.MODE_NORMAL);' – Piwaf 2011-08-10 15:39:18

+0

它干扰手机的全局设置吗? – 2012-10-31 09:17:20

3

有这个问题,最近一些相关的讨论:基于AudioManager源代码
Android - can I mute currently playing audio applications?

,似乎你必须在“呼叫模式”的setSpeakerphoneOn方法有任何影响了。

但是,我最近看到一个应用程序可以在耳机和扬声器之间无缝切换,同时仍然显示当前流为“媒体”流,所以我会对任何进一步的答案感兴趣。

+1

啊,所以我觉得器件I看到这个工作正在运行1.5。不幸的是,AudioManager API在版本之间似乎经常发生变化。路由和扬声器的东西绝对是一个在1.5和1.6之间变化的区域。这很糟糕。 :( – 2010-01-25 16:42:06

+0

嗨克里斯托弗,我目前使用此代码来做到这一点,它在1.5 audio_service.setSpeakerphoneOn(false); audio_service.setMode(AudioManager.MODE_IN_CALL); audio_service.setRouting(AudioManager.MODE_NORMAL,AudioManager.ROUTE_EARPIECE,AudioManager.ROUTE_ALL ); 但其1.6的打破,我不能找到新的解决办法,我已经尝试设置SpeakerPhoneOn方法为假,但它仍然放在了音箱,我已经试过周围,改变所有流仍然没有运气 – 2010-01-25 16:42:18

+0

是,它似乎从1.6公平上破它是在一分钟相当烦人,大多数新设备使用的版本高于1.5! – 2010-01-25 17:54:57

0

如果耳机连接到蓝牙手机(我认为它是),你有没有试过呼叫AudioManager.setBluetoothScoOn(true)

我已经通过了Android的参考,这是我唯一能找到的,你没有提到尝试。

+1

像他使用蓝牙耳机它不发出声音。听筒内置扬声器您你的耳朵在打电话过程中会受到影响 – 2010-01-23 18:30:15

+0

是的,正如克里斯托弗说的,我正在尝试路线通过设备本身上的耳机的音频,人们可以听到正常的电话呼叫。 我可以使用setRouting方法,它工作在1.5,但我不能找到一个解决音频路由从1.6听筒上 – 2010-01-25 15:58:37

1

我似乎在1.6上工作。

所以我说我会在这里发布我是如何做到的。

为了得到它在1.6的工作我:

使用的AudioManager类设置setSpeakerphoneOn(false),然后我用了Voice_Call_Stream和音量控件添加到Voice_Call_Stream

setSpeakerphoneOn(false)方法是在活性onCreate()使用,这似乎路由到耳机,然后我使用的按钮和所使用的方法setSpeakerphoneOn(true)和音频被路由到扬声器。

的方法,只有当它出现时在onCreate()我被使用和我没有测试它广泛但目前它允许我1.6设备

+0

你可以给一些代码? – pengwang 2010-11-07 06:20:28

1
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); 
+0

Achigo给出的代码工作得很好。您的代码需要在清单文件中设置** android.permission.MODIFY_AUDIO_SETTINGS **权限,因为* setSpeakerPhoneOn()*需要该权限。 – MegaMind 2010-11-23 07:42:36

+0

@MegaMind这个许可准确提供了什么?我注意到,音量修改是可以的,不需要权限。这是真的? – 2016-06-07 10:18:57

3

误导了一些答案在这里相当长的时间。我正在使用Android 2.2。 “audioManager.setSpeakerphoneOn(假);”工作中。

audioManager.setSpeakerphoneOn(false); 
... 
mediaPlayer.setDataSource(..); 
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 
mediaPlayer.prepare(); 
+0

不使用MediaPlayer的 – 2011-02-24 10:24:57

+1

其实你不需要'audioManager.setSpeakerphoneOn(假);'。此外,您还需要创建MediaPlayer,而不是使用静态方法'MediaPlayer.create()',但您需要使用'new MediaPlayer()...'创建它' – Andranik 2014-06-12 18:40:24

3

请使用此代码,效果很好:

//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);