如何对多个广播做出回应?Jelly Bean LG向一个活动发送了两个广播



我正在使用在服务中找到的一些工作代码,用于通过action_headset_plug检测耳机连接状态。我有两款用于测试的手机,一台摩托罗拉姜饼和一个果冻豆LG。在姜饼手机上,一切都很好...我插入耳机,然后从Android那里得到一个广播,然后我执行了工作。在果冻豆手机上,我会为每个耳机状态更改而获得两个(2)个广播,因此我自己的东西被称为两次。我不是100%确定的,但我认为这与粘性广播无关,好像是这种情况,我应该在姜饼和果冻手机上看到相同的行为。

在果冻豆手机上过滤所有系统logcat msgs for" headset_plug",我会在耳机状态更改上看到类似的东西:

02-01 07:39:11.983: I/MusicBrowser(1739): [MediaPlaybackService.java:mHeadsetReceiver.onReady()] oooooo intentIntent { act=android.intent.action.HEADSET_PLUG flg=0x40000010 (has extras) }
02-01 07:39:12.083: I/MusicBrowser(1739): [MediaPlaybackService.java:mHeadsetReceiver.onReady()] oooooo intentIntent { act=android.intent.action.HEADSET_PLUG flg=0x40000010 (has extras) }

我可能会误会,但一切似乎都在彼此之间的微秒内发送了两个广播,而摩托罗拉姜饼只发送了一张。我不知道这是否是一个Android错误,版本之间的故意更改,此特定LG手机的问题,或者什么是什么,但似乎我需要一种在多次发送同一广播时仅一次响应的方法。

我需要一种方法,仅在多次发送同一广播

时一次响应一次

如果您连续收到两个,三个或一百万个广播,其中state值与以前的广播没有更改,则该州没有更改。state更改时仅执行您的"状态已更改"逻辑,而不仅仅是因为您收到了广播。

您是否需要专用的boolean lastHeadsetState数据成员来检测状态的变化,或者可以从应用程序中的其他内容推断出最后一个状态,我不能说。

现在,理想情况下,您不需要这种逻辑,因为理想情况下,在状态变化时,广播只会出现一次。您离硬件越近,弹出的设备怪癖就越多。因此,鲁棒性原理在您离硬件越近更加重要。

以防万一任何人以后出现同样的问题...

我无法弄清楚如何使用该州的布尔值处理多个广播,但是我确实通过为状态设置整数来解决此问题。如果该服务收到了"插电"的多个广播,它将始终将int lastheadsettate设置为0。如果它收到了多个插入的广播,则第一个广播将将lastheadsettate设置为1,而其他广播将将lastheadsettate递增。恰好1,然后完成我的工作。除1以外的任何其他值都意味着收到了多个广播,应忽略。

因此,这是我的服务代码,用于听耳机插头/拔下插头状态的更改,忽略了启动服务时生成的初始粘性广播,并包含逻辑以容忍Wacky Hardware的多个广播。如果有人关心提出一种更优雅的方法来实现相同的结果,我会感兴趣。对于下面的任何格式错误表示歉意:

public class HeadsetService extends Service{
private static final String TAG = "HeadsetService";
private HeadsetReceiver hReceiver;
private int lastHeadsetState;
@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}
@Override
public void onCreate() {
    super.onCreate();       
    hReceiver = new HeadsetReceiver();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Register a new HeadsetReceiver       
    IntentFilter hfilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);    
    registerReceiver(hReceiver, hfilter);
return START_STICKY;}
 private class HeadsetReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
        // ignore the initial sticky broadcast when the service starts
        if (isInitialStickyBroadcast()) {
        } 
        else { 
        int state = intent.getIntExtra("state", -1);
        switch (state) {
        case 0:             
            Log.d(TAG, "headset unplugged");
            //set lastHeadsetState to 0 for later comparison
        lastHeadsetState = 0;               
            Log.d(TAG, "lastHeadsetState set to 0");
        break;
        case 1:                             
            Log.d(TAG, "headset plugged in!");
            lastHeadsetState = (lastHeadsetState + 1);
            Log.d(TAG, "lastHeadsetState incremented by 1");
            //check if lastHeadsetState is exactly 1...any greater value means multiple broadcasts were received.
            if (lastHeadsetState == 1) {
        //do whatever you're going to do when the headset is plugged in here                   
        Log.d(TAG, "Headset state has changed from unplugged to plugged");
            }
             else 
                 Log.d(TAG, "Multiple broadcasts received, ignoring duplicates");
        break; 
        default:
            Log.w("uh", "I have no idea what the headset state is");
            }   
          }
       }
     }
   }
 }

相关内容

最新更新