Android - Getting Audio to Play Through Earpiece

Android - Getting audio to play through earpiece

Just got it to work on 2.2. I still needed the In_Call setup which I don't really like but I'll deal with it for now. I was able to ditch the call routing stuff which is deprecated now. I found you definitely need the Modify_Audio_Settings permission, no error without it but it the setSpeakerPhone method just does nothing. Here is the mock up of the code I used.

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

Android - Play audio from earpiece

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.

Detect when sound is playing through earpiece speaker

You can approximate this by regularly polling and making the following checks:

  • Check if the audio system is not in normal mode.
  • Check if the audio is being routed to the earpiece.

I tested this in Android 4.3, and it seemed to work fine with the system phone app, Viber and Skype. However, it doesn't seem to detect music or non-telephony sounds played through the earpiece. I don't think this is much of a problem, because the earpiece generally seems to only be used for telephony anyway.

Example

public class EarpieceSpeakerState {

private AudioManager audioManager;

public EarpieceSpeakerState(AudioManager audioManager) {
this.audioManager = audioManager;
}

public boolean usingEarpieceSpeaker() {
return playingSound()
&& routingToEarpiece();
}

private boolean playingSound() {
return audioManager.getMode() != AudioManager.MODE_NORMAL;
}

private boolean routingToEarpiece() {
return !(
audioManager.isSpeakerphoneOn()
|| audioManager.isBluetoothScoOn()
|| audioManager.isBluetoothA2dpOn()
|| audioManager.isWiredHeadsetOn()
);
}

}

Play sound through earpiece when using MediaPlayer

You need to set audio manager mode too. and then using audiomgr.setSpeakerphoneOn(false) api you can toggle.

audiomgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audiomgr.setMode(AudioManager.STREAM_MUSIC);
audiomgr.setSpeakerphoneOn(false);

Android - Getting audio to play through speakers

What that call to setSpeakerPhoneOn (most likely) will do is to route both the music and the voice call to the loudspeaker, in which case they might be mixed together and the music may be downsampled to the voice call sample rate (8 or 16 kHz).

One thing you could try is what I proposed in how to turn speaker on/off programatically in android 4.0
This could let you let you route only the music to the loudspeaker while voice call audio is routed to the earpiece. It's not guaranteed to work on all devices though.

Android - some devices not playing audio through earpiece

Finally i found the solution. When registering for intent ACTION_HEADSET_PLUG in BroadcastReceiver, it was broadcasting sticky intent for the headset unplugged event which was saved from the past event. This was causing the callback to fire which played the audio through speaker only.

Refer to the following stack overflow post for further details: link

To fix the issue i used isInitialStickyBroadcast() method to filter out the past events.

public void onReceive(Context context, Intent intent) {
switch (intent.getIntExtra("state", -1)) {
case 0:
if (!isInitialStickyBroadcast()) {
// headset unplugged
}
break;
case 1:
// headset plugged in
break;
default:
break;
}
}


Related Topics



Leave a reply



Submit