Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I studied the ACTION_MEDIA_BUTTON intent and Im trying to use it and intercept the button presses and present them on screen using a toast. I registered the receiver to intercept two intents:

  1. ACTION_HEADSET_PLUG - plugging the headset

  2. ACTION_MEDIA_BUTTON - receiving the button presses

This is done in my main activity:

        IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
        mediaFilter.setPriority(10000);
        registerReceiver(_receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
        registerReceiver(_receiver, mediaFilter);

This is the part of the receiver that handles the button presses:

    if (action.equals(Intent.ACTION_HEADSET_PLUG))
    {
        Toast.makeText(context, "earphones activity",Toast.LENGTH_SHORT).show();
        if (intent.getExtras().getInt("state")==1)//if plugged
            Toast.makeText(context, "earphones plugged",Toast.LENGTH_LONG).show();
        else Toast.makeText(context, "earphones un-plugged",Toast.LENGTH_LONG).show();
    }
    else 
    if (action.equals(Intent.ACTION_MEDIA_BUTTON))
    {
        Toast.makeText(context, "button pressed",Toast.LENGTH_LONG).show();
        key=intent.getExtras().getString("EXTRA_KEY_EVENT");
        Toast.makeText(context, key,Toast.LENGTH_LONG).show();
    }

Now the part that handles the headset plug-in and removal works fine, but the part that intercept the button press isn't.

Is there any reason the code that handles the ACTION_MEDIA_BUTTON doesn't work?

Is there a special permission I need to intercept such an intent?

I'm using a Samsung Galaxy S2 to test the code.

I've looked at all the similar posts and tried everything. Unfortunately nothing seems to work.

like image 997
Gabriel H Avatar asked Jan 29 '12 21:01

Gabriel H


2 Answers

I recently developed an application which responded to the media button. I tested it in the Samsung Galaxy S II, and it worked.

First, in your AndroidManifest.xml, inside the <application> area, place the following:

<!-- Broadcast Receivers -->
<receiver android:name="net.work.box.controller.receivers.RemoteControlReceiver" >
    <intent-filter android:priority="1000000000000000" >
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

Then, create a BroadcastReceiver in a different file:

public class RemoteControlReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) {
            KeyEvent event = (KeyEvent) intent .getParcelableExtra(Intent.EXTRA_KEY_EVENT);

            if (event == null) {
                return;
            }

            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                context.sendBroadcast(new Intent(Intents.ACTION_PLAYER_PAUSE));
            }
        }
    }

}

This is probably not the best solution out there (specially the hard coded android:priority above). However, it tried a couple of other techniques and none of them seemed to work. So I have to resort to this one... I hope I helped.

like image 87
gnclmorais Avatar answered Oct 29 '22 14:10

gnclmorais


Thanks for contributing.

For all the others struggling here are the final conclusions :

After lots of blood tears I finally managed to realize that there are two types of broadcasts I can intercept: some like ACTION_HEADSET_PLUG are required to be registered in the activities code.

Others like ACTION_MEDIA_BUTTON are required to be registered in the Manifest file.

In this example to intercept both intents we require to do both.

Set it in the code and in the manifest file.

like image 25
Gabriel H Avatar answered Oct 29 '22 13:10

Gabriel H