2010-01-22 3 views
32

J'ai actuellement un code qui lit un enregistrement dans le micro de l'appareil en utilisant la classe AudioRecord, puis le rejouer en utilisant la classe AudioTrack.Android - Obtenir de l'audio pour jouer à travers l'écouteur

Mon problème est que lorsque je le joue, il joue via le haut-parleur.

Je veux que cela se joue via l'écouteur de l'appareil.

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

Comme vous pouvez le voir si le code que j'ai essayé d'utiliser la classe AudioManager et ses méthodes, y compris la méthode setRouting dépréciée et rien ne fonctionne, la méthode setSpeakerphoneOn semble avoir aucun effet du tout, pas plus que la méthode de routage.

Quelqu'un at-il des idées sur la façon de le faire jouer via l'écouteur au lieu du téléphone spaker?

Répondre

27

Je l'ai juste pour travailler sur 2.2. J'avais toujours besoin de la configuration In_Call que je n'aime pas vraiment mais je vais m'en occuper pour l'instant. J'ai été en mesure d'abandonner les trucs de routage d'appel qui sont maintenant obsolètes. Je vous ai trouvé absolument besoin de la permission Modify_Audio_Settings, pas d'erreur sans cela, mais la méthode setSpeakerPhone ne fait rien. Voici la maquette du code que j'ai utilisé.

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

Avez-vous besoin de rétablir l'état d'origine de l'audio avant de le définir sur IN_CALL? quelque chose comme ceci: 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

Je suis revenu à MODE_NORMAL pour rallumer le haut-parleur. Donc, le code ci-dessus éteint le haut-parleur et les routes vers l'écouteur, et la route de code ci-dessous s'asseoir à la valeur par défaut du haut-parleur. 'm_amAudioManager.setMode (AudioManager.MODE_NORMAL);' – Piwaf

+0

cela perturbe les paramètres globaux du téléphone ?? –

3

Il y a eu des discussions liées à cette question récente:
Android - can I mute currently playing audio applications?

Basé sur le code source AudioManager, il semble que vous devez être en mode « d'appel » avant que la méthode setSpeakerphoneOn a un effet.

Cependant, j'ai récemment vu une application qui pourrait facilement basculer entre l'écouteur et le haut-parleur tout en montrant le flux actuel comme le flux «média», donc je serais intéressé par d'autres réponses.

+1

Ahh, donc je pense que l'appareil que j'ai vu ce travail était en cours d'exécution 1.5. Malheureusement, les API AudioManager semblent souvent changer entre les versions. Le routage et le haut-parleur était certainement un domaine qui a changé entre 1,5 et 1,6. Qui craint. :( –

+0

Salut Christopher, J'utilise actuellement ce code pour le faire et ça marche dans 1.5 audio_service.setSpeakerphoneOn (faux); audio_service.setMode (AudioManager.MODE_IN_CALL); audio_service.setRouting (AudioManager.MODE_NORMAL, AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL Cependant, il est cassé à partir de 1.6 et je ne peux pas trouver la nouvelle solution.J'ai essayé de définir la méthode SpeakerPhoneOn à faux, mais il place toujours le haut-parleur, j'ai essayé de changer tous les flux et toujours pas de chance –

+0

Oui, il semble être assez cassé à partir de la version 1.6, ce qui est plutôt ennuyeux à la minute, la plupart des nouveaux appareils utilisent une version supérieure à la version 1.5! –

0

Si l'oreillette est connectée au téléphone avec Bluetooth (ce que je suppose), avez-vous essayé d'appeler AudioManager.setBluetoothScoOn(true)?

J'ai été à travers la référence Android et c'est la seule chose que je pourrais trouver que vous n'avez pas mentionné essayer.

+1

Il ne semble pas qu'il utilise un casque Bluetooth. avoir l'oreille contre pendant les appels –

+0

Yep comme Christopher dit que je suis en train d'essayer l'audio à travers l'oreillette qui est sur l'appareil lui-même, où les gens écoutent pour les appels téléphoniques normaux. Je peux utiliser la méthode setRouting et cela fonctionne en 1.5, mais je ne trouve pas de solution pour acheminer l'audio à l'écouteur de 1.6 sur –

1

Je semble l'avoir travaillé sur 1.6.

Alors j'ai dit que je posterais ici comment je l'ai fait.

Pour le faire fonctionner en 1.6 I:

Utilisé la classe AudioManager pour définir setSpeakerphoneOn(false), je puis utilisé le Voice_Call_Stream et ajouter le contrôle du volume au Voice_Call_Stream.

La méthode setSpeakerphoneOn(false) est utilisé dans onCreate() de l'activité et cela semble route vers le casque, je puis utiliser un bouton et utilisé la méthode setSpeakerphoneOn(true) et l'audio est acheminé vers le haut-parleur.

La méthode ne semble fonctionner quand il est utilisé dans onCreate() pour moi et je l'ai pas testé intensivement mais pour le moment il me permet de basculer entre le casque et haut-parleur sur un périphérique 1,6

+0

pouvez-vous donner du code? – 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

Le code donné par Achigo a parfaitement fonctionné. Votre code doit avoir l'autorisation ** android.permission.MODIFY_AUDIO_SETTINGS ** dans votre fichier manifeste car * setSpeakerPhoneOn() * requiert cette autorisation. – MegaMind

+0

@MegaMind Qu'est-ce que cette permission fournit exactement? J'ai remarqué que la modification du volume est correcte et n'a pas besoin d'autorisation. Est-ce vrai? –

3

Trompé par quelques réponses ici pour beaucoup de temps. J'utilise Android 2.2. "audioManager.setSpeakerphoneOn (faux);" travaille.

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

Ne pas utiliser MediaPlayer –

+1

En fait, vous n'avez pas besoin de 'audioManager.setSpeakerphoneOn (false);'. Et aussi, vous devez créer MediaPlayer non avec la méthode statique 'MediaPlayer.create()', mais vous devez le créer avec 'new MediaPlayer() ...' – Andranik

3

S'il vous plaît utiliser ce code, fonctionne 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); 
Questions connexes