微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

始终接收所有Android媒体按钮事件的回调(即使其他应用正在播放音频)

背景信息:每当用户按下大多数耳机上的播放/暂停按钮时,我都需要检测(KEYCODE_MEDIA_PLAY_PAUSE).

我拥有它主要使用MediaSessions,但当另一个应用程序开始播放音频时,我停止回调.

这似乎是因为正在播放音频的应用创建了自己的MediaSession,而Android仅将KeyEvents发送到最新的MediaSession.为了防止这种情况,我创建一个OnActiveSessionsChangedListener并在每次触发时创建一个新的MediaSession.

这确实有效,但每次我创建一个新的MediaSession时,监听器再次触发,所以我发现自己陷入了一个inf循环.

我的问题:有谁知道我怎么做以下任何一个??:

>防止其他应用程序窃取我的媒体按钮焦点
>检测我何时将媒体按钮焦点丢失到另一个应用程序,这样我就可以创建一个新的MediaSession,而不是每当有效时
会议变了
>检查我当前是否已经有媒体按钮焦点,所以我不必要地创建一个新的MediaSession

什么行不通:

> broadcastReceiver on
AudioEffect.ACTION_OPEN_AUdio_EFFECT_CONTROL_SESSION不起作用
因为应用必须手动触发广播和许多应用,
像NPR一样不
> AudioManager.OnAudioFocuschangelistener无法正常工作,因为它需要我
音频焦点
>在android.intent.action.MEDIA_BUTTON&上具有最高优先级的broadcastReceiver调用abortbroadcast(),但当其他应用程序播放音频时,我的接收器未被触发.此外,其他应用程序也可以设置最高优先级.

我的代码

mMediaSessionManager.addOnActiveSessionsChangedListener(controllers -> {
    boolean updateButtonReceiver = false;

    // recreate MediaSession if another app handles media buttons
    for (MediaController mediaController : controllers) {
        if (!TextUtils.equals(getPackageName(),mediaController.getPackageName())) {
            if ((mediaController.getFlags() & (MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS)) != 0L) {
                updateButtonReceiver = true;
            }
        }

    }

    if (updateButtonReceiver) {
        // using a handler with a delay of about 2 seconds because this listener fires very often.
        mAudioFocusHandler.removeCallbacksAndMessages(null);
        mAudioFocusHandler.sendEmptyMessageDelayed(0,AUdio_FOCUS_DELAY_MS);
    }
},ClickAppNotificationListener.getComponentName(this));

这是被触发的处理程序:

private final Handler mAudioFocusHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (mShouldBeEnabled) {
            updateButtonReceiverEnabled(true);
        }
    }
};

最后,这是Handler触发的方法

private void updateButtonReceiverEnabled(boolean shouldBeEnabled) {
    // clear old session (not sure if this is necessary)
    if (mMediaSession != null) {
        mMediaSession.setActive(false);
        mMediaSession.setFlags(0);
        mMediaSession.setCallback(null);
        mMediaSession.release();
        mMediaSession = null;
    }

    mMediaSession = new MediaSessionCompat(this,MEDIA_SESSION_TAG);
    mMediaSession.setCallback(mMediaButtonCallback);
    mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    mMediaSession.setPlaybackToLocal(AudioManager.STREAM_MUSIC);
    mMediaSession.setActive(true);
    mMediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
            .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE)
            .setState(PlaybackStateCompat.STATE_CONNECTING,0f)
            .build());

    if (shouldBeEnabled != mShouldBeEnabled) {            
        getPackageManager().setComponentEnabledSetting(mMediaButtonComponent,shouldBeEnabled
                        ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                        : PackageManager.COMPONENT_ENABLED_STATE_disABLED,PackageManager.DONT_KILL_APP);
    }

    mShouldBeEnabled = shouldBeEnabled;
}

谢谢!

最佳答案
如果您只想捕获MediaButton,您可以注册broadcastReceiver以始终获取Media Button操作.

MediaButtonIntentReceiver类:

public class MediaButtonIntentReceiver extends broadcastReceiver {

  public MediaButtonIntentReceiver() {
    super();
    }

 @Override
 public void onReceive(Context context,Intent intent) {
     String intentAction = intent.getAction();
     if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
        return;
       }
     KeyEvent event =   (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
     if (event == null) {
        return;
       }
     int action = event.getAction();
     if (action == KeyEvent.ACTION_DOWN) {
          // do something
       Toast.makeText(context,"BUTTON pressed!",Toast.LENGTH_SHORT).show(); 
        }
    abortbroadcast();
  }
}

将其添加到manifest.xml:

并像这样注册你的BroadcastReceiver(在主要活动中)

IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
filter.setPriority(1000); 
registerReceiver(r,filter); 

还看看:

How to capture key events from bluetooth headset with android

How do I intercept button presses on the headset in Android?

原文地址:https://www.jb51.cc/android/430023.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐