检测Android设备上缺少耳机(仅扬声器)

时间:2011-08-04 14:18:45

标签: android

我有一个应用程序,当在手机上使用时会显示扬声器切换按钮。拨动开关切换手机耳机和扬声器之间的音频路由。但是,当应用程序在平板电脑(或任何没有耳机的设备)上运行时,我想删除切换按钮,因为所有音频都通过免提电话发送。

理想情况下,我想使用某种isEarpiecePresent()调用,或者检查某个配置对象上的标志来查找此信息,但我在API中找不到任何类型的内容。 / p>

我尝试通过调用AudioManager.setSpeakerphoneOn(false)来解决此问题,然后检查AudioManager.isSpeakerphoneOn(),希望它仍然会返回true,我可以关闭它。系统返回false,即使音频仍然通过扬声器传送。

我正在考虑检查电话功能,即使这不完全适合。还有其他想法吗?

5 个答案:

答案 0 :(得分:3)

丑陋的部分是 - 谷歌忽视了这个问题。漂亮的部分是我设法实际检查耳机,并在5/5设备上工作正常(在5.0,5.1,6.0测试)。再一次,丑陋的部分是,这只是糟糕的,不稳定的代码,而且它是hacky,但在他们发布更好的API之前,我做不了多少......

以下是 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;
}

如果你有更好的东西,我可以进行改进编辑:)

答案 1 :(得分:2)

我研究了这个,遗憾的是我找不到任何API支持来检测耳机是否存在。

我现在已将此作为功能请求提出此问题:
http://code.google.com/p/android/issues/detail?id=37623

如果您同意此功能,请点击Google问题页面底部的星标进行投票!

许多用户提出了Google Talk不提供扬声器/耳机切换选项的问题,这可能表明缺少合适的API ...
http://code.google.com/p/android/issues/detail?id=19221

作为一种解决方法,您可能希望在近似设备上隐藏该功能(所有这些方法都有缺点):

  • 具有超大屏幕的那些(即平板电脑)
  • 没有电话支持的人
  • 使用没有耳机的主要设备的可配置白/黑名单。

FTR,如果您使用this answer将音频路由到耳机,则似乎没有任何负面影响在Xoom(OS 3.1)或Samsung Galaxy Tab(OS 2.2)上运行该代码 - 音频继续通过外部扬声器播放。我还没有机会测试是否与蓝牙耳机有任何互动。

答案 2 :(得分:1)

您现在可能已经知道,使用当前的Android API无法完成此操作。

音频硬件接口是专有的,即由制造商为其硬件编写,并且必须支持Android系统的某些调用,以使其与使用Android SDK开发的应用程序兼容。

即使您找到了解决某个设备缺乏API支持的方法,但这可能不适用于所有设备。您的AudioManager.setSpeakerphoneOn(false)示例可能非常适用于设备,因为它取决于音频硬件接口的编写方式。我的假设是,如果没有耳机,大多数平板电脑都会将耳机和扬声器的音频路由视为相同。

如果您想查看Nexus 7的音频硬件接口代码,it's here

答案 3 :(得分:-2)

public boolean isEarPieceConnected() {
        AudioManager audio = (AudioManager) this
                .getSystemService(Context.AUDIO_SERVICE);
        if (audio.isWiredHeadsetOn()) {
            Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
            return true;
        } else {
            Toast.makeText(this, "Not Connected", Toast.LENGTH_SHORT).show();
            return false;
        }
    }

您还可以查看audio.isSpeakerphoneOn()

如果我的问题正确,我希望这会有效。

答案 4 :(得分:-3)

您可以使用音频管理器

进行检查

Audio Manager

并且看看

Head Set Plugged