开发者

Intent.ACTION_HEADSET_PLUG is received when activity starts

开发者 https://www.devze.com 2023-01-23 15:39 出处:网络
I am trying to pause music that is playing when the headset is unplugged. I have created a BroadcastReceiver that listens for ACTION_HEADSET_PLUG intents and acts upon th开发者_开发问答em when the s

I am trying to pause music that is playing when the headset is unplugged.

I have created a BroadcastReceiver that listens for ACTION_HEADSET_PLUG intents and acts upon th开发者_开发问答em when the state extra is 0 (for unplugged). My problem is that an ACTION_HEADSET_PLUG intent is received by my BroadcastReceiver whenever the activity is started. This is not the behavior that I would expect. I would expect the Intent to be fired only when the headset is plugged in or unplugged.

Is there a reason that the ACTION_HEADSET_PLUG Intent is caught immediately after registering a receiver with that IntentFilter? Is there a clear way that I can work with this issue?

I would assume that since the default music player implements similar functionality when the headset is unplugged that it would be possible.

What am I missing?

This is the registration code

registerReceiver(new HeadsetConnectionReceiver(), 
                 new IntentFilter(Intent.ACTION_HEADSET_PLUG));

This is the definition of HeadsetConnectionReceiver

public class HeadsetConnectionReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        Log.w(TAG, "ACTION_HEADSET_PLUG Intent received");
    }

}


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


I use a different approach to stop playback when headset is unplug. I do not want you to use it since you are already fine, but some other people may find it useful. If you get control of audio focus, then Android will send you an event audio becoming noisy, so if you write a receiver for this event it will look like

 public void onReceive(Context context, Intent intent) {
if  (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) { 
       if (isPlaying()){
            stopStreaming();
        }
    }
 }


I ran into the same issue. I'm not sure what causes it, but at least in my testing it seems to be consistent, which means you can work around it. I did just that by adding a boolean member variable that starts as true, and is set to false on the first onReceive(Context, Intent) call. This flag then controls whether I actually process the unplug event or not.

For your reference, here is the code I use to do just that, which is available in context here.

private boolean isFirst;

public void onReceive(Context context, Intent intent)
{
    if(!isFirst)
    {
        // Do stuff...
    }
    else
    {
        Log.d("Hearing Saver", "First run receieved.");
        isFirst = false;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消