2012-11-06 27 views
11

Celem jest przechwycenie transmisji z zestawu słuchawkowego, a także ostatecznie bluetooth, aby reagować na różne typy kliknięć z zestawu słuchawkowego, aby zmienić odtwarzacz multimediów. To rozwiązanie działa dobrze we wszystkich wersjach przed ICS. Oto niektóre z kodu i rzeczy próbowałem:MediaButtonIntentReceiver nie działa w systemie Android 4.0+

.... 
private BroadcastReceiver mediaButtonReceiver = new MediaButtonIntentReceiver(); 
.... 
public void onCreate() { 
    ... 
    IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); 
    mediaFilter.setPriority(2147483647); // this is bad...I know 
    this.registerReceiver(mediaButtonReceiver, mediaFilter); 
    ... 
} 

public class MediaButtonIntentReceiver extends BroadcastReceiver { 

    private KeyEvent event; 

    public MediaButtonIntentReceiver() { 
     super(); 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     String intentAction = intent.getAction(); 
     if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) { 
      return; 
     } 
     event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 
     if (event == null) { 
      return; 
     } 
     try { 
      int action = event.getAction(); 

      switch(action) { 

       case KeyEvent.ACTION_UP : 
        Log.d("TEST", "BUTTON UP"); 
        break; 
       case KeyEvent.ACTION_DOWN : 
       case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE : 
        Log.d("TEST", "BUTTON DOWN"); 
        break; 
      } 
     } catch (Exception e) { 
      Log.d("TEST", "THIS IS NOT GOOD"); 
     } 
     abortBroadcast(); 
    } 
} 

spróbować do tej pracy, to brzmi jak wersji 4.0 lub nowszej wymaga czegoś takiego, który zrobił praca:

((AudioManager)getSystemService(AUDIO_SERVICE)).registerMediaButtonEventReceiver(new ComponentName(this, MediaButtonIntentReceiver.class)); 

Próbowałem nawet dodaj to do manifestu, oprócz powyższego:

<receiver android:name=".MediaButtonIntentReceiver" android:enabled="true"> 
     <intent-filter android:priority="2147483647" > 
      <action android:name="android.intent.action.MEDIA_BUTTON" /> 
     </intent-filter> 
    </receiver> 

Nadal nie ma szczęścia. Czego tu mi brakuje? Z pewnością jest to problem 4.0 +/ICS/JellyBean ... Robi się to w usłudze, a nie w działaniu.

+0

Też znalazłem to jako przyczynę w rdzeniu Androida, ale nie było sposobu na obejście tego: http://code.google.com/p/media-button-router/issues/detail?id=10#c4 – Du3

Odpowiedz

10

Wygląda na to, że twój odbiornik telewizyjny jest wewnętrzną klasą usług? Jeśli tak, sprawdź odbiornik transmisji statyczne i w manifeście to zrobić:

<receiver android:name="MyOuterClass$MediaButtonIntentReceiver" android:enabled="true"> 
    <intent-filter android:priority="2147483647" > 
     <action android:name="android.intent.action.MEDIA_BUTTON" /> 
    </intent-filter> 
</receiver> 

W Androidzie 3.0+ należy użyć registerMediaButtonEventReceiver zarejestrować słuchawkę. Używa AndroidManifest dla IntentFilter. Powodem, dla którego działa w wersji 2.x, jest rejestrowanie go pod numerem this.registerReceiver(), który zarejestrował odbiornik bez AndroidManifest.

+3

Jedynym usprawiedliwieniem dla mnie, gdy używam klasy wewnętrznej, jest możliwość uzyskania dostępu do metod klasy zewnętrznej, ale jeśli klasa wewnętrzna stanie się statyczna, nie będę mógł uzyskać dostępu do tych metod. [Catch 22] (http://stackoverflow.com/questions/15058743/how-do--register-in-manifest-an-inner-media-button-broadcastreciver#comment21174031_15058783). Sugestia? – an00b

+0

@ an00b Używamy EventBus Greenrobota jako prostego sposobu komunikacji między komponentami (http://greenrobot.org/eventbus/documentation/). Na przykład. static BroadcastReceiver wysyła zdarzenie, które subskrybuje aktywność. Doskonały do ​​rozłączenia –

1

Spróbuj na galaretki na to pracuje dla mnie:

   broadcastReceiver = new BroadcastReceiver() {//global BroadcastReceiver 
      @Override 
      public void onReceive(Context context, Intent intent) { 

       String action = intent.getAction(); 
       if(action.equals("android.intent.action.MEDIA_BUTTON")){ 
        Log.e("test", "ok"); 
       } 
      }; 

zamiar:

 IntentFilter intentfilterTime = null; 
     intentfilterTime = new IntentFilter(); 
     intentfilterTime.addAction("android.intent.action.MEDIA_BUTTON"); 
     registerReceiver(broadcastReceiver, intentfilterTime); 

test ze służby z przyciskiem mediów Widgetsoid (który emuluje BT przyciski multimedialne). Wszystko działa.

+0

Po naciśnięciu i przytrzymaniu przycisku multimediów aplikacje Google nadal go przejmują. Dodałem nawet maksymalny priorytet do intencji. Dodałem twój snippit kodu w funkcji onCreate. Czy są jakieś inne miejsca, które muszę zdefiniować, jak w manifeście dotyczącym intencji? Jak już mówiłem, działa to dobrze na Androidzie przed 4.0. – Du3

+0

Czy testowałeś na prawdziwym urządzeniu? lub emulator? Mój kod nie działa dla ciebie? Przyczyniaj się do pracy dla mnie na Nexusie Galaxy z Androidem 4.2. Zwykle intencjonalny jest zamanifestowany lub w kodzie, jak ci daję, ale nie ma innych miejsc. – jaumard

+0

Testowany na Galaxy S3 z 4.1.1. Próbowałem wszystkich powyższych. Twój kod działa na 2.3.6 – Du3

Powiązane problemy