处理 Android Pie 上的后退按钮 VideoView
Posted
技术标签:
【中文标题】处理 Android Pie 上的后退按钮 VideoView【英文标题】:Handling back button VideoView on Android Pie 【发布时间】:2018-12-18 09:51:31 【问题描述】:我正在使用 VideoView
和 MediaController
。我正在与背压错误作斗争,这很常见,因此我们可以找到很多关于此的主题:
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 上,当媒体控件可见时,我在任何地方都没有收到 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);
当我删除上面的代码时一切正常,但我需要这些媒体控件
一年前有人遇到过类似的问题,没有任何答案...(请注意,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的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中删除 MaterialApp 上的 Android 后退按钮?
如何禁用 Android 上的设备后退按钮(react-native)?
当backstack为空时,按下android上的后退按钮会破坏导航逻辑