Android中检测当前音频路由的有效方法?

Android中检测当前音频路由的有效方法?,android,audio,android-audiomanager,Android,Audio,Android Audiomanager,我的应用程序需要知道用户选择的基本音频路径。在iOS上,这很简单,因为您只需注册回调,就可以准确地知道音频的去向 在Android上,我很高兴看到MediaRouter类,但令我失望的是,没有可预测的方法来确定路由类型。例如,当切换到蓝牙A2DP设备时,唯一的标识项是RouteInfo.getName()方法,但该方法返回A2DP设备的友好名称,因此无法与之进行比较 我还尝试使用以下广播: AudioManager.ACTION_AUDIO_BECOMING_NOISY Intent.ACTIO

我的应用程序需要知道用户选择的基本音频路径。在iOS上,这很简单,因为您只需注册回调,就可以准确地知道音频的去向

在Android上,我很高兴看到
MediaRouter
类,但令我失望的是,没有可预测的方法来确定路由类型。例如,当切换到蓝牙A2DP设备时,唯一的标识项是
RouteInfo.getName()
方法,但该方法返回A2DP设备的友好名称,因此无法与之进行比较

我还尝试使用以下广播:

AudioManager.ACTION_AUDIO_BECOMING_NOISY
Intent.ACTION_HEADSET_PLUG
BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED
然而,这种方法容易出错。例如,如果您连接到蓝牙A2DP,然后插入耳机,很容易判断路由是“耳机”,但在拔出耳机时,您必须通过记录所有蓝牙事件的连接状态来猜测哪个路由仍然处于活动状态

在应用程序启动时,确定初始音频路由也有困难。耳机插头是粘的,所以这很好,但没有其他东西是


关于如何处理此问题并准确检测此问题,有何建议?为什么在安卓系统中这是一项如此困难的任务?

这里有一种非常黑客的方式来轮询当前路由,它也支持A2DP的检测。使用风险由您自己承担,因为这些类的内部可能在将来发生很大的变化。不过,它应该适用于Jellybean和Jellybean MR1

String ouputDeviceName;
try {
    MediaRouter mr = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE);
    Class mediaRouterClass = Class.forName("android.media.MediaRouter");
    Method getSystemAudioRouteMethod = mediaRouterClass.getMethod("getSystemAudioRoute");
    RouteInfo ri = (RouteInfo)getSystemAudioRouteMethod.invoke(mr);

    Class mediaRouterStaticClass = Class.forName("android.media.MediaRouter$Static");
    Field staticField = mediaRouterClass.getDeclaredField("sStatic");
    Field a2dpField = mediaRouterStaticClass.getDeclaredField("mBluetoothA2dpRoute");
    AccessibleObject.setAccessible(new AccessibleObject[]{staticField}, true);
    AccessibleObject.setAccessible(new AccessibleObject[]{a2dpField}, true);
    Object a2dpRoute = a2dpField.get(staticField.get(null));
    if (a2dpRoute != mr.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO)) {
        // Phone, Headphone, HDMI, etc..
        ouputDeviceName = "name: " + ri.getName().toString();
    } else {
        // Audio is routed to A2DP
        ouputDeviceName  = "name: A2DP";
    }
} catch (Exception e) {
    e.printStackTrace();
}

蓝牙路由是否使用SCO或HFP,或者是否由第一个案例处理?当音频路由到BT SCO时,我没有检查结果,而且我现在没有可用的BT附件。不确定您是否能从MediaRouter类中获得有关路由到BT SCO的任何信息-毕竟,您通常不会将媒体音频路由到BT SCO(除非您在语音通话中播放媒体)。只需查看MediaRouter源,它们不会解释除A2DP以外的任何内容,他们只是使用AudioManager.isBluetoothA2dpOn()——我想如果我发现一个我不认识的路由名称,我可以检查这个方法。