如何使用MediaSession.setMediaButtonReceiver(PendingIntent)恢复播放

时间:2016-08-28 18:35:27

标签: android android-mediaplayer android-audiomanager android-broadcastreceiver android-mediasession

我的应用程序停止时单击耳机按钮时,我试图能够从我的应用程序启动音乐播放。

我可以使用MediaSession.Callback onMediaButtonEvent()或现已弃用registerMediaButtonEventReceiver()来监听媒体按钮点击 WHILE 我的应用正在播放音乐,但如果我暂停音乐一分钟,我的活动和播放服务仍在运行,然后我按下耳机按钮,我看到我已经失去了接收媒体按钮广播的能力。相反,Google即时会打开。

我尝试做的事情就像Google Play音乐一样。即使应用程序完全停止,它也可以启动音乐播放......后台没有服务。

我觉得setMediaButtonReceiver()是用来做这件事的人,但是我还没能让它发挥作用。

  

setMediaButtonReceiver(PendingIntent mbr)

     

为媒体按钮接收器设置待处理意图,以便在会话停止后重新开始播放。如果您的应用以这种方式启动,则会通过待处理的意图发送ACTION_MEDIA_BUTTON意图。

我的服务中有以下代码段。

PendingIntent pi = PendingIntent.getBroadcast(HeadsetService.this, 0, new Intent(HeadsetService.this, RemoteControlReceiver.class), 0);
mMediaSession.setMediaButtonReceiver(pi);

我的RemoteControlReceiver BroadcastReceiver已在Manifest中注册,但按下按钮时没有收到任何广播。

我也看到其他音乐播放器应用程序一旦停止播放约一分钟就会失去接收媒体按钮广播的功能。

我有什么想法可以拥有更强大的媒体按钮控件吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

首先,将MediaSessionCompat与任何服务(例如MediaBrowserServiceCompat)区分开来很重要。

MediaSessionCompat与外部MediaSessionStack进行通信,该命令指示哪个应用将从外部MediaSessionService获取媒体键命令。在API 26+上,密钥将发送到最后播放的应用程序。 API <26的设备将首先查找活动的播放/缓冲会话,然后查找活动的会话,然后查找最后的播放会话。后者允许应用通过在不需要的时候保持mMediaSesssion.isActive标签的“窃取”焦点。有关优先级的更多详细信息,请参见the official guide

只要您的应用在某个时候设置了mMediaSesssion.isActive = true并最后一次播放,它就会获得媒体密钥,除非调用了mMediaSession.release()。后者将从MediaSessionStack中删除您的会话,因此您的会话将不再接收媒体密钥。这就是为什么一旦您不再希望用户继续播放视频或音乐时呼叫release()的重要性。还有一个警告:如果系统认为您的应用程序被杀死而不是正常结束,那么该应用程序也将从MediaSessionStack中删除,这是有道理的,因为在服务中不一定要调用onDestroy()在这种情况下,系统将为您释放会话。轻扫应用程序时可能会发生这种情况。我使用的一种解决方法是在使用主应用程序时将服务保持在前台,然后在接到服务中对onTaskRemoved()的呼叫后短暂延迟后结束服务。

如果将mMediaSession.release()的呼叫放在服务的onDestroy()中,则会在某个时候发生。该服务预计在不使用时终止,否则将占用系统资源。因此,建议在onStop()命令中或在滑动应用程序或通知时结束它。在您的情况下,电源管理器可能会在闲置一段时间后终止您的服务。根据实现的不同,即使服务被销毁,播放器的某些部分仍可能工作。由于服务不再处于前台,因此通知可能仍然存在。这可能使您误以为该服务正在运行。尽管没有更多细节,但我无法真正说出您的情况到底出了什么问题。

另一个可能导致您的应用无法获取媒体密钥的原因是:清单配置不正确。确保您的BroadcaseReceiver条目包括android.intent.action.MEDIA_BUTTON意向过滤器。

另一个可能的错误是在服务或任何其他生命周期组件中初始化媒体密钥回调MediaSessionCompat.Callback()。因此,如果该组件被破坏,则会迅速导致意外行为。

TLDR:

Logcat过滤MediaSessionStack|MediaSessionService,以确保您的应用获取媒体密钥。如果没有,那么:

  • 确保已设置mMusicService.isActive = true(例如,在onPlay()中)
  • 确保未调用mMusicService.release()
  • 确保清单正确设置
  • 确保系统不会认为您的服务(例如通过刷掉应用程序)被杀死,而不是被正常终止

然后确保您的应用正确处理了媒体密钥。

  • 如果是自定义接收方,它们应该在那里。
  • 对于androidx.media.session.MediaButtonReceiver,它们应处于MediaControllerCompat.Callback(),其状态不应取决于任何服务或生命周期组件

我写的答案比较笼统,因为这是一个古老的问题,其他人可能比OP受益更多。