WebView control with focus blocks media button events in Android 5

Edit May 8, 2016

I found the cause of my problems receiving events with media buttons in my application. See answer below. I am editing the title of this question to make it easier to find the problem. Original title: "What can block media buttons on Android Lollipop."

Original Question, April 2015:

Having scratched my head and looking at the entire code for 2 days to no avail ... My Android application should respond to multimedia buttons (for example, from the headset, check it using the Bluetooth headset), for example, play / pause, then rewind. Works great on KitKat and below. I swear that he even worked for Lollipop, and until a few days ago. Now nothing, no traces that he hears at the touch of a button media buttons. Does anyone have a quick suggestion where to look for problems? Tested with two Lollipop phones, one Bluetooth headset and the same headset, great for lower versions of Android. The same headset also works great, multimedia buttons are audible in other applications. What maybe I can break?

Now I have tested both old and new ways to listen to media buttons. In AndroidManifest.xml:

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

The fact that he says enabled = "false" is fine: I turn the receiver on and off as needed, and MediaButtonIntentReceiver.java perfectly transmits events to KitKat and below, complete silence to Lollipop.

Then I switched to the last appcompat (v22.1) and tried to use the MediaSessionCompat object and the corresponding code as follows. This did a great job in a small test application, just one action I wrote - I received my Logcat messages confirming that it hears multimedia keys pressed on Lollipop. But when it is inserted into my application, it again does not work on Lollipop. What the hell???

 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); } } 
+7
android android-5.0-lollipop
source share
2 answers

May 8, 2016. Certainly solved. Finally, I found the reason the media buttons did not work with my application when the main screen was turned on. Later I noticed that they worked if some other application was active, or the screen was turned off, etc., But not when my main activity was. It turns out that in Android 5, at least the WebView control that I use on the main screen blocks the multimedia buttons if it has focus. Vocation:

 webView.setFocusable(false); 

or

 webView.setFocusableInTouchMode(false); 

or setting the same attribute in the layout solves the problem. With Android 6, the custom WebView setting didn't matter for receiving media button events.

April 24, 2015: Resolved? - not really ... From the comment on this post: Control media buttons in Android 5.0 Lollipop from @mangini:

To receive events with media buttons when your activity is in the foreground, call setMediaController () in your activity using the MediaController instance associated with your active MediaSession. - mangini Jan 23 at 18:35

I tested the screen all the time, and my activity opened on it, because it always worked that way in older versions of Android ... As soon as I pressed the home button or turned off the screen, the old MediaButtonIntentReceiver started working fine.

Refresh Events with media buttons come into my application only if my screen lock manager using the cushioned RemoteControlClient is turned on, and, of course, my activity is not in the foreground. If I turn off the screen lock manager (which is an option in my application) and delete RemoteControlClient, again, I cannot get any media events.

This problem under Lollipop is a complete mess. Or at least a complete mess in it exists in my mind right now. Wish someone posted a clear code sample for handling multimedia buttons that would work on older versions of Android, and Lollipop ...

Greg

+2
source share

Pls overrides the return false function.

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

All Articles