【问题标题】:Android : Force audio routingAndroid:强制音频路由
【发布时间】:2015-07-10 05:34:21
【问题描述】:

我想在我的 Android 应用中更改声音设备输出。我想在耳机插入时使用手机的扬声器。

我尝试将 AudioManager classaudioManager.setSpeakerphoneOn(true); 中的 setSpeakerphoneOn 与 audioManager.setMode(AudioManager.MODE_IN_CALL); 一起使用,但我不想设置 MODE_IN_CALL !我想留在 MODE_NORMAL。

我搜索了 AudioSystem 类,发现了一个应用程序“SoundAbout”,它可以做到这一点。您可以为媒体音频选择扬声器,并且模式保持在 NORMAL。

所以我尝试在 AudioSystem 中使用 setDeviceConnectionState 将 DEVICE_OUT_WIRED_HEADPHONE 设置为 0,但它不起作用。当我检查 DEVICE_OUT_WIRED_HEADPHONE 的状态时,它总是设置为 1 (AVAILABLE),我无法通过扬声器播放声音。

如何在不处于 MODE_IN_CALL 的情况下将 DEVICE_OUT_WIRED_HEADPHONE 设置为 0 或通过扬声器播放声音?

感谢和抱歉我的英语不好!

【问题讨论】:

    标签: android output android-audiomanager speaker


    【解决方案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。

    【讨论】:

    • 能否请您提供一些提示,我需要如何使用您的AudioSystem 课程? @Mattt1438
    • setDeviceConnectionState 似乎不适用于 Android 10 及更高版本,记录以下错误:AudioSystem-JNI: Command failed for android_media_AudioSystem_setDeviceConnectionState。在最近的 SDK 版本上工作的任何替代方案?
    猜你喜欢
    • 2015-11-01
    • 1970-01-01
    • 2011-04-10
    • 2014-01-09
    • 2018-12-12
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多