我正在使用支持将音乐发送到ChromeCast的Android应用。我们希望用户能够在应用在后台运行时投放整个音乐播放列表。
当我的Nexus 7未连接USB电源且我在设置中将屏幕不活动超时时间设置为15秒时,应用程序将在设备关闭其屏幕后约90秒与ChromeCast断开连接。
我已经确定我正在MediaRouter.Callback
拨打onRouteUnselected
,因为这是我在用户断开路线时收到的回叫,我和#39;通过拆除ApplicationSession
来处理它。
当我重新插入并检查logcat时,我会在同一时间看到此消息:
I/MediaRouter(19970): Choosing a new selected route because the current one is no longer selectable: MediaRouter.RouteInfo{ uniqueId=... }
当应用程序在后台时,我可以做任何事情来避免路由被取消选择,还是我可以采取其他措施来获得我想要的行为?
答案 0 :(得分:3)
我最终通过在这些条件下断开路由时拒绝断开消息流并拆除会话来解决这个问题,并在它再次可用时默默地重新选择路由。路线被取消选择,但它不会影响我的演员会话。
为此,我检查路线是否存在,当它未被选中时。
public void onRouteUnselected(final MediaRouter router, final RouteInfo route) {
if (!onUiThread()) {
new Handler(Looper.getMainLooper()).post((new Runnable() {
@Override
public void run() {
onRouteUnselected(router, route);
}
}));
return;
}
boolean isThisRouteAvailable = doesRouterContainRoute(router, route);
mRouteToReconnectTo = null;
if (isThisRouteAvailable) {
// Perform code to close the message streams and tear down the session.
} else {
// The route was unselected because it's no longer available from the router,
// so try to just keep playing until the message streams get disconnected.
mRouteToReconnectTo = route;
// Short-circuited a disconnect.
}
}
稍后,当路线返回时,我们可以立即重新选择它。
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route) {
super.onRouteAdded(router, route);
// if mRouteToReconnectTo is not null, check to see if this route
// matches it, and reconnect if it does with router.selectRoute(route)
}
@Override
public void onRouteSelected(final MediaRouter router, final RouteInfo route) {
if (!onUiThread()) {
new Handler(Looper.getMainLooper()).post((new Runnable() {
@Override
public void run() {
onRouteSelected(router, route);
}
}));
return;
}
if (areRoutesEqual(mRouteToReconnectTo, route)) {
// Short-circuited a reconnect.
mRouteToReconnectTo = null;
return;
}
mRouteToReconnectTo = null;
// Standard post-selection stuff goes here
}
没有比较两个RouteInfo的好方法,所以我最终编写了一个比较其描述字符串的辅助函数。
答案 1 :(得分:3)
Rooster的答案是完全可行的,实际上提供了一个很好的见解,一旦它重新上线后如何重新连接到路线....
但....只是为了进一步了解发生了什么......
你得到......
I/MediaRouter(19970): Choosing a new selected route because the current one is no longer selectable: MediaRouter.RouteInfo{ uniqueId=... }
因为当设备进入休眠状态且未插入电源时,WIFI硬件将进入低功耗配置模式(并可能完全关闭)。这会导致数据包丢失,从而导致MedaRouter触发onRouteUnselected回调。
为防止Wifi关闭,您可以通过以下方式在Wifi上设置WakeLock:
WifiLock wifiLock;
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF , "MyWifiLock");
wifiLock.acquire();
使用标志WifiManager.WIFI_MODE_FULL_HIGH_PERF可在设备进入休眠状态时使WIFI硬件保持活动状态。注意,此标志仅适用于API 12及更高版本。
我在创建WifiLock时尝试使用WifiManager.WIFI_MODE_FULL标志,但这似乎没有办法。
显然,任何使用任何类型的WifiLock或WakeLock的人都应该非常小心地确保在不再需要时释放锁。另外,请注意,当设备屏幕关闭时,这会导致电池耗尽。
答案 2 :(得分:0)
如果你使用了示例代码(在这种情况下是Android),你可能正在这样做......
mSession.setStopApplicationWhenEnding(true);
mSession.endSession();
...取消选择路线时。如果你这样做......
mSession.setStopApplicationWhenEnding(false);
mSession.endSession();
...然后您可以清理会话,但Chromecast会使应用程序保持活跃状态。当路由再次可用时(或者可能在用户再次选择设备时),您可以构建新会话。我还没有探索如何确定新会话是在与应用程序的“全新”实例或从另一个会话中运行的应用程序进行通信,但是当我这样做时,我会更新这个答案。