Android - Play audio from earpiece

I'd like to play audio from a file into the phone's earpiece (or headset of that is connected) using the android MediaPlayer. I tried using the MODE_IN_CALL hack as suggested in this thread - Android - Getting audio to play through earpiece but that did not help. The app also has the android.permission.MODIFY_AUDIO_SETTINGS permission, but any call to m_amAudioManager.setSpeakerphoneOn(false); is ignored.

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

A call to setMode(AudioManager.STREAM_VOICE_CALL); on the MediaPlayer did not help either.

mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();

Has something changed since android 2.3 to break this code ? I tried the code on Android ICS without any success. Can someone point me in the right direction ? The audio always plays from the speaker phone so far.


Solution 1:

It turns out the right way to do this is through the following code.

Play through the ear piece

mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

Play through the speaker phone

mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

That is it. Any other solution (Including the one posted here -> Android - Getting audio to play through earpiece) does not work consistently across devices. In fact using MODE_IN_CALL ensures that your audio will never play on certain devices.

Note: You will need to re-prepare the media player to change streams.

Solution 2:

i just wanted to add a complete example for Deepak Bala's Answer. It works when not using the MediaPlayer.create() method:

    this.player = new MediaPlayer(); 
    this.player.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

    try {
        this.player.setDataSource(getContext(), Uri.fromFile(new File(m.localFileUrl)));
        this.player.prepare();
    } catch (IllegalStateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }