【问题标题】:Android: Handle headset buttons events and Send information to MainActivityAndroid:处理耳机按钮事件并将信息发送到 MainActivity
【发布时间】:2016-09-28 09:48:45
【问题描述】:

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

am.registerMediaButtonEventReceiver(RemoteControlReceiver); // Wrong

所以我查看了其他示例来更正代码。比如this question已经发布了很多秘密建议,我也尝试了this等其他代码,以及MediaSession的另一个解决方案,清理不需要的我写了这段代码:

我实现了类RemoteControlReceiver。显然不需要静态内部类,其实可以看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>

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

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

我正在努力

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

这里是我的问题:

  • 为什么不推荐使用 registerMediaButtonEventReceiver?现在似乎所有这些范式都是错误的,但我在 Android 开发者门户上没有找到有关如何处理此类问题的信息。
  • 我可以通过哪种方式与 MainActivity 交互?我的目的是在执行某些耳机操作后对 MainActivity 执行操作。

【问题讨论】:

  • 您的清单显示为MainActivity$MediaButtonReceiver,但您的课程名称为RemoteControlReceiver。是哪个?
  • 感谢@ianhanniballake 的提醒。虽然这只是一个复制粘贴错字,但我在所有实验中都实现了许多接收器。现在我更正了,我确认设置与描述的一样。

标签: android headset


【解决方案1】:

API 21 更改了整个媒体应用 API,现在完全以 MediaSession 为中心。您可以直接在MediaSession.Callback 中接收回调,而不是注册BroadcastReceiver(API 18 之前需要)或PendingIntent(通过registerMediaButtonEventReceiver(PendingIntent))。

您可以通过以下代码设置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 介绍了构建出色的媒体应用程序所需的所有细节和其他 API,但请注意,它使用 MediaSessionCompat 和其他支持库类,如 Media playback and the Support Library blog post 中所述。

【讨论】:

  • 就是这样@ianhanniballake,我想查找有关新的最佳实践的信息。所有附加的参考资料也将很有用。谢谢!
  • @ianhanniballake,如果我只想听按钮事件,而不播放任何媒体怎么办。有没有办法做到这一点?
  • 我也在寻找一种无需实际播放媒体即可收听按钮按下的方法。 (仅在应用可见时)。
  • 尝试了 Ian 的示例代码,它现在可以工作了。似乎我的 mediaSession 设置顺序错误。 (在 setActive 之前设置状态似乎很关键)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 2013-03-03
  • 2015-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多