在Android 5.0 Lollipop中处理媒体按钮

13

在 API 21 之前,我使用类似 audioManager.registerMediaButtonEventReceiver(receiver); 的调用来处理用户按下耳机按钮时的媒体按钮事件。从 API 21 开始,似乎应该使用 MediaSession。然而,我完全没有得到任何响应。

final MediaSession session = new MediaSession(context, "TAG");
session.setCallback(new Callback() {
    @Override
    public boolean onMediaButtonEvent(final Intent mediaButtonIntent) {
        Log.i("TAG", "GOT EVENT");
        return super.onMediaButtonEvent(mediaButtonIntent);
    }
});

session.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
        MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

session.setActive(true);

以上是我认为应该可行但实际上不起作用的内容。有人知道这为什么不起作用,或者我应该如何注册吗?


你设置了会话活动状态吗?session.setActive(true) - Nikola Despotoski
请查看代码示例。最后一行是 session.setActive(true); - tvkanters
1
我遇到了你报告的完全相同的问题。我也尝试使用你的代码片段与MediaSessionCompat(来自support V4),但没有成功。我会继续调查,如果我找到了一些解决方案,我会在这里发布答案。 - Luis
1个回答

22

为了接收媒体按钮事件,您需要:

  1. 设置一个MediaSession.Callback并处理适当的事件(*)

  2. 设置MediaSession.FLAG_HANDLES_MEDIA_BUTTONSMediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS标志

  3. 将mediaSession设置为活动状态

  4. 正确设置播放状态,特别是您的会话处理的操作(播放事件)。例如:

    PlaybackState state = new PlaybackState.Builder()
            .setActions(
                    PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PLAY_PAUSE |
                    PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | PlaybackState.ACTION_PAUSE |
                    PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS)
            .setState(PlaybackState.STATE_PLAYING, position, speed, SystemClock.elapsedRealtime())
            .build();
    mSession.setPlaybackState(state);
    

我猜你错过了#4,因为你做其他事情都正确。

(*)Callback.onMediaButtonEvent的默认实现处理所有常见的媒体按钮,并调用正确的onXXXX()方法(onPlay、onPause、onSkipToNext等)。除非你需要处理不常见的媒体按钮,或者出于调试目的,否则不需要重写onMediaButtonEvent。


@Luis,我不明白你所说的接听电话是什么意思。你是指使用硬件按钮来接听电话,还是当来电时暂停音乐? - mangini
实际上,在我的情况下,我想始终通过自定义操作来覆盖默认的Android操作。例如,我想设置单击以增加系统音量。在当前实现中,如果设备正在播放音乐或未播放音乐,我可以拦截耳机点击并执行我的操作,而不是Android默认操作(播放/暂停)。但是当用户正在进行通话时,MediaSession无法拦截耳机点击,呼叫应用程序具有更高的优先级,然后执行其自己的操作,而不是我的自定义操作。 - Luis
1
这就是我所说的“受限标志”的意思 :-) - mangini
3
如果您希望在您的Activity处于前台时接收媒体按钮事件,则需调用setMediaController()方法,并使用已连接到您当前活动的MediaSession的MediaController实例进行设置。 - mangini
我知道这个答案有点老了...我想提出两点观察:
  1. 在MediaSession上不需要设置FLAG_HANDLES_MEDIA_BUTTONSFLAG_HANDLES_TRANSPORT_CONTROLS标志...这些标志已经过时了。
  2. 文档或本答案中未提到的一些事情...当您的应用程序在后台运行时,您必须播放真实的音频才能接收到媒体按钮事件。请参见https://stackoverflow.com/questions/66132814/handling-mediabuttonevents-in-android。
- Hector Ricardo
显示剩余4条评论

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