2010-01-22 80 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);