处理 Android Pie 上的后退按钮 VideoView

Posted

技术标签:

【中文标题】处理 Android Pie 上的后退按钮 VideoView【英文标题】:Handling back button VideoView on Android Pie 【发布时间】:2018-12-18 09:51:31 【问题描述】:

我正在使用 VideoViewMediaController。我正在与背压错误作斗争,这很常见,因此我们可以找到很多关于此的主题:

android back button and MediaController

Back button won't work when VideoView is playing video

First Back button press not caught when playing a video android

Problem with back button in VideoView

所有这些都建议在MediaController 中覆盖dispatchKeyEvent。但它不会在 Android Pie 上触发...方法适用于较旧的操作系统版本,但在 Pie 上,当媒体控件可见时,我在任何地方都没有收到 dispatchKeyEventonKeyPressed 调用 - 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);

当我删除上面的代码时一切正常,但我需要这些媒体控件

一年前有人遇到过类似的问题,没有任何答案...(请注意,Pie 更年轻...)

Android back button not working while playing video in VideoView

【问题讨论】:

遇到同样的问题 - 您找到解决方案了吗? 很遗憾,没有...我以左上角的 X 按钮结束。我正在考虑用 ExoPlayer 替换 VideoView,也许这会有所帮助,但目前我有更重要的任务要做。但仍然:这不会解决VideoView-MediaConstroller-pair 问题... 有同样的问题。我假设 dispatchKeyEvent 必须获取事件,因为 MediaController 按钮仍然在 Pie 中工作,但是当我在子类中覆盖它时,没有收到任何事件...... 【参考方案1】:

我也在寻找解决方案,直到我自己找到它:

在您的 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 上测试它【参考方案2】:

我扩展了 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);




【讨论】:

以上是关于处理 Android Pie 上的后退按钮 VideoView的主要内容,如果未能解决你的问题,请参考以下文章

带有kivy的android上的后退按钮功能

如何在 Flutter 中删除 MaterialApp 上的 Android 后退按钮?

如何禁用 Android 上的设备后退按钮(react-native)?

当backstack为空时,按下android上的后退按钮会破坏导航逻辑

Android:为EditText打开键盘时处理后退按钮单击

PhoneGap - 后退按钮上的android退出