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

5

我想在我的应用程序停止时,通过耳机按钮点击开始音乐播放。

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

我想做的是像Google Play Music一样的事情。即使应用程序完全停止,也能开始音乐播放...没有后台服务。

我觉得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广播接收器已在清单中注册,但我按下按钮时没有收到广播。

我还发现其他音乐播放器应用程序一旦停止播放约一分钟后就失去了接收媒体按钮广播的能力。

有什么想法可以让我的媒体按钮控制更加强大可靠吗?

提前致谢!


这段时间过得怎么样?你有什么好运气吗? - Glaucus
1个回答

5
首先,需要将MediaSessionCompat与任何服务(如MediaBrowserServiceCompat)区分开来。 MediaSessionCompat正在与外部的MediaSessionStack通信,该堆栈指定哪个应用程序将从外部的MediaSessionService接收媒体键命令。在API 26+上,该键将发送到最后一个播放的应用程序。具有API<26的设备将首先查找活动播放/缓冲会话,然后查找活动会话,最后查找最后一个播放会话。后者允许应用程序通过保持mMediaSesssion.isActive标记而“窃取”焦点。当它们不应该这样做时,可以在官方指南中找到有关优先级的更多详细信息。
只要您的应用程序在某个时刻设置了mMediaSesssion.isActive = true并且是最后一次播放的应用程序,它就会获得媒体键,除非调用了mMediaSession.release()。后者会将您的会话从MediaSessionStack中删除,因此您的会话将不再接收媒体键。这就是为什么在您不再希望用户继续播放视频或音乐时调用release()非常重要。还有一个注意事项:如果系统认为您的应用程序已被杀死而不是正常结束,则该应用程序也会从MediaSessionStack中删除,这是有道理的,因为在这种情况下,在服务中onDestroy()不一定被调用,因此系统会为您释放会话。当您滑动应用程序时可能会发生这种情况。我使用的解决方法是在主应用程序使用时将服务保持在前台,然后在收到服务中的onTaskRemoved()调用后延迟一段时间结束服务。
如果在您的服务的onDestroy()中放置了mMediaSession.release(),则将在某个时刻调用它。当服务未被使用时,预计该服务将结束,否则它将占用系统资源。因此,建议在onStop()命令或滑动应用程序或通知时结束它。在您的情况下,可能会发生电源管理器在一段时间不活动后杀死您的服务。根据实现方式,即使服务被销毁,播放器的某些部分可能仍在工作。此外,通知可能仍然存在,因为服务不再处于前台。这可能会让您误以为服务正在运行。但是,如果没有更多详细信息,我无法确定您的情况出了什么问题。
另一个可能阻止您的应用程序获得媒体键的原因是您的清单未正确配置。确保您的BroadcaseReceiver条目包括android.intent.action.MEDIA_BUTTON意图过滤器。
另一个可能的错误是在服务或任何其他生命周期组件中初始化您的媒体密钥回调MediaSessionCompat.Callback()。因此,如果该组件被销毁,可能会迅速导致意外行为。
简而言之: 过滤您的Logcat,以确保您的应用程序获取媒体密钥。如果没有,则需要: 1. 确保在onPlay()中设置mMusicService.isActive = true 2. 确保不调用mMusicService.release() 3. 确保正确设置了您的清单 4. 确保系统认为您的服务已经优雅地结束,而非通过关闭应用程序来杀死服务
然后,请确保您的应用程序正确处理媒体键。 1. 对于自定义接收器,它们应该存在。 2. 对于androidx.media.session.MediaButtonReceiver,它们应该在状态不依赖于任何服务或生命周期组件的MediaControllerCompat.Callback()中。
我将答案写得更加通俗易懂,因为这个问题很久以前就存在了,其他人可能会从中受益。

这真的很有帮助 - 我最长时间忽略的另一件事是,设置媒体按钮接收器“不是必需的”,事实上,如果您不设置它,您就不需要担心媒体会话的生命周期。我只是在查看Vanilla音乐播放器的源代码后才注意到这个差异,幸运的是,它是开源的,我知道它会从媒体按钮恢复播放 - https://github.com/vanilla-music/vanilla/blob/3442b6cdd049a1f96de4c8f2e354fab3d7f9f880/app/src/main/java/ch/blinkenlights/android/vanilla/MediaSessionTracker.java - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接