问题
I've tried these phones: Motorolla Backflip 1.5, Nexus One 2.1
Basically I register BroadcastReceiver to get ACTION_HEADSET_PLUG broadcast and look on 3 extras that come in intent:
- state
- name
- microphone
Here is the description from API:
* state - 0 for unplugged, 1 for plugged.
* name - Headset type, human readable string
* microphone - 1 if headset has a microphone, 0 otherwise
Issue #1: Broadcast comes when activity is started (not expected), when screen rotation happens (not expected) and when headset/headphones plugged/unplugged (expected).
Issue #2: Backflip phone (1.5) sends null for state + microphone, 'No Device' as name when headset/headphones unplugged, and sends null for state + microphone, 'Stereo HeadSet'/'Stereo HeadPhones' as name when headset/headphones plugged.
UPDATE: T-Mobile G1 with 1.6 behaves the same as Backflip phone.
Nexus even worse, it always sends null for state + microphone, 'Headset' as name when headset/headphones plugged or unplugged.
Question: How it can be explained that API is broken so much on both 1.5 and 2.1 versions and different devices, manufactures?
UPDATE:
Code in onCreate of main Activity:
// Register receiver
this.registerReceiver(new BroadcastsHandler(), new IntentFilter(Intent.ACTION_HEADSET_PLUG));
Now the code of BroadcastReceiver:
public class BroadcastsHandler extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_HEADSET_PLUG)) {
String data = intent.getDataString();
Bundle extraData = intent.getExtras();
String st = intent.getStringExtra("state");
String nm = intent.getStringExtra("name");
String mic = intent.getStringExtra("microphone");
String all = String.format("st=%s, nm=%s, mic=%s", st, nm, mic);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Headset broadcast");
builder.setMessage(all);
builder.setPositiveButton("Okey-dokey", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
}
}
回答1:
The code is wrong!
"state" and "microphone" is integer, not string. So the code should be modified as following:
int st = intent.getIntExtra("state" , -1);
String nm = intent.getStringExtra("name");
int mic = intent.getIntExtra("microphone", -1);
String all = "st="+Integer.toString(st)+" nm="+nm+" mic="+Integer.toString(mic);
It works!
回答2:
Broadcast comes when activity is started (not expected)
It's in the documentation of registerReceiver:
The system may broadcast Intents that are "sticky" -- these stay around after the broadcast as finished, to be sent to any later registrations. If your IntentFilter matches one of these sticky Intents, that Intent will be returned by this function and sent to your receiver as if it had just been broadcast.
My guess as to the reason would be that your Activity has a chance to get the current state for such "sticky" broadcasts right after you have registered for it.
I'm currently working on an app with 2 devices that need to receive ACTION_HEADSET_PLUG, and it seems there are devices that do not send this system broadcast (i'm not receiving it on my tablet, but am receiving it on my phone), so one could conclude that, after registering for this broadcast and it hasn't been received at least once, then the device doesn't support sending it. I haven't tested if this applies to other system broadcasts as well, but i would imagine so.
回答3:
Silly me, the problem is slightly different - 'state' and 'name' are there without 'microphone'. Another thing - 'state' is 0 and 1 for headphones, and 0 and 3 for headset. Super weird...
来源:https://stackoverflow.com/questions/2524923/issues-with-action-headset-plug-broadcast-in-android