androidaudiospeaker

Detect when sound is playing through earpiece speaker


Background

I'm developing an app that monitors the proximity sensor. However, I don't want to monitor the sensor while the user is listening to something through the phone ear speaker. This is because the user will probably have his/her head against the handset to listen, which in turn triggers the proximity sensor, and I'm not trying to detect head proximity.

Question

How can I detect when sound is and isn't playing through the handset ear speaker? Callbacks are preferable, of course, but I'm willing to poll if it's the only way.


Solution

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

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