MediaBrowser无法连接MediaBrowserService,onConnected回调未触发
我之前也碰到过这个一模一样的头疼问题!明明MediaBrowserService的onCreate都执行完了,可onConnected就是不触发,连onConnectionFailed都没动静,直接设置MediaController还报错,太闹心了。咱们一步步来排查可能的原因:
1. 先检查AndroidManifest.xml里的服务声明
这是最容易踩坑的点!你必须确保StreamingService的<service>标签里包含了正确的intent-filter,否则MediaBrowser根本找不到你的服务:
<service android:name=".StreamingService" android:exported="false"> <!-- 同一APP内使用设为false即可 --> <intent-filter> <!-- 必须添加这个action,MediaBrowser才能识别到服务 --> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>
如果漏了这个intent-filter,MediaBrowser连服务的存在都检测不到,自然不会触发任何连接回调。
2. 确认MediaBrowserService的onGetRoot方法正确实现
onGetRoot是连接流程的关键入口,如果这个方法返回null,MediaBrowser会直接判定连接失败(甚至可能不触发onConnectionFailed)。对于同一APP内的连接,你可以直接返回一个非空的BrowserRoot:
@Override public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { // 同一APP内的客户端直接允许访问,返回根节点 return new BrowserRoot("media_root", null); }
如果这里做了严格的权限校验,比如误判了客户端包名,也会导致返回null,阻断连接。
3. 检查MediaBrowser的ComponentName是否正确
你的代码里用了new ComponentName(this, StreamingService.class),要确保StreamingService的类名完全正确——比如有没有在子包下?有没有拼写错误?如果类名不对,MediaBrowser同样找不到服务。
4. 验证SessionToken的设置时机
你提到在服务的onCreate里调用了setSessionToken,但必须确保这一步是在MediaSessionCompat创建完成之后执行的:
private MediaSessionCompat mMediaSession; @Override public void onCreate() { super.onCreate(); // 先初始化MediaSession mMediaSession = new MediaSessionCompat(this, "StreamingServiceTag"); mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); // 设置必要的SessionCallback(处理播放控制等逻辑) mMediaSession.setCallback(new MediaSessionCompat.Callback() { // 实现必要的方法,比如onPrepareFromUri、onPlay等 }); // 最后再设置SessionToken setSessionToken(mMediaSession.getSessionToken()); }
如果setSessionToken调用过早(比如MediaSession还没创建),服务无法正常对外提供连接能力。
5. 排查服务初始化时的隐藏异常
虽然你说服务的onCreate执行到了末尾,但有没有可能在onCreate之后的代码里出现了未捕获的异常?比如MediaSession初始化时抛出了错误?你可以打开Logcat,过滤StreamingService相关的日志,看看有没有崩溃警告或者异常信息。
6. 调试连接流程的关键节点
给服务的onGetRoot和onLoadChildren方法加日志或断点:
- 如果
onGetRoot没被调用:说明MediaBrowser找不到服务,回到第一步检查Manifest。 - 如果
onGetRoot被调用但返回了null:调整权限校验逻辑,返回有效的BrowserRoot。 - 如果
onGetRoot返回了BrowserRoot,但onLoadChildren没被调用:检查MediaBrowser的连接逻辑,或者看看有没有其他生命周期问题。
按照这个顺序排查,大概率能找到问题所在。我当时就是漏加了Manifest里的intent-filter,折腾了半天!
内容的提问来源于stack exchange,提问作者transiti0nary

