I use v7 support library MediaRouter for switching routes between phone's speaker and bluetooth device.
And sometimes it works strange, for example, when I turn off the bluetooth, corresponding route seems to be removed (playback switches to the speaker), but my application doesn't receive any callback about it. And moreover, when I manually get all the routes via MediaRouter.getRoutes(), it returns that bluetooth route, but when I try to switch to it, it seems to be selected, but actually playback still goes through the speaker.
I tried all the flags CALLBACK_FLAG_FORCE_DISCOVERY, CALLBACK_FLAG_REQUEST_DISCOVERY etc, without result. Only phone reboot helps. Any suggestions?
I used Android 4.2, 4.4.
UPDATE, code sample: ....
private MediaRouter mMediaRouter;
private MediaRouter.Callback mMediaRouterCallback = new MediaRouter.Callback(){
@Override
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo route) {
super.onRouteAdded(router, route);
refreshRoutes();
Log.i(TAG, "Route added ==> " + route.getName());
}
@Override
public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo route) {
super.onRouteRemoved(router, route);
refreshRoutes();
Log.i(TAG, "Route removed ==> " + route.getName());
}
@Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
super.onRouteSelected(router, route);
Log.i(TAG, "Route selected ==> " + route.getName());
refreshRoutes();
}
@Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
super.onRouteUnselected(router, route);
Log.i(TAG, "Route UNselected ==> " + route.getName());
refreshRoutes();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRoutesList = (ListView) findViewById(R.id.routesList);
mRoutesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String routeName = mRoutesAdapter.getItem(i);
List<MediaRouter.RouteInfo> routes = mMediaRouter.getRoutes();
for (MediaRouter.RouteInfo rout : routes){
if (rout.getName().equals(routeName)){
mMediaRouter.selectRoute(rout);
}
}
}
});
mMediaRouter = MediaRouter.getInstance(this);
mMediaRouter.addCallback(
new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build(),
mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
mRoutesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
mRoutesList.setAdapter(mRoutesAdapter);
refreshUi();
}
@Override
protected void onDestroy() {
mMediaRouter.removeCallback(mMediaRouterCallback);
super.onDestroy();
}
private void refreshRoutes(){
mRoutesAdapter.clear();
MediaRouter.RouteInfo selectedRoute = mMediaRouter.getSelectedRoute();
List<MediaRouter.RouteInfo> routes = mMediaRouter.getRoutes();
for (MediaRouter.RouteInfo rout : routes){
if (rout == selectedRoute)
mRoutesAdapter.add(rout.getName() + " [selected]");
else
mRoutesAdapter.add(rout.getName());
}
mRoutesAdapter.notifyDataSetChanged();
}
Using @Xaver's suggestion in the question comments, I put all of the MediaRouting in a Service. I got everything working how it was before the service but the same error was occurring. When I returned to an activity, after one switch from the wired to the BlueTooth speaker, the MediaRouter
would get stuck on the wired speaker despite saying that the current route was the Bluetooth speaker.
Switching from android.support.v7.media.MediaRouter
to the android.media.MediaRouter
and refactoring my code a little everything worked perfectly. Hard to say if moving the routing to a service was part of the combination but I got it working (after ~50 hours of tinkering with everything)
The unfortunate thing with android.media.MediaRouter
is it doesn't have a getRoutes
method, but nothing a little Googleing couldn't handle! Since I found it a pain to figure this out from the docs, since everything is referencing the v7
library, below is how to get the MediaRouter and select a route.
MediaRouter mr = (MediaRouter)this.getSystemService(this.MEDIA_ROUTER_SERVICE);
mr.selectRoute(mr.ROUTE_TYPE_LIVE_AUDIO, mr.getRouteAt(0));
Hopefully this helps someone!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With