开发者

Detecting whether a headset is plugged into an Android device or not.

How can I det开发者_运维技巧ermine whether a headset is plugged into an Android device or not?


You can use the broadcast receiver.

So, You might write this code in "AndroidManifest.xml"

<receiver android:name="com.juno.brheadset.HeadsetStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.HEADSET_PLUG"/>
    </intent-filter>
</receiver>-->

But, This doesn't work. When OS send this "HEADSET_PLUG" intent, OS set the flag "Intent.FLAG_RECEIVER_REGISTERED_ONLY" So, You should write the code like below in Activity or Service class instead of "AndroidManifest" things.

public class BRHeadsetActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    HeadsetStateReceiver receiver = new HeadsetStateReceiver();
    registerReceiver( receiver, receiverFilter );


}

I hope this article help you. Bye!

This is the part of "HeadsetObserver.java", Android SDK Source.

private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
    if ((headsetState & headset) != (prevHeadsetState & headset)) {
        //  Pack up the values and broadcast them to everyone
        Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);

        **intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);**

        int state = 0;
        int microphone = 0;

        if ((headset & HEADSETS_WITH_MIC) != 0) {
            microphone = 1;
        }
        if ((headsetState & headset) != 0) {
            state = 1;
        }
        intent.putExtra("state", state);
        intent.putExtra("name", headsetName);
        intent.putExtra("microphone", microphone);

        if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
        // TODO: Should we require a permission?
        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }
}


When you say "headset", do you mean "wired headset"? If so, there's an intent to detect whether or not one is being plugged or unplugged: ACTION_HEADSET_PLUG.

To check the status, you can use AudioManager.isWiredHeadsetOn(), although that may return false if there is also a bluetooth headset, and audio is routed to that instead.


AudioManager.isWiredHeadsetOn() always return false because it requires user-permission MODIFY_AUDIO_SETTINGS.

I spent several days while found answer. There are no info about this in official documentation. And this bug already registered in BugTracker.


This should help you : http://developer.android.com/reference/android/content/Intent.html#ACTION_HEADSET_PLUG


You can create this kind of receiver class (Kotlin with Flow) in your project:

class HeadsetPlugReceiver : BroadcastReceiver() {

    private val _isPlugged = MutableStateFlow<Boolean>(false)
    val isPlugged: StateFlow<Boolean> = _isPlugged.asStateFlow()

    override fun onReceive(context: Context, intent: Intent) {
        context.appComponent.inject(this)
        val action = intent.action
        Log.i(TAG, "onReceive: $action")
        when (action) {
            Intent.ACTION_HEADSET_PLUG -> sendEvent(intent)
            else -> checkStateOff(intent)
        }
    }

    private fun checkStateOff(intent: Intent) {
       Log.i(TAG, "onReceive: the local Bluetooth adapter is off")
    }

    private fun sendEvent(intent: Intent) {
        val isPlugged = intent.getIntExtra(HEADSET_STATE, 0) == 1
        Log.i(TAG, "sendEvent: $isPlugged")
        _isPlugged.value = isPlugged
    }

    private companion object {

       private const val TAG = "HeadsetPlugReceiver"
       // Headset constant
       private const val HEADSET_STATE = "state"
    }
}

then register this receiver in some class with context:

val headsetReceiver = HeadsetPlugReceiver()
val headsetFilter = IntentFilter(Intent.ACTION_HEADSET_PLUG)
    context.registerReceiver(headsetReceiver, headsetFilter)

then collect isPlugged and you get the state of your wire headset connecting state

PS: don't forget to unregister your receiver when it no needs context.unregisterReceiver(headsetReceiver)


First , create receiver in your manifest:

    <receiver android:name="com.yourapplication.BroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.HEADSET_PLUG"/>
        </intent-filter>
    </receiver>

don't forget to change com.yourapplication according to your project name

Create two variables in the head of your activity :

private  BroadcastReceiver mReceiver  ;
boolean Microphone_Plugged_in = false;

Define your receiver inside onCreate of your activity :

        mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            int iii=2;
            if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
                iii=intent.getIntExtra("state", -1);
                if(Integer.valueOf(iii)==0){
                    Microphone_Plugged_in = false;
                    Toast.makeText(getApplicationContext(),"microphone not plugged in",Toast.LENGTH_LONG).show();
                }if(Integer.valueOf(iii)==1){
                    Microphone_Plugged_in = true;
                    Toast.makeText(getApplicationContext(),"microphone plugged in",Toast.LENGTH_LONG).show();
                }
            }
        }};
        IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
        registerReceiver( mReceiver, receiverFilter );

add onResume and onStope :

@Override
  protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    getApplicationContext().registerReceiver(mReceiver, filter);
}

@Override
protected void onStop() {
    super.onStop();
    getApplicationContext().unregisterReceiver(mReceiver);
}


To add to the other answers, from Android documentation:

Warning: Limit how many broadcast receivers you set in your app. Having too many broadcast receivers can affect your app's performance and the battery life of users' devices. For more information about APIs you can use instead of the BroadcastReceiver class for scheduling background work, see Background Optimizations.

https://developer.android.com/guide/topics/manifest/receiver-element

Which means that you should create a small number of broadcast receivers as possible, to prevent memory issues with your app.

I will suggest using a singleton class with this receiver. In Kotlin:

class HeadsetReceiver private constructor(): BroadcastReceiver() {

    // instances
    var callback: HeadsetReceiverCallback? = null

    //region singleton
    private object HOLDER {
        val INSTANCE = HeadsetReceiver()
    }

    companion object {
        val instance: HeadsetReceiver by lazy { HOLDER.INSTANCE }
    }
    //endregion

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_HEADSET_PLUG) {
            if(intent.getIntExtra("state", -1) == 0) {
                callback?.onHeadsetDisconnected()
            } else {
                callback?.onHeadsetConnected()
            }
        }
    }

    fun register(context: Context) {
        val receiverFilter = IntentFilter(Intent.ACTION_HEADSET_PLUG)
        context.registerReceiver(this, receiverFilter)
    }

    fun unregister(context: Context) {
        context.unregisterReceiver(this)
        callback = null
    }

    interface HeadsetReceiverCallback {
        fun onHeadsetConnected()
        fun onHeadsetDisconnected()
    }
}

Register:

HeadsetReceiver.instance.register(context)
        HeadsetReceiver.instance.callback = object : HeadsetReceiver.HeadsetReceiverCallback {
            override fun onHeadsetConnected() {
                println("connected!")
            }

            override fun onHeadsetDisconnected() {
                println("disonnected!")
            }
        }

Unregister:

HeadsetReceiver.instance.unregister(context)
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜