Подтвердить что ты не робот

Обнаруживать отсутствие наушника (только для громкой связи) на устройстве Android

У меня есть приложение, которое отображает кнопку переключения громкой связи при использовании на телефоне. Тумблер переключает маршрутизацию звука между телефонной гарнитурой и громкой связью. Однако, когда приложение запускается на планшете (или на любом устройстве, у которого отсутствует наушник), я бы хотел удалить переключатель, поскольку все аудио направляется через громкую связь.

В идеале, я бы хотел использовать какой-то вызов isEarpiecePresent() или, возможно, проверить флаг на каком-то объекте конфигурации, чтобы найти эту информацию, но я не могу найти что-либо из этого типа в API.

Я попытался обойти проблему, вызвав AudioManager.setSpeakerphoneOn(false), а затем проверив AudioManager.isSpeakerphoneOn(), надеясь, что он все равно вернется, и я мог бы отменить это. Система вернула false, хотя звук все еще прокладывается через динамик.

В настоящее время я думаю о проверке возможности телефонии, хотя это точно не подходит. Любые другие идеи?

4b9b3361

Ответ 1

Я исследовал это, и, к сожалению, я не могу найти поддержку API для обнаружения того, существует ли динамик.

Теперь я добавил это с Google как запрос функции:
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, если вы используете этот ответ для маршрутизации звука на динамик, не кажется, что какая-либо отрицательная сторона влияет на запуск этого кода в Xoom (ОС 3.1) или вкладку Samsung Galaxy Tab (OS 2.2) - звук просто продолжает воспроизводиться через внешний динамик. У меня не было возможности проверить, нет ли каких-либо взаимодействий с Bluetooth-гарнитурами.

Ответ 2

Таким образом, уродливая часть - Google игнорирует проблему. Приятная часть заключается в том, что мне удалось выполнить проверку на наушники, а на 5/5 устройствах она работала нормально (протестировано на 5.0, 5.1, 6.0). И снова, уродливая часть заключается в том, что это просто плохой, нестабильный код и что он взломан, но пока они не опубликовали лучший API, я бы не смог сделать многое.

Вот хак:

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

Я открыт для редактирования изменений, если у вас есть что-то лучше:)

Ответ 3

Как вы теперь можете быть в курсе, это невозможно сделать с использованием текущего Android API.

Интерфейс Audio Hardware является патентованным, т.е. написанным производителями для их оборудования и должен поддерживать определенные вызовы системой Android, чтобы сделать его совместимым с приложениями, разработанными с помощью Android SDK.

Даже если вы найдете способ избежать поддержки API для одного устройства, это может не работать на всех устройствах. Ваш пример AudioManager.setSpeakerphoneOn(false) может очень хорошо работать для устройств, поскольку все зависит от того, как был записан интерфейс Audio Hardware. Было бы предположение, что большинство планшетов будут обрабатывать звуковую маршрутизацию для наушников и динамиков одинаково, если нет наушников.

Если вы хотите проверить код интерфейса Audio Hardware для Nexus 7, здесь

Ответ 4

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

Я надеюсь, что это сработает, если я получу вашу проблему правильно.

Ответ 5

Вы можете проверить это, используя Audio Manager

Audio Manager

а также посмотрите

Head Set Plugugged