Элемент управления WebView с фокусом блокирует события медиа-кнопок в Android 5
Редактировать 8 мая 2016 г.
Я нашел причину своих проблем с получением событий мультимедийных кнопок в моем приложении. Смотрите ответ ниже. Я отредактировал название этого вопроса, чтобы облегчить поиск проблемы. Первоначальное название было "Что может блокировать мультимедийные кнопки на Android Lollipop".
Оригинальный вопрос, апрель 2015 года:
Почесывая голову и глядя на весь код в течение 2 дней, но безрезультатно... Предполагается, что мое приложение Android реагирует на мультимедийные кнопки (например, с гарнитуры, проверьте их с помощью гарнитуры Bluetooth), например, воспроизведение / пауза, затем перемотка назад., Прекрасно работает на KitKat и ниже. Клянусь, он даже работал на Lollipop еще несколько дней назад. Теперь ничего, нет никаких следов, что он слышит нажатия кнопок мультимедиа. У кого-нибудь будет быстрое предложение, где искать проблему? Протестировано с двумя телефонами Lollipop, одной и той же гарнитурой Bluetooth и одной и той же гарнитурой, которая отлично работает для более низких версий Android. Также работает та же гарнитура, нажатия кнопок мультимедиа слышны в других приложениях. Что возможно я мог сломать???
Сейчас я проверил как старые, так и новые способы прослушивания мультимедийных кнопок. В AndroidManifest.xml:
<receiver android:name=".MediaButtonIntentReceiver" android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
Тот факт, что он говорит, что enabled="false" в порядке - я включаю и отключаю приемник по мере необходимости, и MediaButtonIntentReceiver.java получает события прекрасно в KitKat и ниже, полное молчание в Lollipop.
Затем я переключился на последний appcompat (v22.1) и попытался использовать объект MediaSessionCompat и связанный код следующим образом. Это прекрасно работало в небольшом тестовом приложении, только одно из написанных мною действий - мои сообщения Logcat подтверждали, что он слышит нажатие клавиш мультимедиа на Lollipop. Но при вставке в мое приложение снова не работает на Lollipop. Какого черта???
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);
}
}
2 ответа
8 мая 2016: Решил наверняка, я наконец нашел причину, по которой кнопки мультимедиа не работали с моим приложением, когда был включен главный экран. Позже я заметил, что они работали, если какое-либо другое приложение было активно, или экран выключен и т. Д., Но не тогда, когда моя основная активность была активна. Оказывается, что по крайней мере в Android 5 элемент управления WebView, который я использую на своем главном экране, блокирует мультимедийные кнопки, если он имеет фокус. Вызов:
webView.setFocusable(false);
или же
webView.setFocusableInTouchMode(false);
или установка того же атрибута в макете, решает проблему. В Android 6 настраиваемая настройка WebView не имела значения для получения событий мультимедийных кнопок.
24 апреля 2015 г.: решено? - не совсем... Из комментария к этому посту: Обработка мультимедийных кнопок в Android 5.0 Lollipop от @mangini:
Чтобы получать события мультимедийных кнопок, когда ваша активность находится на переднем плане, вызовите setMediaController() для вашей активности с экземпляром MediaController, подключенным к вашей активной MediaSession. - Манджини 23 января в 18:35
Я все время проводил тестирование с включенным экраном, и на нем открывалась моя активность, так как она всегда работала таким же образом и в более старых версиях Android... Как только я нажал кнопку "Домой" или выключил экран, мой старый MediaButtonIntentReceiver запустился работает нормально.
События кнопки " Обновить мультимедиа" поступают в мое приложение только в том случае, если включен диспетчер экрана блокировки с использованием устаревшего RemoteControlClient, и, конечно, моя деятельность находится не на переднем плане. Если я отключу диспетчер экрана блокировки (который есть в моем приложении) и удалю RemoteControlClient, я снова не получу никаких событий мультимедиа.
Эта проблема под Lollipop - полный беспорядок. Или по крайней мере полный беспорядок об этом существует в моей голове прямо сейчас. Желаю, чтобы кто-то опубликовал пример кода для работы с мультимедийными кнопками, который будет работать в старых версиях Android и Lollipop...
Greg
Просьба переопределить функцию возврата false.
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return false;
}