How do I detect that the headset has been plugged in?

Asked

Viewed 88 times

7

I’ve been watching that every time I "plug" the headset in my smarphone, a notification from Deezer (a stream music) already telling to click and to open the application.

According to the documentation that talks about the ACTION_HEADSET_PLUG, they recommend using the Audiomanager if the minimum version of the SDK is Lollipop.

It is necessary to create a <receiver> to perform this procedure? How do I check the status of headset or detect if it was "plugged in"?

2 answers

5


Yes, it is necessary to create a Broadcastreceiver but it must be registered explicitly, through Context.registerReceiver(), and not merely stated in Androidmanifest.xml.

In relation to ACTION_HEADSET_PLUG, what the documentation says is that if the minimum SDK version is Lollipop, you should use the constant AudioManager.ACTION_HEADSET_PLUG instead of Intent.ACTION_HEADSET_PLUG.(1)

To know the status of the headset check, in the method onReceive() of the Broadcastreceiver, the key state of Extra do Intent.

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
        int state = intent.getIntExtra("state", -1);
        switch(state) {
            case(0):
                Log.d(TAG, "Headset unplugged");
                break;
            case(1):
                Log.d(TAG, "Headset plugged");
                break;
            default:
                Log.d(TAG, "Headset state invalid");
        }
    }
}

(1) I do not understand why, since in both it is said that its value is android.intent.action.HEADSET_PLUG.

  • Because intent.getIntExtra("state", -1) even?

  • The methods getXXXExtra() receive in the 2nd parameter a value to be used/returned if the key does not exist.

1

Just out of curiosity and to complement the response of the ramaral, which is excellent.

There is the possibility to use the Awareness API to detect, when the headset is plugged in and at the same time know if you currently have a headset plugged in.

To get the headset status snapshot (just by placing the important part):

Awareness.SnapshotApi.getHeadphoneState(mGoogleApiClient)
                .setResultCallback(new ResultCallback<HeadphoneStateResult>() {
                    @Override
                    public void onResult(@NonNull HeadphoneStateResult headphoneStateResult) {
                        if (!headphoneStateResult.getStatus().isSuccess()) {
                            Log.e(TAG, "Could not get headphone state.");
                            return;
                        }
                        HeadphoneState headphoneState = headphoneStateResult.getHeadphoneState();
                        if (headphoneState.getState() == HeadphoneState.PLUGGED_IN) {
                            Log.i(TAG, "Headphones are plugged in.\n");
                        } else {
                            Log.i(TAG, "Headphones are NOT plugged in.\n");
                        }
                    }
                });

This example is in the documentation itself: Get headphone state

And to be notified, using the Fences API:

// Declare variables for pending intent and fence receiver.
private PendingIntent myPendingIntent;
private MyFenceReceiver myFenceReceiver;

// Initialize myPendingIntent and fence receiver in onCreate().
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    Intent intent = new Intent(FENCE_RECEIVER_ACTION);
    myPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
    MyFenceReceiver = new myFenceReceiver();
    registerReceiver(myFenceReceiver, new IntentFilter(FENCE_RECEIVER_ACTION));
    ...
}

// Create a fence.
AwarenessFence headphoneFence = HeadphoneFence.during(HeadphoneState.PLUGGED_IN);

// Register the fence to receive callbacks.
// The fence key uniquely identifies the fence.
Awareness.FenceApi.updateFences(
        mGoogleApiClient,
        new FenceUpdateRequest.Builder()
            .addFence("headphoneFenceKey", headphoneFence, myPendingIntent)
            .build())
        .setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(@NonNull Status status) {
                if (status.isSuccess()) {
                    Log.i(TAG, "Fence was successfully registered.");
                } else {
                    Log.e(TAG, "Fence could not be registered: " + status);
                }
            }
        });

// Handle the callback on the Intent.
public class MyFenceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        FenceState fenceState = FenceState.extract(intent);

        if (TextUtils.equals(fenceState.getFenceKey(), "headphoneFenceKey")) {
            switch(fenceState.getCurrentState()) {
                case FenceState.TRUE:
                    Log.i(TAG, "Headphones are plugged in.");
                    break;
                case FenceState.FALSE:
                    Log.i(TAG, "Headphones are NOT plugged in.");
                    break;
                case FenceState.UNKNOWN:
                    Log.i(TAG, "The headphone fence is in an unknown state.");
                    break;
            }
        }
    }
}

As I said, they are different ways of solving the same problem. But in fact the Fences API requires a little more Boilerplate. But you have the possibility to consult Snapshot simply.

The great advantage in my opinion is the possibility to combine states.

  • I want to be notified when the user is with the phone and also with the mobile charging, so I can suggest an action X.

  • I want to be notified when the user has the headset plugged in and is running, may I suggest his racing playlist.

Doing this using only the framework’s Apis is much harder.

  • 2

    Good, I didn’t know that possibility.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.