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 ?

1voto

Achigo Points 17
public MediaPlayer m_mpSpeakerPlayer;

private AudioManager m_amAudioManager;

m_amAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);

// From Receiver Earpiece sound

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

// Set the sound to come from the Earpiece
// The key is here, it needs to be set to in-call
m_amAudioManager.setMode(AudioManager.MODE_IN_CALL);

// Start playing music
m_mpSpeakerPlayer.reset();

m_mpSpeakerPlayer.setDataSource("sdcard/receiver.mp3");

m_mpSpeakerPlayer.prepare();

m_mpSpeakerPlayer.start();

// Finally, set it to play from the Speaker!

m_amAudioManager.setMode(AudioManager.MODE_NORMAL);

0voto

Jonas Van der Aa Points 953

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

J'ai parcouru la documentation Android et c'est la seule chose que j'ai pu trouver que vous n'avez pas mentionnée avoir essayée.

0voto

snachmsm Points 3912

Maintenant en 2022 dans Android S (12, API31) setSpeakerphoneOn(false) ne fonctionne pas de manière fiable, en fait il est obsolète! au lieu de cela, nous pouvons utiliser la nouvelle API et la méthode setCommunicationDevice(AudioDeviceInfo). (fonctionne avec AudioManager.STREAM_VOICE_CALL)

un exemple

Boolean result = null;

ArrayList targetTypes = new ArrayList<>();
if (earpieceMode) {
    targetTypes.add(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
} else { // jouer à voix haute
    targetTypes.add(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
}

AudioDeviceInfo currentDevice = audioManager.getCommunicationDevice();
if (currentDevice!=null) {
    for (Integer targetType : targetTypes) {
        if (targetType == currentDevice.getType()) {
            Log.i("AUDIO_MANAGER", "setCommunicationDevice targetType DEJA CONFIGURE!!");
            result = true;
            break;
        }
    }
}

if (result == null) {
    List devices = audioManager.getAvailableCommunicationDevices();
    outer:
    for (Integer targetType : targetTypes) {
        for (AudioDeviceInfo device : devices) {
            if (device.getType() == targetType) {
                result = audioManager.setCommunicationDevice(device);
                Log.i("AUDIO_MANAGER", "setCommunicationDevice type:" + targetType + " result:" + result);
                if (result) break outer;
            }
        }
    }
}

if (result == null) {
    Log.i("AUDIO_MANAGER", "setCommunicationDevice targetType NON TROUVE!!");
}
else if (!result) {
    Log.i("AUDIO_MANAGER", "setCommunicationDevice targetType ECHOUE A CONFIGURER!!");
}

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