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)
精彩评论