13

我已尝试根据Google 的谈话实现媒体按钮控制

我在清单中设置了接收器:

<receiver android:name="android.support.v4.media.session.MediaButtonReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

<service android:name=".player.PlayFileService">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</service>

创建MediaSessionCompat服务onCreate()

    mediaSession = new MediaSessionCompat(getApplicationContext(), "SOUNDPROCESS");
    mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    PlaybackStateCompat ps = new PlaybackStateCompat.Builder()
            .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE)
            .build();
    mediaSession.setPlaybackState(ps);
    mediaSession.setCallback(new MediaSessionCompat.Callback() {
        @Override
        public void onPlay() { ...
           }
    });

并处理意图onStartCommand()

MediaButtonReceiver.handleIntent(mediaSession, intent);

然后setActive(true);,当我获得音频焦点和setActive(false);停止播放时,我会打电话。这是第一次,我的应用程序成为首选的媒体按钮接收器并接收回调。

但是,如果我在我的应用程序中停止播放,进入另一个应用程序(如 Google Play 音乐)并在那里开始播放,然后返回我的应用程序并调用setActive(true)Google Play 音乐继续接收回调,并且媒体按钮在我的应用程序中不起作用。

据我了解,最后一次调用setActive(true)应该优先。我已经验证isActive()返回 true。我也可以通过每次创建一个新的来解决这个问题MediaSessionCompat,但这似乎并不理想。

每次打电话时,如何让我的应用程序成为首选的媒体按钮接收器setActive(true)

更新:在此处重现问题的最小项目:https ://github.com/svenoaks/MediaButtonDemo.git

重现步骤:

  1. 运行应用程序,按 PLAY 按钮。setActive(true)被调用并且 MediaButtonReceiver 现在是首选的媒体按钮。
  2. 按有线或无线耳机或其他媒体按钮上的播放/暂停按钮。Toast 显示表明回调正在工作。
  3. 在支持媒体按钮的其他应用程序(例如 Google Play 音乐)上开始播放。在这个应用程序上按暂停。
  4. 演示应用程序不再是首选的媒体按钮接收器,即使再次按下 PLAY 按钮,再次调用setActive(true) 。另一个应用程序始终响应媒体按钮。

这是在 Android 6.0 上测试的。

4

2 回答 2

3

我的观察:(没有足够的声誉来评论,道歉,但我可以回复这个答案的评论)

  1. '运行应用程序,按下播放按钮。调用 setActive(true) 并且 MediaButtonReceiver 现在是首选媒体按钮:因为 Android 首先将媒体按钮事件分派到前台活动。

  2. '在另一个应用程序上开始播放.......在这个应用程序上按暂停........然后返回我的应用程序并调用 setActive(true)':

a) 如果您在播放 GooglePlay 音乐之前调用了 onStop 侦听器,那么当您按下任何媒体按钮时,您的媒体会话不会处于活动状态(直到再次调用 onPlay),因此当前会话即 Google Play 会被播放。

b)如果您没有调用 onStop 则有 2 个活动会话(您的应用程序的第一个会话和 Google Play 的第一个会话。除非再次调用 OnPlay,否则不会调用第二个会话)。根据文档,如果有多个活动媒体会话,Android 会尝试选择一个准备播放(缓冲/连接)、播放或暂停的媒体会话,而不是一个已停止的媒体会话。因此 GooglePlay 是具有暂停状态并被播放的最新活动会话。

c)如果您调用了 onStop(因此 setActive(false)),并且如果 GooglePlayMusic 也已 setActive(false),并且您没有再次单击 onPlay,那么在这种情况下,GooglePlayMusic 也会播放,因为“如果没有活动会话, Android 尝试将事件发送到最近活动的会话。在 Android 5.0(API 级别 21)或更高版本上,事件仅发送到已调用 setMediaButtonReceiver() 的会话。

你有设置MediaButtonReceiver()吗?

https://developer.android.com/guide/topics/media-apps/mediabuttons.html 请看一下

于 2017-01-26T11:43:17.313 回答
2

使这项工作正常工作的关键是正确设置PlaybackState您的应用程序每次开始播放或暂停的时间(当另一个应用程序获得音频会话并激活自己的时应该这样做MediaSession。如果没有这个,就会发生上述问题。另外,对于 Android 4.4 及更低版本, FLAG_HANDLES_TRANSPORT_CONTROLS必须设置,否则会发生同样的问题。

于 2017-03-20T16:10:50.933 回答