无需CastButton选中MediaRouter.RouteInfo后CastSession为null的解决方法
你遇到的问题很典型:手动调用MediaRouter.selectRoute()只是切换了系统的媒体路由,但并不会自动触发Cast SDK创建并连接CastSession,所以getCurrentCastSession()才会返回null。要手动开启CastSession,需要借助Cast SDK的SessionManager主动发起会话请求,而不是只依赖路由选择。
下面是具体的解决步骤和代码修改方案:
1. 先确保CastContext初始化完成
在你的Activity或者Application的初始化阶段,先获取CastContext实例,这是Cast SDK的核心入口:
private CastContext mCastContext; private SessionManager mSessionManager; private SessionManagerListener<CastSession> mSessionManagerListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化CastContext mCastContext = CastContext.getSharedInstance(this); mSessionManager = mCastContext.getSessionManager(); // 初始化SessionManager监听器,用来监听会话状态变化 setupSessionManagerListener(); }
2. 实现SessionManagerListener监听会话状态
这个监听器会在CastSession创建、连接成功或者失败时回调,这是你获取有效CastSession的关键:
private void setupSessionManagerListener() { mSessionManagerListener = new SessionManagerListener<CastSession>() { @Override public void onSessionStarted(CastSession session, String sessionId) { // 会话启动成功,这里可以拿到有效的CastSession mCastSession = session; Log.v(TAG, "CastSession已连接: " + mCastSession.isConnected()); // 在这里可以开始发送媒体内容到Cast设备 } @Override public void onSessionEnded(CastSession session, int error) { // 会话结束,清理资源 mCastSession = null; } // 其他回调方法可以按需实现 @Override public void onSessionResumed(CastSession session, boolean wasSuspended) {} @Override public void onSessionStarting(CastSession session) {} @Override public void onSessionEnding(CastSession session) {} @Override public void onSessionResuming(CastSession session, String sessionId) {} @Override public void onSessionSuspended(CastSession session, int reason) {} }; }
3. 修改MyMediaRouterCallback的onRouteSelected方法
当选中路由后,不要直接去拿CurrentCastSession,而是用拿到的CastDevice发起会话请求:
@Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { mSelectedDevice = CastDevice.getFromBundle(info.getExtras()); if (mSelectedDevice != null) { // 创建会话请求,可指定要启动的Receiver应用ID CastSessionRequest request = new CastSessionRequest.Builder(mCastContext) .setCastDevice(mSelectedDevice) // 如果需要指定Receiver应用,替换成你的Receiver ID // .setApplicationId("YOUR_RECEIVER_APP_ID") .build(); // 发起会话启动请求 mSessionManager.startSession(request); Log.v(TAG, "已发起CastSession连接请求到设备: " + mSelectedDevice.getFriendlyName()); } else { Log.v(TAG, "无法从路由信息中获取CastDevice"); } }
4. 注册/注销SessionManagerListener
在Activity生命周期中处理监听器,避免内存泄漏:
@Override protected void onStart() { super.onStart(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); } @Override protected void onStop() { super.onStop(); mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); }
关键注意点
- 会话创建是异步的:你不能在
onRouteSelected里立刻拿到有效的CastSession,必须等待onSessionStarted回调。 - Receiver应用ID:如果需要启动特定的Receiver应用,一定要在
CastSessionRequest里指定,否则会使用默认的媒体Receiver。 - 依赖与权限:确保项目已正确添加Cast SDK依赖,且Manifest中声明了网络等必要权限。
这样修改后,当你选中"Living room"路由时,SDK会主动发起CastSession的连接请求,连接成功后就能在onSessionStarted里拿到可用的CastSession了。
内容的提问来源于stack exchange,提问作者Sergio Burgos
相关产品推荐
相关产品推荐

