我有一个功能,我需要获取电流并检测系统有源音频输出设备的开关。就像是:
- 运行应用程序 -> 获取当前设备(可能是嵌入式扬声器)
- 连接蓝牙音箱 - >检测开关到蓝牙音箱
- 连接音频插孔 - >检测从蓝牙扬声器到音频插孔的开关
在我看来,这应该有一个 API,但似乎有几个。最有意义的一个似乎是,MediaRouter
但它有两个大问题阻止我如上所述使用它:
- 至少在 2 种情况下,它会获取错误的设备作为活动路由,而在其他情况下,它根本不会检测到路由切换。有关这方面的详细信息,请查看我在谷歌问题跟踪器上打开的票
- 我需要有关当前活动输出设备的某些信息,最重要的是通用标识符。对于蓝牙设备,
Complete Local Name
可以用于此,可从BluetoothDevice
类型获得,但不能从MediaRouter
. 相反,提供MediaRouter
一个productName
可用的,有时可以是蓝牙设备的别名,而不是静态名称。
我已经放弃了这个 API 并继续寻找其他解决方案,如果有人认为有办法解决上述问题,请告诉我,最重要的是第一个问题。我会注意到我同时使用了 theandroid.media.MediaRouter
和androidx
one,它们都有这些问题。
我现在正在利用其他 API 的组合。它有效,但远非可接受的解决方案:
用于
AudioManager.registerAudioDeviceCallback(object : AudioDeviceCallback)
非蓝牙设备检测 (AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER)
)。当添加或删除这些设备中的任何一个时,我会收到回调,然后我可以检查是否存在有线类型的设备,那么 100% 的时间是活动的,如果不是,那么嵌入式类型是活动的。这有点hacky,但它有效。更有趣的是,为了检测蓝牙输出设备,我使用了一个私有 API,Android 本身在设置应用程序中使用该 API 来显示当前的音频输出设备。
BluetoothA2dp::class.java.getDeclaredMethod("getActiveDevice")
获取当前活动的输出设备。这是通过获取配置文件代理服务来完成的bluetoothAdapter.getProfileProxy
- 为此操作注册一个接收器,
BluetoothA2dp::class.java.getField("ACTION_ACTIVE_DEVICE_CHANGED").get(null)
以检测蓝牙有源音频设备的开关。
此解决方案有效,但也有一些限制:
- 它们是明显的私有 API,会发生突然的变化和潜在的中断
- 上面提到的活动设备API 不可用 < Android 9。我还没有调查 Android 在“设置”应用中使用的是什么 Android9 之前的版本
- 在三星设备上,活动设备API 无法正常工作。
所以,百万美元的问题。如何可靠地获取和检测 Android 上的当前音频路由?