public class MediaButtonReceiver extends BroadcastReceiver {
private static String TAG = "MediaButtonReceiver";
@Override
public void onReceive(Context context, Intent intent) {
// 获得Action
String intentAction = intent.getAction();
// 获得KeyEvent对象
KeyEvent keyEvent = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction) && keyEvent != null) {
try {
// 获得按键字节码
int keyCode = keyEvent.getKeyCode();
// 按下 / 松开 按钮
int keyAction = keyEvent.getAction();
// ....很多其他代码
会发现keyEvent 在Android 12中为null,虽然前面有对keyEvent 有判断,但三方平台仍报nullpointException,找到使用的地方,发现调用registerMediaButtonEventReceiver方法
// 注册的地方
val audioManager = activity!!.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val name = ComponentName(activity!!.packageName,
MediaButtonReceiver::class.java.name)
audioManager.registerMediaButtonEventReceiver(name)
查看方法源码
@Deprecated
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
}
if (!eventReceiver.getPackageName().equals(getContext().getPackageName())) {
Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
"receiver and context package names don't match");
return;
}
// construct a PendingIntent for the media button and register it
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
// the associated intent will be handled by the component being registered
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent pi = PendingIntent.getBroadcast(getContext(),
0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
registerMediaButtonIntent(pi, eventReceiver);
} @Deprecated
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
}
if (!eventReceiver.getPackageName().equals(getContext().getPackageName())) {
Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
"receiver and context package names don't match");
return;
}
// construct a PendingIntent for the media button and register it
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
// the associated intent will be handled by the component being registered
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent pi = PendingIntent.getBroadcast(getContext(),
0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
registerMediaButtonIntent(pi, eventReceiver);
}
intent确实没有放EXTRA_KEY_EVENT,该方法末尾调用registerMediaButtonIntent,既然如此,直接调用这个方法不就可以了,自己在intent添加事件?! audioManager .registerMediaButtonIntent(),调用不了,但是registerMediaButtonEventReceiver方法的参数还可以传pendingIntent, 所以,可以这么用
val audioManager = activity!!.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val name = ComponentName(activity!!.packageName,
MediaButtonReceiver::class.java.name)
// audioManager.registerMediaButtonEventReceiver(name)
val intent = Intent(Intent.ACTION_MEDIA_BUTTON)
intent.component = name
intent.putExtra(Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK))
pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, 0)
// 开始用反射调用registerMediaButtonIntent方法,但发现完全没必要
// val m = audioManager.javaClass.getMethod("registerMediaButtonIntent",PendingIntent::class.java,ComponentName::class.java)
// m.invoke(audioManager,pendingIntent,null)
audioManager.registerMediaButtonEventReceiver(pendingIntent)
最后记得不用的时候
audioManager.unregisterMediaButtonEventReceiver(pendingIntent)