开发者

Issues with ACTION_HEADSET_PLUG broadcast in Android

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

}


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!


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.


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...

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜