Android: 处理耳机按钮事件并将信息发送到 MainActivity

Android: Handle headset buttons events and Send information to MainActivity

这是我努力编写的工作代码,以最佳方式处理耳机按钮事件。我读了 Android developer guide,但这显然是错误的,因为他们要求开始收听注册一个 class 名称。

am.registerMediaButtonEventReceiver(RemoteControlReceiver); // Wrong

所以我查看了其他示例来更正代码。比如this question, I also tried other code such as this, and another solution with 发表了很多秘笈,清理不需要的我写了这段代码:

我实现了 class RemoteControlReceiver。显然不需要静态内部 class,实际上,请参阅 this comment:

public class RemoteControlReceiver extends BroadcastReceiver {

        public RemoteControlReceiver() {
            super();
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "EVENT!!", Toast.LENGTH_SHORT).show();
            if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
                KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
                    Toast.makeText(context, "EVENT!!", Toast.LENGTH_SHORT).show();

                }
            }
        }
    }

然后我在 MainActivity onCreate(){...

中注册了意图
    AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
    ComponentName mReceiverComponent = new ComponentName(this, RemoteControlReceiver.class);
    am.registerMediaButtonEventReceiver(mReceiverComponent);

顺便说一句,registerMediaButtonEventReceiver 已被弃用...

在清单中,我记录了过滤器,在 activity 标签之后:

<activity>
...
</activity>

<receiver android:name=".RemoteControlReceiver" android:enabled="true">
    <intent-filter android:priority="2147483647">
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

注意:静态内部 class 将是,例如,“.MainActivity$RemoteControlReceiver”。

我正在研究

compileSdkVersion 24
buildToolsVersion "24.0.0"
...
minSdkVersion 21
targetSdkVersion 24

这是我的问题:

API 21 改变了整个媒体应用程序 APIs,现在完全以 MediaSession. Instead of registering a BroadcastReceiver (as was needed prior to API 18) or a PendingIntent (via registerMediaButtonEventReceiver(PendingIntent)), you can receive callbacks directly in the MediaSession.Callback.

为中心

您可以通过以下代码设置MediaSession

MediaSession.Callback callback = new MediaSession.Callback() {
  @Override
  public void onPlay() {
    // Handle the play button
  }
};
MediaSession mediaSession = new MediaSession(context,
  TAG); // Debugging tag, any string
mediaSession.setFlags(
  MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
  MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setCallback(callback);

// Set up what actions you support and the state of your player
mediaSession.setState(
  new PlaybackState.Builder()
    .setActions(PlaybackState.ACTION_PLAY |
                PlaybackState.ACTION_PAUSE |
                PlaybackState.ACTION_PLAY_PAUSE);
    .setState(PlaybackState.STATE_PLAYING,
      0, // playback position in milliseconds
      1.0); // playback speed

// Call this when you start playback after receiving audio focus
mediaSession.setActive(true);

如果您只想在您的 activity 可见时处理媒体按钮,您可以让 Activity 本身处理您的 MediaSession(这将允许您的 Callback 只是你的 Activity).

中的一个变量

Best practices in media playback talk from I/O 2016 goes through all of the details and other APIs required to build a great media app, although note that it uses MediaSessionCompat and the other Support Library classes as detailed in the Media playback and the Support Library blog post.