MediaButtonIntentReceiver not working in Android 4.0+

The goal is to intercept broadcasts from the headset, as well as bluetooth eventually, to respond to different types of clicks from the headset to alter the mediaplayer. This solution works fine for all versions prior to ICS. Here is some of the code and things I have tried:

....
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();
    }
}

To try to make this work, it sounds like 4.0+ requires something like this which didnt work:

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

I even tried to add it to the manifest, in addition to the above:

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

Still no luck. What am I missing here? It's certainly a 4.0+/ICS/JellyBean issue... This is being done in a service, not an activity.


It looks like your broadcast receiver is an inner class to your service? If so, make your broadcast receiver static and in the manifest do this:

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

In Android 3.0+ you must use registerMediaButtonEventReceiver to register the receiver. This uses the AndroidManifest for the IntentFilter. The reason it works in 2.x is because you were registering it with this.registerReceiver() which registered the receiver without the AndroidManifest.


Just try on jelly on this is working for me :

             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");
                }
            };

Intent :

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

Test from service with media button of Widgetsoid (who emulate BT media buttons). All is working.