使用MediaSessionCompat来实现Media Button的监听

在API21之前,如果想实现线控,则只需要使用:

1
AudioManager.reregisterMediaButtonEventReceiver(ComponentName eventReceiver)

即可,但是最近更新SDK之后发现这个API已经废弃掉了,推荐使用MediaSession来代替。

API21之前的实现可以参考这篇文章,但是MediaSession是在新的api中加入的,我们可以使用android.support.v4.media.session.MediaSessionCompat:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Creates a new session.
*
* @param context The context.
* @param tag A short name for debugging purposes.
* @param mediaButtonEventReceiver The component name for your receiver.
* If null, this will attempt to find an appropriate
* {@link BroadcastReceiver} that handles
* {@link Intent#ACTION_MEDIA_BUTTON} from your manifest.
* A receiver is required to support platform versions earlier
* than {@link android.os.Build.VERSION_CODES#LOLLIPOP}.
* @param mbrIntent The PendingIntent for your receiver component that
* handles media button events. This is optional and will be used
* on {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} and
* later instead of the component name.
*/
public MediaSessionCompat(Context context, String tag, ComponentName mediaButtonEventReceiver,
PendingIntent mbrIntent) {

MediaSessionCompat的构造函数一共有四个参数,我们这里简单实现Media Button的监听,只需要context和mediaButtonEventReceiver即可,tag用于调试,mbrIntent设置为null即可。首先和API21之前一样实现了一个MediaButtonReceiver:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MediaButtonReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
return;
}

KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null || event.getAction() != KeyEvent.ACTION_UP) {
return;
}

// do something
}
}

接下来我们要做的就是new一个MediaSessionCompat:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class PlayerService extends Service {
private MediaSessionCompat mMediaSession;

@Override
public void onCreate() {
super.onCreate();

ComponentName mbr = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());
mMediaSession = new MediaSessionCompat(this, "mbr", mbr, null);
/* set flags to handle media buttons */
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

/* this is need after Lolipop */
mMediaSession.setCallback(new MediaSessionCompat.Callback() {
@Override
public boolean onMediaButtonEvent(Intent intent) {
if (!Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
return super.onMediaButtonEvent(intent);
}

KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null || event.getAction() != KeyEvent.ACTION_UP) {
return super.onMediaButtonEvent(intent);
}

// do something

return true;
}
});

/* to make sure the media session is active */
if (!mMediaSession.isActive()) {
mMediaSession.setActive(true);
}
}

@Override
public void onDestroy() {
mMediaSession.release();
}
}

其他的和API21之前一样,需要在manifest中注册这个MediaButtonReceiver

1
2
3
4
5
<receiver android:name="com.coolerfall.managers.receivers.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
</receiver>

这样就可以实现和API21之前的监听效果了。

PS: API21之前MediaButtonReceiver是必须的;API21之后MediaSessionCompat.setCallback是必须的,因为MediaSessionCompatAPI21之后通过callback来处理media button。

0%