34 votes

Android - Faire jouer l'audio à travers l'écouteur interne

Actuellement, j'ai du code qui lit un enregistrement depuis le microphone de l'appareil en utilisant la classe AudioRecord et le joue ensuite en utilisant la classe AudioTrack.

Mon problème est que lorsqu'il est lu, cela se fait via le haut-parleur du téléphone.

Je veux qu'il soit lu via l'écouteur de l'appareil.

Voici mon code :

public class LoopProg extends Activity {

 boolean isRecording; //actuellement non utilisé
 AudioManager am;
 int count = 0;

 /** Appelé lorsque l'activité est créée. */
 @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", "Le compteur est: " + 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", "Le haut-parleur est-il actif ? : " + am.isSpeakerphoneOn());
      am.setSpeakerphoneOn(false);
      Log.d("SPEAKERPHONE", "Le haut-parleur est-il actif ? : " + 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, 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 n'avoir aucun effet du tout, tout comme la méthode de routage.

Est-ce que quelqu'un a une idée de comment le faire passer par l'écouteur au lieu du haut-parleur ?

29voto

Piwaf Points 304

Vient de le faire fonctionner sur la version 2.2. J'ai quand même eu besoin de la configuration In_Call que je n'aime pas vraiment mais je vais faire avec pour l'instant. J'ai pu me débarrasser du truc de routage d'appels qui est maintenant obsolète. J'ai trouvé que vous avez définitivement besoin de l'autorisation Modify_Audio_Settings, aucune erreur sans elle mais la méthode setSpeakerPhone ne fait tout simplement rien. Voici le code que j'ai utilisé en maquette.

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

7voto

jmachete Points 977

Veuillez utiliser ce code, il fonctionne bien:

    //JOUER SUR L'OREILLETTE
    mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
    audioManager.setMode(AudioManager.MODE_IN_CALL);
    audioManager.setSpeakerphoneOn(false);

    //JOUER SUR LE HAUT-PARLEUR
    mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    audioManager.setMode(AudioManager.MODE_IN_CALL);
    audioManager.setSpeakerphoneOn(true);

4voto

Christopher Orr Points 58514

Il y a eu une discussion connexe dans cette question récente:
Android - puis-je désactiver les applications audio en cours de lecture?

Sur la base du code source de AudioManager, il semble que vous devez être en "mode d'appel" avant que la méthode setSpeakerphoneOn ait un quelconque effet.

Cependant, j'ai récemment vu une application qui pouvait passer de manière transparente entre l'écouteur et le haut-parleur tout en affichant toujours le flux actuel comme le flux "média", donc je serais intéressé par d'autres réponses.

3voto

Haisea Points 936

Égaré par certaines réponses ici pendant un certain temps. J'utilise Android 2.2. "audioManager.setSpeakerphoneOn(false);" fonctionne.

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

1voto

Donal Rafferty Points 7914

Il semble que j'ai réussi à le faire fonctionner sur 1.6.

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

Pour le faire fonctionner en 1.6, j'ai :

Utilisé la classe AudioManager pour définir setSpeakerphoneOn(false), j'ai ensuite utilisé le Voice_Call_Stream et ajouté le contrôle du volume au Voice_Call_Stream.

La méthode setSpeakerphoneOn(false) est utilisée dans onCreate() de l'activité et cela semble routé vers le casque, j'ai ensuite utilisé un bouton et utilisé la méthode setSpeakerphoneOn(true) et le son est routé vers le haut-parleur.

La méthode semble fonctionner uniquement quand elle est utilisée dans onCreate() pour moi et je ne l'ai pas testée de manière approfondie mais pour le moment cela me permet de basculer entre le casque et le haut-parleur sur un appareil 1.6

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X