问题 MediaButtonIntentReceiver无法在Android 4.0+中运行


目标是拦截来自耳机的广播以及最终的蓝牙,以响应来自耳机的不同类型的点击以改变媒体播放器。此解决方案适用于ICS之前的所有版本。这是我尝试过的一些代码和事情:

....
private BroadcastReceiver mediaButtonReceiver = new MediaButtonIntentReceiver();
....
public void onCreate() {
    ...
    IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
    mediaFilter.setPriority(2147483647); // this is bad...I know
    this.registerReceiver(mediaButtonReceiver, mediaFilter);
    ...
}

public class MediaButtonIntentReceiver extends BroadcastReceiver {

    private KeyEvent event;

    public MediaButtonIntentReceiver() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
            return;
        }
        event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
        if (event == null) {
            return;
        }
        try {
            int action = event.getAction();

            switch(action) {

                case KeyEvent.ACTION_UP :
                    Log.d("TEST", "BUTTON UP");
                    break;
                case KeyEvent.ACTION_DOWN :
                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE :
                    Log.d("TEST", "BUTTON DOWN");
                    break;
            }
        } catch (Exception e) {
            Log.d("TEST", "THIS IS NOT GOOD");
        }
        abortBroadcast();
    }
}

为了使这个工作,听起来像4.0+需要这样的东西,它没有工作:

((AudioManager)getSystemService(AUDIO_SERVICE)).registerMediaButtonEventReceiver(new ComponentName(this, MediaButtonIntentReceiver.class));

除了上面的内容之外,我甚至尝试将它添加到清单中:

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

仍然没有运气。我在这里想念的是什么?这肯定是4.0 + / ICS / JellyBean问题......这是在服务中完成的,而不是活动。


10550
2017-11-06 19:28


起源

我也发现这是Android核心的原因,但没有办法解决它: code.google.com/p/media-button-router/issues/detail?id=10#c4 - Du3


答案:


您的广播接收器看起来像是您服务的内部类别?如果是这样,请使您的广播接收器静止,并在清单中执行以下操作:

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

在Android 3.0+中你必须使用 registerMediaButtonEventReceiver 注册接收器。这使用AndroidManifest作为IntentFilter。它在2.x中工作的原因是因为你在注册它 this.registerReceiver() 注册接收器没有AndroidManifest。


10
2017-11-27 01:34



我使用内部类的唯一理由是能够访问外部类的方法,但如果内部类是静态的,我将无法访问这些方法。 赶上22。建议? - an00b
@ an00b我们使用Greenrobot的EventBus作为组件之间通信的简单方法(greenrobot.org/eventbus/documentation)。例如。 static BroadcastReceiver发布活动订阅的事件。非常适合脱钩 - Ben Clayton


试试果冻这对我有用:

             broadcastReceiver = new BroadcastReceiver() {//global BroadcastReceiver
            @Override
            public void onReceive(Context context, Intent intent) {

                String action = intent.getAction();
                if(action.equals("android.intent.action.MEDIA_BUTTON")){
                    Log.e("test", "ok");
                }
            };

意图:

        IntentFilter intentfilterTime = null;
        intentfilterTime = new IntentFilter();  
        intentfilterTime.addAction("android.intent.action.MEDIA_BUTTON");
        registerReceiver(broadcastReceiver, intentfilterTime);

使用Widgetsoid的媒体按钮(模拟BT媒体按钮)进行服务测试。一切正常。


1
2017-11-25 18:08



当我按住媒体按钮时,谷歌应用仍会接管它。我甚至为意图添加了最高优先级。我在onCreate函数中添加了你的snippit代码。还有其他我需要定义的地方,比如关于意图的清单吗?就像我说的,这在4.0之前的Android上运行良好 - Du3
你在真实设备上测试了吗?还是模拟器?我的代码不适合你吗?使用android 4.2在galaxy nexus上为我工作。通常意图是清单或代码,就像我给你的,但没有其他地方。 - jaumard
用4.1.1在Galaxy S3上测试。我已经尝试了以上所有内容。您的代码适用于2.3.6 - Du3
也许你有另一个具有高优先级的应用程序(比你的更多)获得事件,所以你永远不会拥有它。因为这个代码在android 4上对我有用。我只看到这种可能性...... - jaumard
我试过3个设备,所有类似的应用程序。我只是不认为寄存器正在工作。看一下这个: stackoverflow.com/questions/10537184/... - Du3