Обработка кнопки возврата VideoView на Android Pie

Я использую VideoView с MediaController. Я борюсь с ошибкой обратного пресса, которая является обычным явлением, и на SO мы можем найти много тем об этом:

Кнопка возврата Android и MediaController

Кнопка "Назад" не работает, когда VideoView воспроизводит видео

Первое нажатие кнопки Назад не улавливается при воспроизведении видео на андроиде

Проблема с кнопкой возврата в VideoView

все это предполагает преобладание dispatchKeyEvent внутри MediaController. Но он не сработает на Android Pie ... Метод работает в более старых версиях ОС, но на Pie я не получаю вызова dispatchKeyEvent или onKeyPressed нигде, когда видны элементы управления мультимедиа - Activity (также отмечен onBackPressed), любой View, включая VideoView (имеет фокус в течение всего времени выполнения) и MediaController. Фактически, пока MediaController виден на экране, кнопка «Назад» не работает (не закрывает Activity и не скрывает MediaController), и я не могу понять, «кто» потребляет это событие ...

MediaController mp = new MediaController(this) {
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                if (event.getAction() == KeyEvent.ACTION_UP)
                    onBackPressed();
                return true;
            }
            return super.dispatchKeyEvent(event);
        }
    };
videoView.setMediaController(mp);

когда я удаляю приведенный выше код, все работает нормально, но мне нужны эти элементы управления мультимедиа

у кого-то была аналогичная проблема год назад, без ответа ... (обратите внимание, что Пирог моложе ...)

Кнопка возврата Android не работает при воспроизведении видео в VideoView

У вас та же проблема - вы нашли решение?

tipa 15.05.2019 12:10

к сожалению, нет ... Я закончил с кнопкой X в верхнем левом углу. Я подумываю о замене VideoView на ExoPlayer, возможно, это поможет, но сейчас у меня есть более важные задачи. Но все же: это не решит проблему с парой VideoView-MediaConstroller ...

snachmsm 16.05.2019 13:41

Есть такая же проблема. Я предполагаю, что dispatchKeyEvent должен получать события, потому что кнопки MediaController по-прежнему работают в Pie, но когда я переопределяю его в подклассе, события никогда не получаются ...

PM4 22.05.2019 17:35
2
3
771
2

Ответы 2

Я тоже искал решение, пока не нашел его сам:

В вашем MediaController вы должны добавить OnUnhandledKeyEventListener.

 public bool OnUnhandledKeyEvent(View v, KeyEvent e)
    {
        if (e.KeyCode == Keycode.Back && e.Action == KeyEventActions.Up)
        {
            ...
        }
        return true;
    }

Для меня (с использованием Xamarin) это выглядит так:

public class ExtMediaController : MediaController
{
    public delegate void CallBackButtonDelegate();
    public CallBackButtonDelegate BackEvent;
    public ExtMediaController(Context context) : base(context)
    {
        base.AddOnUnhandledKeyEventListener(new OnUnhandledKeyEventListener(this));
    }


    public override bool DispatchKeyEvent(KeyEvent e)
    {
        if (e.KeyCode == Keycode.Back)
        {
            BackEvent?.Invoke();
            //return base.DispatchKeyEvent(e);
        }  

        return base.DispatchKeyEvent(e);
    }

}


 public class OnUnhandledKeyEventListener : Java.Lang.Object, IOnUnhandledKeyEventListener
{
    private ExtMediaController LinkedMediaController;

    public OnUnhandledKeyEventListener(ExtMediaController extMediaController)
    {
        LinkedMediaController = extMediaController;
    }

    public bool OnUnhandledKeyEvent(View v, KeyEvent e)
    {
        if (e.KeyCode == Keycode.Back && e.Action == KeyEventActions.Up)
        {
            LinkedMediaController.BackEvent?.Invoke();
        }
        return true;
    }
}

Это решение не сработало для меня. Тестирую на Android 11

MarounG 14.12.2020 17:57

Я расширил класс mediacontroller, чтобы он мог правильно обрабатывать данные о действиях для всех версий Android (включая Android P). Вы можете создать экземпляр этого класса как медиа-контроллер.

public class ExtendedMediaController extends MediaController {
private Activity            mParentActivity;

public ExtendedMediaController(Context context, Activity parentActivity) {
    super(context);
    mParentActivity = parentActivity;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        OnUnhandledKeyEventListener eventListener = new OnUnhandledKeyEventListener() {
            @Override
            public boolean onUnhandledKeyEvent(View v, KeyEvent event) {
                boolean fHandled = false;

                if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        fHandled =  true;
                    } else if (event.getAction() == KeyEvent.ACTION_UP) {
                        if (mParentActivity != null) {
                            mParentActivity.onBackPressed();
                            fHandled = true;
                        }
                    }
                }
                return(fHandled);
            }
        };
        addOnUnhandledKeyEventListener(eventListener);
    }

}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    boolean fHandled = false;
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            fHandled =  true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            mParentActivity.onBackPressed();
            fHandled = true;
        }
    }
    if (!fHandled) {
        fHandled = super.dispatchKeyEvent(event);
    }
    return(fHandled);
}


}

Другие вопросы по теме