5

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

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

我正在尝试做的是类似于 Google Play 音乐的东西。即使应用程序完全停止,它也可以开始播放音乐……后台没有服务。

我觉得setMediaButtonReceiver()是用于此的,但我无法让它工作。

setMediaButtonReceiver(PendingIntent mbr)

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

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

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

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

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

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

提前致谢!

4

1 回答 1

2

首先,MediaSessionCompat与任何服务(例如MediaBrowserServiceCompat.

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

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

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

可能会阻止您的应用获取媒体密钥的另一个原因是您的清单配置不正确。确保您的BroadcaseReceiver条目包含android.intent.action.MEDIA_BUTTON意图过滤器。

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

TLDR:

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

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

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

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

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

于 2020-09-09T00:03:53.187 回答