2010-01-22 9 views
32

Actualmente tengo un código que lee una grabación desde el micrófono del dispositivo utilizando la clase AudioRecord y luego la reproduce con la clase AudioTrack.Android - Obtención de audio para escuchar a través del auricular

Mi problema es que cuando juego se reproduce a través del altavoz del teléfono.

Quiero que se reproduzca a través del auricular en el dispositivo.

Aquí está mi código:

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

Como se puede ver si el código que han intentado usar la clase AudioManager y sus métodos, incluyendo el método setRouting obsoleto y funciona nada, el método setSpeakerphoneOn parece tener ningún efecto en absoluto, tampoco lo hace el método de enrutamiento.

¿Alguien ha tenido alguna idea sobre cómo hacer que funcione a través del auricular en lugar del teléfono spaker?

Respuesta

27

Acabo de hacerlo funcionar en 2.2. Todavía necesitaba la configuración de In_Call que realmente no me gusta, pero me ocuparé de eso por el momento. Pude abandonar el enrutamiento de llamadas que ahora está en desuso. Descubrí que definitivamente necesita el permiso Modify_Audio_Settings, sin error pero el método setSpeakerPhone simplemente no hace nada. Aquí está la maqueta del código que utilicé.

private AudioManager m_amAudioManager; 
m_amAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 
m_amAudioManager.setMode(AudioManager.MODE_IN_CALL); 
m_amAudioManager.setSpeakerphoneOn(false); 
+0

¿Necesita volver a establecer el audio en el estado original antes de establecerlo en IN_CALL? algo como esto: 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

+0

Lo ajusto a MODE_NORMAL para volver a encender el altavoz. Por lo tanto, el código anterior apaga el altavoz y se dirige al auricular, y la ruta del código siguiente vuelve al modo predeterminado del Altavoz. 'm_amAudioManager.setMode (AudioManager.MODE_NORMAL);' – Piwaf

+0

¿altera la configuración global del teléfono? –

3

hubo alguna discusión relacionada en esta última pregunta:
Android - can I mute currently playing audio applications?

Basado en el código fuente AudioManager, parece que debe estar en "modo de llamada" antes de que el método setSpeakerphoneOn tiene ningún efecto.

Sin embargo, recientemente vi una aplicación que podía cambiar sin problemas entre el auricular y el altavoz al mismo tiempo que mostraba el flujo actual como el flujo de "medios", por lo que estaría interesado en cualquier otra respuesta.

+1

Ahh, así que creo que el dispositivo vi este trabajo se estaba ejecutando 1.5. Desafortunadamente, las API de AudioManager parecen estar cambiando a menudo entre lanzamientos. El enrutamiento y el altavoz fueron definitivamente un área que cambió entre 1.5 y 1.6. Lo que apesta. :( –

+0

Hola Christopher, actualmente uso este código para hacerlo y funciona en 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); Sin embargo, está roto desde 1.6 en adelante y no puedo encontrar la nueva solución. He intentado configurar el método SpeakerPhoneOn en falso, pero aún coloca el altavoz, he intentado cambiar todos los flujos y todavía no hay suerte –

+0

Sí, parece bastante roto desde 1.6 en el cual es bastante molesto en el minuto, la mayoría de los dispositivos nuevos están usando una versión más alta que 1.5! –

0

Si el auricular está conectado al teléfono con bluetooth (que supongo que es), ¿ha intentado llamar al AudioManager.setBluetoothScoOn(true)?

He pasado por la referencia de Android y esto es lo único que pude encontrar que no mencionó intentarlo.

+1

No parece que esté usando un auricular Bluetooth. El auricular es el altavoz incorporado que usted tiene su oído en contra durante las llamadas telefónicas –

+0

Sí, como dice Christopher Estoy tratando de ruta el audio a través del auricular que se encuentra en el dispositivo mismo, donde las personas escuchan las llamadas telefónicas normales. Puedo usar el método setRouting y funciona en 1.5; sin embargo, no puedo encontrar una solución para enrutar el audio al auricular desde 1.6 en –

1

Parece que lo tengo funcionando en 1.6.

Así que dije que publicaría aquí cómo lo hice.

para que funcione en 1,6 I:

Se utiliza la clase AudioManager para establecer setSpeakerphoneOn(false), que entonces utilizó el Voice_Call_Stream y añadir control de volumen al Voice_Call_Stream.

setSpeakerphoneOn(false) El método se utiliza en onCreate() de la actividad y esto parece ruta a los auriculares, que luego se usa un botón y se utiliza el método setSpeakerphoneOn(true) y el audio va a parar al altavoz.

El método sólo parece funcionar cuando se utiliza en onCreate() para mí y no he probado ampliamente, pero por el momento me permite cambiar entre el auricular y el altavoz en un dispositivo de 1,6

+0

¿se puede dar algún código? – pengwang

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

El código proporcionado por Achigo funcionaba perfectamente bien. Su código debe tener el permiso ** android.permission.MODIFY_AUDIO_SETTINGS ** establecido en su archivo de manifiesto porque * setSpeakerPhoneOn() * requiere ese permiso. – MegaMind

+0

@MegaMind ¿Qué proporciona este permiso exactamente? Me di cuenta de que la modificación de volumen está bien y no necesita un permiso. ¿Es esto cierto? –

3

Aquí le dejamos algunas respuestas por bastante tiempo. Estoy usando Android 2.2. "audioManager.setSpeakerphoneOn (false);" está trabajando.

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

No está utilizando MediaPlayer –

+1

En realidad, no necesita 'audioManager.setSpeakerphoneOn (false);'. Y también, necesita crear MediaPlayer no con el método estático 'MediaPlayer.create()', pero necesita crearlo con 'new MediaPlayer() ...' – Andranik

3

Por favor, use este código, funciona bien:

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