Status Update
Comments
an...@gmail.com <an...@gmail.com> #2
there are some image for help
an...@gmail.com <an...@gmail.com> #4
The behaviour points you described do indeed make sense but in reality two of them (2 and 3) do not work as described. For 1 and 4, I wasn't aware that was the case and thanks for clarifying.
2. a wired device is plugged in -> onRouteSelected(defaultRoute) // active audio device will be the wired audio device.
If BT was previously the active route, when plugging a wired device in onRouteSelected(defaultRoute)
will get called correctly indeed, however, if you were to then continue and unplug the wired device (#3 below), the system will have audio coming out of the device speakers (default route) but onRouteSelected(BT ROUTE) will get called. After this state occurs, continuing to plug/unplug the wired device will result in a onRouteSelected (BT ROUTE)
getting called every time the active route is the default speakers one.. (Please see Scenario 1 in my initial post for further info on this behaviour)
3. a wired device is plugged out -> onRouteSelected(btRoute) // active audio device will be the previously connected BT device.
Indeed this is what happens, but again, the audio is not coming through the BT speaker, it's coming through the default speakers. Furthermore, I can turn off the BT device as well as turn off BT on the system completely and onRouteSelected(btRoute)
will still get called every time the embedded speakers are the active output device. This behaviour will persist until I re-connect the BT device and make it the in-active route normally (i.e. without plugging in a wired device but simply disconnecting from the BT device).
Please note this behaviour I have experienced on a Google Pixel 1 and Google Pixel 2 both with Android 10, with the androidx mediarouter API
an...@gmail.com <an...@gmail.com> #5
Also, I'd like to re-open this ticket but it seems I cannot.
ol...@google.com <ol...@google.com> #6
I think #4 warrants further investigation/thought?
an...@gmail.com <an...@gmail.com> #7
"I think #4 warrants further investigation/thought?"
And #3 and #4 don't? At least #4 works as intended, whereas #2 and #3 are an almost complete break.
ol...@google.com <ol...@google.com> #8
#4 is just referring to the comment number (i.e.,
an...@gmail.com <an...@gmail.com> #9
Gotcha, sorry about that.
su...@google.com <su...@google.com>
an...@gmail.com <an...@gmail.com> #11
Are there any news on this issue?
jm...@google.com <jm...@google.com> #12
si...@gmail.com <si...@gmail.com> #13
Is there any update on this issue?
When 2 BT devices are connected and the active BT device is changed from BT settings (by tapping on the BT device), no MediaRouter event is fired. Expectation is at least onRouteChanged()
method should be called. This happens on all Pixel devices and other devices which have the option to change the active device from BT like OnePlus.
si...@gmail.com <si...@gmail.com> #14
And also why a volume change also triggers onRouteChanged()
method? Shouldn't it only trigger onRouteVolumeChanged()
?
si...@gmail.com <si...@gmail.com> #15
Some more pain points :
-
If 2 identical(same model number) BT devices are connected and active BT device is changed, shouldn't there be any way to identify if route was actually changed or only volume or any other characteristic of the device is changed?
RouteInfo.getId()
returns same value for both the devices. How is it unique then? The 2 devices differ inMAC address
but theMediaRouter
doesn't give any way to distinguish between the 2 devices. -
If a
wired headset
is connected and then aUSB
device is connected,MediaRouter
givesheadphone
as the current route even thoughUSB
is the active route.
si...@gmail.com <si...@gmail.com> #16
When a onRouteChanged()
event is fired, it would be good to know what was changed. This method gets called even when volume of the device changes. API should indicate reason for change like REASON_VOLUME_CHANGED
etc similar to reason parameter which is added to onRouteUnselected
.
an...@gmail.com <an...@gmail.com> #17
Any news on this? This is an important feature that our product relies upon. If this is gonna take a while to be resolved at least please let us know what other APIs (or even private functions) may be leveraged to achieve proper audio output detection on Android.
er...@softavail.com <er...@softavail.com> #18
da...@gmail.com <da...@gmail.com> #19
co...@gmail.com <co...@gmail.com> #20
an...@gmail.com <an...@gmail.com> #21
If this were not enough, on SKD 32 they now request the (runtime) permission BLUETOOTH_CONNECT to access BluetoothA2dp.getActiveDevice, the only hope I have to correctly query the current route. Same permission is currently required to get the name of any BluetoothDevice, nice.
Good job guys, thanks!
Description
Devices reproduced on: Pixel 1, Pixel 2, Pixel 3
Using the `onRouteSelected` through the `MediaRouter.Callback` of `MediaRouter`, in certain scenarios where the active output device of the system changes (i.e a bluetooth speaker connects, audio jack disconnects, etc) `MediaRouter` will wrongfully report certain routes as being `selected` when they are in fact not.
This is the sample code I am using. Lower down after this sample, I list the scenarios where it fails and how.
```Kotlin
val mediaRouter = MediaRouter.getInstance(context)
val mediaRouterCallback = object: MediaRouter.Callback() { // Implement callback methods as needed.
override fun onRouteSelected(router: MediaRouter?, route: MediaRouter.RouteInfo?) {
super.onRouteSelected(router, route)
println("test route selected: $router?.name)
}
}
val mSelector = MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build()
mediaRouter.addCallback(mSelector, mediaRouterCallback,
MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
```
Fail scenarios:
**Scenario 1 ( Bluetooth device + Audio jack device)**
1. Run the sample
1. Connect a bluetooth audio device so that it is the current active audio output device on the system -> `onRouteSelected` will accurately report the bluetooth device as the selected route.
3. Plug something into the audio jack -> `onRouteSelected` will accurately report the `Headphones` as the selected route
4. Unplug the audio jack device -> `onRouteSelected` will **incorrectly** report the previous bluetooth device as being `selected`. That is, the `isSelected` field for that device (`MediaRouter.RouteInfo`) will be true.
5. At this point, the MediaRouter ends up in a state where it no longer detects any bluetooth changes (as it thinks a bluetooth device is already active). What this means is if I disconnect and reconnect that same bluetooth device (**or others!!**), manually turning off/on or by going to system settings and marking the device active/inactive, `onRouteSelected` will not even get called anymore. The only way I can get it called again from this point is if I plug something into the audio jack.
**Scenario 2 (Bluetooth device + Bluetooth device)**
1. Run sample
2. Connect bluetooth audio device -> `onRouteSelected` will accurately report the bluetooth device as the selected route.
3. Connect **a second** bluetooth audio device and make it the system active audio device (usually that happens automatically or you can do it through `Connected Devices` in the system settings) -> `onSelectedRoute` doesn't get called
4. Essentially, when two bluetooth audio devices are connected, `MediaRouter` will not notify you when you (or the system) is switching between them.
----
I want to **accurately** detect exactly what the active audio output device is at any one time. Digging through the Android source code I noticed that when you guys need to do this exact thing I'm trying to achieve, you're using an internal API that can only be accessed through reflection; the `BluetoothA2DP.class`'s `ACTION_ACTIVE_DEVICE_CHANGED` and `getActiveDevice`.
I tried it and it works but I have to combine this with other APIs (`AudioManager`) to achieve detection for all kinds of devices (BL and non-BL). And also I'd rather not use a private API which is not even available <Android 8.
Furthermore, even if `MediaRouter` were to work properly.. I require getting information similar to the info in `BluetoothDevice`.. which doesn't seem to be available in `MediaRouter`. Can someone give some tips on how I could circumvent all of these problems and get what I want?
Thanks