2014-02-01 1 views
0

Я использую какой-то рабочий код, который я нашел here в службе для обнаружения состояния подключения наушников через ACTION_HEADSET_PLUG. У меня есть два телефона для тестирования, Gingerbread Motorola и Jelly Bean LG. На телефоне Gingerbread все отлично работает ... я подключаю наушники, и я получаю одну трансляцию от Android, а затем выполняю свою работу. На телефоне Jelly Bean я получаю две (2) трансляции для каждого изменения состояния наушников, и поэтому мои собственные вещи затем вызывают дважды. Я не уверен на 100%, но я не думаю, что это связано с липкими трансляциями, как если бы это было так, я должен видеть то же поведение на телефонах Gingerbread и Jellybean.Как реагировать один раз на несколько передач? Jelly Bean LG отправляет две трансляции для одного события

Фильтрация всей системы LogCat сбщ для «headset_plug» по телефону Jelly Bean я увидеть что-то вроде этого на изменение гарнитуры состояния:

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

я мог ошибиться, но, все кажется, как этот телефон посылает два вещания в микросекундах друг друга, тогда как Gingerbread Motorola отправляет только один. Я не знаю, является ли это ошибкой Android, преднамеренным изменением между версиями, проблемой с этим конкретным телефоном LG или тем, что мне кажется, мне нужен способ ответить только один раз, когда одна и та же передача отправляется несколько раз.

+0

Просмотрели ли вы дополнительные функции на этих «намерениях», чтобы узнать, есть ли различия? – CommonsWare

+0

Мое предположение - это дополнительные, идентичные, потому что результаты идентичны.В связанном коде выше он фильтрует «состояние» дополнительно в операторе switch, а журналы подключаются (состояние 1) и отключается (состояние 0). На телефоне Jelly Bean я получаю ровно два подключенных или два отключенных сообщения журнала. Если дополнительные параметры были разными, я должен получить два разных журнала или игнорировать дополнительные функции, если они не соответствуют типу «состояние». –

ответ

0

Только в случае, если кто приходит позже ж/с той же проблемой ...

Я не мог понять, как иметь дело с несколькими передач с помощью логических значений для государства, но я решить эту проблему, установив число для штат. Если услуга получает несколько широковещательных сообщений для «отключенной», она всегда устанавливает значение int lastHeadsetState равным 0. Если он получает несколько широковещательных сообщений для подключения первой широковещательной передачи, будет установлено значение lastHeadsetState равным 1, а дополнительные трансляции будут увеличивать значение lastHeadsetState на 1. Затем я проверяю, будет ли lastHeadsetState равным ровно 1, а затем выполните мою работу. Любое значение, отличное от 1, подразумевает получение нескольких передач и их следует игнорировать.

Итак, вот мой код для обслуживания, который прослушивает изменения состояния штепселя для наушников/отключает его, игнорирует начальные липкие трансляции, сгенерированные при запуске службы, и содержит логику, позволяющую переносить несколько широковещательных сообщений с пустых аппаратных средств. Если кто-то хочет предложить более элегантный способ добиться того же результата, мне было бы интересно. Извините, для получения каких-либо ошибок при форматировании ниже:

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"); 
      } 
      } 
     } 
    } 
    } 
} 
1

Мне нужен способ, чтобы ответить только один раз, когда тот же широковещательный отправляется несколько раз

Если вы получаете два, три, или миллион передач подряд, где значение state не имеет измененный с предыдущей трансляции, состояние не изменилось. Только измените логику «состояние изменилось», когда изменяется state, а не только потому, что вы получили трансляцию.

Независимо от того, нужен ли вам специальный элемент данных boolean lastHeadsetState для определения изменения состояния или может сделать вывод о последнем состоянии из других вещей в вашем приложении, я не могу сказать.

Теперь, в идеале, вам не нужна эта логика, так как в идеале трансляция будет выходить только один раз, после изменения состояния. Чем ближе вы подключаетесь к аппаратным средствам, тем больше проявляется причуды устройства. Следовательно, robustness principle тем более важно, что вы ближе к аппаратным средствам.

+0

Благодарим вас за предложения. Я прочитаю об изменении этого широковещательного приемника, чтобы работать только на изменениях штата, а не на отдельных передачах, и публиковать его здесь, если я что-то получаю. Наверное, меня просто немного бросили, потому что каждый указывает на некоторые вариации этого кода здесь всякий раз, когда появляется тема обнаружения гарнитуры, но я не мог найти никого, кто спрашивал, что делать в случае нескольких идентичных передач. Если это конкретная модель, мне интересно, что LG сделала бы с изображением Android, чтобы запускать несколько трансляций. –

+0

@CharlieNS: «Если это конкретная модель, я задаюсь вопросом, что LG сделала бы с изображением Android, чтобы запускать несколько трансляций», - наверняка прикрутил. Если вы считаете, что это беспорядочно, попробуйте некоторое время работать с камерой ... :-) – CommonsWare

+0

Еще раз спасибо за ваш совет. Это поставило меня на правильный путь к решению, которое я добавил к моему первоначальному вопросу. –

Смежные вопросы