2015-04-23 1 views
7

Modifier le 8 mai 2016contrôle WebView avec des événements discussion bloque les boutons des médias dans Android 5

J'ai trouvé la raison de mes problèmes recevoir des événements de bouton de médias dans mon application. Voir la réponse ci-dessous. J'édite le titre de cette question pour faciliter la recherche du problème. Le titre original était "Ce qui peut éventuellement bloquer les boutons des médias sur Android Lollipop".

question originale, Avril 2015:

Gratter la tête et regarder tout le code pour 2 jours en vain ... Mon application Android est censé réagir aux boutons de médias (par exemple à partir d'un casque, tester avec un casque Bluetooth), comme lire/pause, suivant, rembobiner. Fonctionne bien sur KitKat et ci-dessous. Je jure qu'il a même travaillé sur Lollipop jusqu'à il y a quelques jours. Maintenant rien, aucune trace qu'il entend des pressions sur les médias. Quelqu'un aurait-il une suggestion rapide où chercher le problème? Testé avec deux téléphones Lollipop, même casque Bluetooth, et le même casque fonctionne très bien pour les versions inférieures d'Android. En outre, le même casque fonctionne correctement, les boutons médiatiques peuvent être utilisés dans d'autres applications. Que pourrais-je casser?

J'ai maintenant testé les anciennes et les nouvelles façons d'écouter les boutons multimédia. En AndroidManifest.xml:

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

Le fait qu'il dit activé = « false » est OK - activer et désactiver le récepteur au besoin, et le MediaButtonIntentReceiver.java obtient les événements fines sur KitKat et bas, silence complet sur Lollipop. J'ai ensuite basculé vers la dernière application appcompat (v22.1) et essayé d'utiliser l'objet MediaSessionCompat et le code associé comme suit. Cela a très bien fonctionné dans une petite application de test, une seule activité que j'ai écrite - mes messages Logcat confirmant qu'elle entendait les touches multimédia sur Lollipop. Mais lorsqu'il est inséré dans mon application, encore une fois ne fonctionne pas sur Lollipop. Que diable???

private MediaSessionCompat _mediaSession; 
final String MEDIA_SESSION_TAG = "some_tag"; 

void initMediaSessions(Context context) { 
    // Start a new MediaSession 
    if (context == null) 
     return; 
    Lt.d("initMediaSession()..."); 
    ComponentName eventReceiver = new ComponentName(context.getPackageName(), MediaButtonIntentReceiver.class.getName()); 
    PendingIntent buttonReceiverIntent = PendingIntent.getBroadcast(
      context, 
      0, 
      new Intent(Intent.ACTION_MEDIA_BUTTON), 
      PendingIntent.FLAG_UPDATE_CURRENT 
    ); 

    // Parameters for new MediaSessionCompat(): 
    // context The context. 
    // tag A short name for debugging purposes. 
    // mediaButtonEventReceiver  The component name for your receiver. This must be non-null to support platform 
    // versions earlier than LOLLIPOP. May not be null below Lollipop. 
    // mbrIntent The PendingIntent for your receiver component that handles media button events. This is optional 
    // and will be used on JELLY_BEAN_MR2 and later instead of the component name. 
    _mediaSession = new MediaSessionCompat(context, MEDIA_SESSION_TAG, eventReceiver, buttonReceiverIntent); 
    _mediaSession.setCallback(new MediaSessionCallback()); 
    _mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | 
          MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 
    _mediaSession.setActive(true); 
    PlaybackStateCompat state = new PlaybackStateCompat.Builder() 
      .setActions(
        PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE | 
          PlaybackStateCompat.ACTION_PAUSE | 
          PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) 
      .setState(PlaybackStateCompat.STATE_STOPPED, 0, 1, SystemClock.elapsedRealtime()) 
      .build(); 
    _mediaSession.setPlaybackState(state); 
} 


final class MediaSessionCallback extends MediaSessionCompat.Callback { 
    @Override 
    public void onPlay() { 
     Lt.d("play"); 
    } 

    @Override 
    public void onPause() { 
     Lt.d("pause"); 
    } 

    @Override 
    public void onStop() { 
     Lt.d("stop."); 
    } 

    @Override 
    public void onSkipToNext() { 
     Lt.d("skipToNext"); 
    } 

    @Override 
    public void onSkipToPrevious() { 
     Lt.d("skipToPrevious"); 
    } 

    @Override 
    public boolean onMediaButtonEvent(final Intent mediaButtonIntent) { 
     Lt.d("GOT MediaButton EVENT"); 
     KeyEvent keyEvent = (KeyEvent) mediaButtonIntent.getExtras().get(Intent.EXTRA_KEY_EVENT); 
     // ...do something with keyEvent, super... does nothing. 
     return super.onMediaButtonEvent(mediaButtonIntent); 
    } 
} 
+0

Pouvez-vous vous assurer que votre .MediaButtonIntentReceiver est réellement activé? – cygery

+0

Oui, c'est, avoir un message de logcat là aussi et ça permet bien. Le même code exact fonctionne sur chaque version inférieure d'Android ... Et pour le nouveau code sur Lollipop avec l'objet MediaSessionCompat, le récepteur n'est pas nécessaire, peut être défini sur null. Je l'ai essayé de cette façon aussi (et mis en commentaire tout le code MediaButtonIntentReceiver), rien. Travaillé très bien avec des zéros dans la petite application de test ... – gregko

+0

Appareils sur lesquels vous testez? –

Répondre

2

8 mai 2016: Résolu sûr j'ai finalement trouvé la raison pour laquelle les boutons des médias ne fonctionnait pas avec mon application, lorsque l'écran principal était. Plus tard, j'ai remarqué qu'ils fonctionnaient si toute autre application était active, ou l'écran éteint, etc. - mais pas quand mon activité principale était en hausse. Il s'avère que dans Android 5 au moins, le contrôle WebView que j'utilise sur mon écran principal bloque les boutons des médias, s'il a le focus. Appel:

webView.setFocusable(false); 

ou

webView.setFocusableInTouchMode(false); 

ou le réglage de la même attribut dans la mise en page, résout le problème. Avec Android 6, le paramètre focalisable de WebView n'a pas d'importance pour la réception des événements de bouton multimédia.

24 avril 2015: Résolu? - pas tout à fait ... Du commentaire à ce poste: Handling media buttons in Android 5.0 Lollipop par @mangini:

Pour recevoir des événements de bouton de médias alors que votre activité est au premier plan, appel setMediaController() sur votre activité avec un MediaController instance connectée à votre MediaSession active.- Mangini 23 janvier à 18:35

je testais tout le temps avec écran et mon activité sur ouvert, comme il a toujours travaillé de cette façon dans les anciennes versions d'Android aussi ... Dès que je Appuyez sur le bouton d'accueil, ou éteint l'écran, mon ancien MediaButtonIntentReceiver a commencé à travailler normalement.

Mise à jour Les événements des boutons multimédias arrivent dans mon application uniquement si mon gestionnaire d'écran de verrouillage, utilisant RemoteControlClient déprécié, est activé et, bien sûr, mon activité n'est pas au premier plan. Si je désactive le gestionnaire d'écran de verrouillage (qui est une option dans mon application) et supprime RemoteControlClient, à nouveau, je ne peux obtenir aucun événement multimédia.

Ce problème sous Lollipop est un désordre complet. Ou au moins un désordre complet à ce sujet existe dans mon esprit en ce moment. Quelqu'un a posté un Souhait exemple de code clair pour le traitement des boutons de médias, qui travaillerait sous les anciennes versions d'Android et Lollipop ...

Greg

0

Pls remplacer la fonction return false.

@Override 
    public boolean dispatchKeyEvent(KeyEvent event) { 
     return false; 
    }