Android: принудительная маршрутизация аудио

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

Я пытался использовать setSpeakerphoneOn из класса AudioManageraudioManager.setSpeakerphoneOn(true); с audioManager.setMode(AudioManager.MODE_IN_CALL); но я не хочу устанавливать MODE_IN_CALL! Я хочу остаться в MODE_NORMAL.

Я обыскал класс AudioSystem и нашел приложение "SoundAbout", которое это делает. Вы можете выбрать динамик для мультимедийного аудио, и режим остается в НОРМАЛЬНОМ.

Итак, я попробовал setDeviceConnectionState в AudioSystem, чтобы установить DEVICE_OUT_WIRED_HEADPHONE в 0, но это не работает. Когда я проверяю статус DEVICE_OUT_WIRED_HEADPHONE, он всегда устанавливается в 1 (AVAILABLE), и я не могу воспроизвести звук через динамик.

Как я могу установить DEVICE_OUT_WIRED_HEADPHONE на 0 или воспроизводить звук через динамик, не находясь в MODE_IN_CALL?

Спасибо и извините за мой плохой английский!

1 ответ

Решение

Я пытаюсь это, и это работает для моего случая:

class AudioSystem {

private static final int REFLECTION_ERROR = -999;

private static final String DEVICE_OUT_SPEAKER          = "DEVICE_OUT_SPEAKER";
private static final String DEVICE_OUT_EARPIECE         = "DEVICE_OUT_EARPIECE";
private static final String DEVICE_OUT_WIRED_HEADPHONE  = "DEVICE_OUT_WIRED_HEADPHONE";


Class<?> mAudioSystem;

protected AudioSystem() {

    try {
        mAudioSystem = Class.forName("android.media.AudioSystem");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

private int getConstantValue(String s) {

    try {
        return ((Integer)mAudioSystem.getDeclaredField(s).get(int.class)).intValue();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return REFLECTION_ERROR;

}


private int setDeviceConnectionState(int i, int j, String s) {

    try {
        return (Integer) mAudioSystem.getMethod("setDeviceConnectionState", int.class, int.class, String.class).invoke(mAudioSystem, i, j, s);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return REFLECTION_ERROR;
}

private int setDeviceConnectionState(String deviceName, Boolean state) {
    return setDeviceConnectionState(getConstantValue(deviceName), (state ? 1 : 0), "");
}

private void forceWiredHeadphonesMedia() {
    setDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE, true);
    setDeviceConnectionState(DEVICE_OUT_SPEAKER, false);
}


private void forceSpeakerMedia() {
    setDeviceConnectionState(DEVICE_OUT_SPEAKER, true);
    setDeviceConnectionState(DEVICE_OUT_EARPIECE, true);
    setDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE, false);
    setDeviceConnectionState(DEVICE_OUT_SPEAKER, true);
}

public void setSpeakerOn(Boolean state) {
    if (state) {
        forceSpeakerMedia();
    } else {
        forceWiredHeadphonesMedia();
    }
}

}

я использую setSpeakerOn(true) отключить проводную гарнитуру.

Предел: AudioManager.isWiredHeadsetOn() вернуть false, даже если гарнитура подключена.

Другие вопросы по тегам