web-dev-qa-db-fra.com

Android - Obtenir la lecture audio via l'écouteur

J'ai actuellement du code qui lit un enregistrement depuis le micro de l'appareil à l'aide de la classe AudioRecord, puis le reproduit à l'aide de la classe AudioTrack.

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

Je veux qu'il 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 obsolète et que rien ne fonctionne, la méthode setSpeakerphoneOn semble n'avoir aucun effet, pas plus que la méthode de routage.

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

33
Donal Rafferty

Je viens de le faire fonctionner 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 pu abandonner les trucs de routage d'appels qui sont obsolètes maintenant. J'ai trouvé que vous avez vraiment besoin du Modify_Audio_Settings permission, pas d'erreur sans elle 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); 
27
Piwaf

Trompé par quelques réponses ici depuis pas mal de temps. J'utilise Android 2.2. "AudioManager.setSpeakerphoneOn (false);" fonctionne.

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

Veuillez 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);
3
João Machete

Il y a eu une discussion connexe dans cette question récente:
Android - puis-je couper le son des applications audio en cours de lecture?

Basé sur le code source AudioManager, il semble que vous devez être en "mode appel" avant que la méthode setSpeakerphoneOn n'ait d'effet.

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

3
Christopher Orr
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);
1
Achigo

Il semble que je l'ai fait fonctionner sur 1.6.

J'ai donc dit que je publierais ici comment je l'ai fait.

Pour le faire fonctionner en 1.6 I:

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 être acheminé vers le casque, j'ai ensuite utilisé un bouton et utilisé la méthode setSpeakerphoneOn(true) et l'audio est acheminé vers le haut-parleur.

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

1
Donal Rafferty

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

J'ai parcouru la référence Android référence et c'est la seule chose que j'ai pu trouver que vous n'avez pas mentionnée en essayant.

0
Jonas Van der Aa