Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect lack of earpiece (speakerphone only) on an Android device

Tags:

android

I've got an app which displays a speakerphone toggle button when used on a phone. The toggle switches audio routing between the phone's earpiece and the speakerphone. However, when the app is run on a tablet (or any device which lacks an earpiece), I'd like to remove the toggle, since all audio is routed through the speakerphone.

Ideally, I'd like to use some kind of isEarpiecePresent() call, or maybe check a flag on some configuration object to find this information, but I can't find anything of the sort in the API.

I attempted to work around the issue by calling AudioManager.setSpeakerphoneOn(false), then checking AudioManager.isSpeakerphoneOn(), hoping that it would still return true and I could key off of that. The system returned false, even though audio is still routing through the speaker.

I'm currently thinking of checking for telephony capability, even though that doesn't exactly fit. Any other ideas?

like image 574
Josh Avatar asked Aug 04 '11 14:08

Josh


People also ask

Why can't people hear me on my phone unless it's on speaker?

Method 1: Turn your Volume up Now, this might come as a shock, but most of the time, you can't hear phone calls unless on speaker Android only because of a low call volume. And in some cases, zero volume! Before doing anything drastic, this should be the first thing that you should do –– increase your phone's volume.

Can only hear phone calls on Speaker Android?

Check the call and media volume on your Android phone . If it is low or mute, increase the call and media volume and retry. Also, check for dirt particles in your phone's microphone and clean it if it is clogged.


2 Answers

So the ugly part is - Google is ignoring the problem. The pretty part is that I managed to actually do the check for earpiece, and on 5/5 devices it worked fine (tested on 5.0, 5.1, 6.0). And again, the ugly part is that this is just bad, unstable code and that it's hacky, but until they publish a better API, I couldn't do much..

Here is the hack:

private Boolean mHasEarpiece = null; // intentionally 'B' instead of 'b'

public boolean hasEarpiece() {
    if (mHasEarpiece != null) {
        return mHasEarpiece;
    }

    // not calculated yet, do it now
    try {
        Method method = AudioManager.class.getMethod("getDevicesForStream", Integer.TYPE);
        Field field = AudioManager.class.getField("DEVICE_OUT_EARPIECE");
        int earpieceFlag = field.getInt(null);
        int bitmaskResult = (int) method.invoke(mAudioManager, AudioManager.STREAM_VOICE_CALL);

        // check if masked by the earpiece flag
        if ((bitmaskResult & earpieceFlag) == earpieceFlag) {
            mHasEarpiece = Boolean.TRUE;
        } else {
            mHasEarpiece = Boolean.FALSE;
        }
    } catch (Throwable error) {
        Log.e(TAG, "Error while checking earpiece! ", error);
        mHasEarpiece = Boolean.FALSE;
    }

    return mHasEarpiece;
}

I'm open for improvement edits if you have something better :)

like image 102
milosmns Avatar answered Oct 12 '22 13:10

milosmns


I've researched this and unfortunately I can't find any API support for detecting whether an earpiece exists.

I've now raised this with Google as a feature request:
http://code.google.com/p/android/issues/detail?id=37623

If you agree with the feature, click on the star at the bottom of the Google issue page to vote for it!

Lots of users have raised the issue that Google Talk doesn't offer a speaker/earpiece toggle option, which perhaps suggests the absence of a suitable API...
http://code.google.com/p/android/issues/detail?id=19221

As a workaround you may wish to hide the feature on devices approximated by (all of these approaches have drawbacks):

  • those with extra large screens (i.e. tablets)
  • those with no telephony support
  • use a configurable white/blacklist of the main devices that do not have an earpiece.

FTR, if you use this answer to route audio to the earpiece, there don't seem to be any negative side affects running that code on the Xoom (OS 3.1) or the Samsung Galaxy Tab (OS 2.2) - the audio just continues to play through the external speaker. I haven't had a chance to test if there are any interactions with Bluetooth headsets yet.

like image 45
Dan J Avatar answered Oct 12 '22 13:10

Dan J