How to Detect When a User Plugs Headset on Android Device? (Opposite of Action_Audio_Becoming_Noisy)

How to detect when a user plugs headset on android device? (Opposite of ACTION_AUDIO_BECOMING_NOISY)

How about this call:
http://developer.android.com/reference/android/content/Intent.html#ACTION_HEADSET_PLUG
which I found at
Droid Incredible Headphones Detection
?

The updated code I see in your question now isn't enough. That broadcast happens when the plugged state changes, and sometimes when it doesn't, according to Intent.ACTION_HEADSET_PLUG is received when activity starts so I would write:

package com.example.testmbr;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private MusicIntentReceiver myReceiver;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MusicIntentReceiver();
}

@Override public void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
registerReceiver(myReceiver, filter);
super.onResume();
}

private class MusicIntentReceiver extends BroadcastReceiver {
@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 is unplugged");
break;
case 1:
Log.d(TAG, "Headset is plugged");
break;
default:
Log.d(TAG, "I have no idea what the headset state is");
}
}
}
}

@Override public void onPause() {
unregisterReceiver(myReceiver);
super.onPause();
}
}

The AudioManager.isWiredHeadsetOn() call which I earlier recommended turns out to be deprecated since API 14, so I replaced it with extracting the state from the broadcast intent. It's possible that there could be multiple broadcasts for each plugging or unplugging, perhaps because of contact bounce in the connector.

Do something when a headset is plugged in when my app is running in the background. (if possible i want to do it with broadcast receivers)

Your code is correct, but as far as I know, you cannot put the HEADSET_PLUG filter on the manifest.
Instead, create a receiver in its own class, and make it listen for USER_PRESENT (screen unlocked) or BOOT_COMPLETED in the manifest:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>  
<receiver android:name="classes.myReceiver" >
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>

When triggered by such events, your receiver should start the service:

public class myReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent intent) {
Intent service = new Intent(ctx, VoiceLaunchService.class);
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)||intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
ctx.startService(service);
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
ctx.stopService(service);
}
}

The service will now register the receiver that will be listening to the HEADSET_PLUG intent, in its onCreate method:

@Override
public void onCreate() {
super.onCreate();
speechReconRx=new SpeechReconControlReceiver(this);//"this" will allow you to call service's methods from the receiver
registerReceiver(speechReconRx, new IntentFilter(Intent.HEADSET_PLUG));
}

It's is a hassle, but you'll need it if you don't want to use an activity.
It is google's fault for not letting us put PLUG receivers in the manifest! Finally make the Broadcast that will take action when the headset is plugged in.

public class SpeechReconControlReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent intent) {
Log.e("joshcsr","HEADSET PLUGGED!");
if(intent.getStringExtra("command")!=null){
c=intent.getStringExtra("command");
}
//run some methods from the service
if (c.equals("resume")) {
sService.resume();
}

if (c.equals("pause")) {
sService.pause();
}

if (c.equals("stop")) {
sService.stop();
}
}
}

To wrap, up you will need:
*A receiver for the BOOT/Screen unlock events.
*A Service to hold everything that will run on the background and to register your headset listening broadcast.
*And a receiver for the headset Plug, that will take action and call methods hosted in the service.

I've did this yesterday, and it works from Jelly bean to Lollipop ...and perhaps even older versions. Cheers.

Check whether headphones are plugged in

You can use this code for checking if the headset is plugged in

AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.isWiredHeadsetOn();

(Don't worry about the deprecation, it's still usable for ONLY checking if the headset are plugged in.)

And you need
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Available in Android 2.0 +

ACTION_AUDIO_BECOMING_NOISY not being captured

The NOISY filter gets triggered when audio output sources change, and might cause funky stuff.

The correct filter for headset plug should be:

IntentFilter commandFilter = new IntentFilter();
commandFilter.addAction(Intent.ACTION_HEADSET_PLUG);

The Manifest should read:

 <intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>

Intent.ACTION_HEADSET_PLUG is received when activity starts

Thanks for the reply Jake. I should have updated the original post to indicate that I discovered the issue that I was having. After a bit of research, I discovered that the ACTION_HEADSET_PLUG Intent is broadcast using the sendStickyBroadcast method in Context.

Sticky Intents are held by the system after being broadcast. That Intent will be caught whenever a new BroadcastReceiver is registered to receive it. It is triggered immediately after registration containing the last updated value. In the case of the headset, this is useful to be able to determine that the headset is already plugged in when you first register your receiver.

This is the code that I used to receive the ACTION_HEADSET_PLUG Intent:

 private boolean headsetConnected = false;

public void onReceive(Context context, Intent intent) {
if (intent.hasExtra("state")){
if (headsetConnected && intent.getIntExtra("state", 0) == 0){
headsetConnected = false;
if (isPlaying()){
stopStreaming();
}
} else if (!headsetConnected && intent.getIntExtra("state", 0) == 1){
headsetConnected = true;
}
}
}


Related Topics



Leave a reply



Submit