2013-03-01 16 views
20

mam ten odbiornik do transmisji ACTION_MEDIA_BUTTON który faktycznie działa zarówno Android 2.x oraz Androida 4.1, ale z jakiegoś dziwnego powodu, na Android 2.x (tylko), otrzymuję każdego nawet dwukrotnie (dla jednym kliknięciem na przycisk pauzy, oczywiście):KeyEvent.ACTION_UP wystrzelił dwukrotnie ACTION_MEDIA_BUTTON

public class RemoteControlReceiver extends BroadcastReceiver { 
    private static long prevEventTime = 0; 

    @Override 
    public void onReceive(Context ctx, Intent intent) { 
    if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { 
     KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 
     long curEventTime = event.getEventTime(); 
     if (event != null && (event.getAction() == KeyEvent.ACTION_UP) /*&& (curEventTime != prevEventTime)*/) { 
     int keycode = event.getKeyCode(); 
     switch (keycode) 
     { 
      case KeyEvent.KEYCODE_MEDIA_NEXT: 
      Log.i(TAG, "KEYCODE_MEDIA_NEXT"); 
      break; 
      case KeyEvent.KEYCODE_HEADSETHOOK: 
      Log.i(TAG, "KEYCODE_HEADSETHOOK" + " " + curEventTime + " <> " + prevEventTime + " (" + event.getAction() + ")"); 
      prevEventTime = curEventTime; 
      break; 
      case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 
      Log.i(TAG, "KEYCODE_MEDIA_PREVIOUS"); 
      break; 
      default: 
     } 
     }  
    } 
    } 

} 

próbując zrozumieć tajemnicę, loguję czas zdarzenia dla każdego takiego zdarzenia:

03-01 18:27:05.264: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142304436 <> 0 (1) 
03-01 18:27:05.434: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142304436 <> 142304436 (1) 

03-01 18:27:14.054: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142313265 <> 142304436 (1) 
03-01 18:27:14.074: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142313265 <> 142313265 (1) 

03-01 18:27:24.254: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142323464 <> 142313265 (1) 
03-01 18:27:24.264: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142323464 <> 142323464 (1) 

03-01 18:27:37.574: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142336795 <> 142323464 (1) 
03-01 18:27:37.614: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142336795 <> 142336795 (1) 

03-01 18:27:45.214: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142344433 <> 142336795 (1) 
03-01 18:27:45.284: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142344433 <> 142344433 (1) 

03-01 18:27:52.474: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142351687 <> 142344433 (1) 
03-01 18:27:52.504: I/RemoteControlReceiver.onReceive(22377): KEYCODE_HEADSETHOOK 142351687 <> 142351687 (1) 

Ponownie, to podwójne wystąpienie nie występuje w systemie Android 4.1. Dzieje się tak tylko w systemie Android 2.x.

Każdy pomysł dlaczego?

(podczas gdy mogę użyć tej samej techniki rejestrowania czasu zdarzenia, aby odfiltrować drugie wystąpienie, wolę najpierw zrozumieć, co się dzieje (możliwe błędy w programowaniu po mojej stronie?) I sprawdzić, czy istnieje lepsze rozwiązanie dla że)


Odpowiadając na poniższe pytanie: ("jak dokładnie zarejestrować swój odbiornik")

pierwszy w aplikacji manifeście:

<receiver android:name="com.example.mylib.RemoteControlReceiver" android:enabled="true"> 
    <intent-filter android:priority="2147483647" > 
     <action android:name="android.intent.action.MEDIA_BUTTON" /> 
    </intent-filter> 
</receiver> 

Następnie w mojej działalności biblioteki (za this tip), w onCreate():

mRemoteControlReceiver = new ComponentName(this, RemoteControlReceiver.class); 
mAudioManager.registerMediaButtonEventReceiver(mRemoteControlReceiver); 

Mam nadzieję, że to daje pełniejszy obraz, który może pomóc rozwiązać tę tajemnicę.

+0

Jak dokładnie rejestrujesz swój odbiornik? – clover

+0

Teraz nie mogę edytować mojego tekstu nagrody (żałosnego). Przez "Nie używam żadnej biblioteki" Chodzi mi o to, że nie mam więcej niż aplikacji rejestrującej tego samego słuchacza. – matteo

Odpowiedz

8

Zauważyłem, że używasz tego odbiornika w bibliotece (część "mylib" w twoim manifeście).

Jeśli jest to rzeczywiście sprawa i masz tego odbiornika zarejestrowany przez dwa aplikacji korzystających z tego samego kodu rejestracyjnego, widać te wydarzenia dwukrotnie.

Jeśli trzy wnioski zarejestrować tego odbiornika, będziesz otrzymywać te wydarzenia trzykrotnie ...

upewnić się, że każda aplikacja wykorzystuje inny (unikalny) <receiver android:name.

+0

Po raz kolejny trafiłeś prosto na cel (gra słów nie przeznaczona :)) – an00b

+0

Nie moja sprawa, i obserwuję problem. Mam tylko filtr zdefiniowany w manifeście. Dzieje się tak tylko w systemie Android 2.x. Jest to oczywiście błąd, ponieważ zweryfikowałem, że mój własny odbiornik jest instancjonowany i uruchamiany dwa razy (dwa razy dla UP i dwa razy dla DOWN) i jest zarejestrowany tylko jeden (sprawdzany przez PackageManager.queryBroadcastReceivers. Czy obejście tego problemu sprawdza wiarygodność czasu i Czy to jest jedyne? – matteo

0

Aby zapewnić, że po raz pierwszy zawsze można użyć flagi, aby powiedzieć, że jest to pierwsza czynność.

boolean firstAction= false; 
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { 
    firstAction= !firstAction; 
    if(!firstAction) 
    { 
     return true; 
    } 

    KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 
    long curEventTime = event.getEventTime(); 
    if (event != null && (event.getAction() == KeyEvent.ACTION_UP) /*&& (curEventTime != prevEventTime)*/) { 
     int keycode = event.getKeyCode(); 
     switch (keycode) 
     { 
      case KeyEvent.KEYCODE_MEDIA_NEXT: 
      Log.i(TAG, "KEYCODE_MEDIA_NEXT"); 
      break; 
      case KeyEvent.KEYCODE_HEADSETHOOK: 
      Log.i(TAG, "KEYCODE_HEADSETHOOK" + " " + curEventTime + " <> " + prevEventTime + " (" + event.getAction() + ")"); 
      prevEventTime = curEventTime; 
      break; 
      case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 
      Log.i(TAG, "KEYCODE_MEDIA_PREVIOUS"); 
      break; 
      default: 
     } 
    }  
} 
+0

Zanotuj skomentowane '/ * && (curEventTime! = PrevEventTime) * /' w moim oryginalnym kodzie: Działa to już wokół problemu opisanego powyżej. Pytałem: dlaczego tak się dzieje, a nie jak rozwiązać problem. Dzięki za próbę pomocy. :) – an00b

6

Natknąłem się na ten problem i spędziłem chwilę waląc głową w ścianę, zanim zdałem sobie sprawę, że każde naciśnięcie przycisku generuje dwa zdarzenia: KeyEvent.ACTION_DOWN i KeyEvent.ACTION_UP.Więc dwa testy są potrzebne, aby użyć przycisku multimedialnego:

if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {} 

i

if (event.getAction() == KeyEvent.ACTION_DOWN) {} 

więc jeśli ktoś znajdzie się tutaj w wyniku tego samego błędu, być może ta odpowiedź pomoże.

+1

To rozwiązało to dla mnie Wydaje się to oczywiste teraz, ale wcześniej o tym nie myślałem Dzięki – SteveEdson

+0

To była magia ... Ugh! Przeczytałem to nawet raz i pomyślałem, że to nie problem. Dzięki! –