2

I'm using VideoView with MediaController. I'm fighting with back-press bug, which is common and on SO we can find a lot of topics about that:

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

all of these are suggesting overriding dispatchKeyEvent inside MediaController. But it won't fire on Android Pie... Method works on older OS versions, but on Pie I'm not getting a dispatchKeyEvent or onKeyPressed call anywhere when media controls are visible - Activity (onBackPressed also checked), any View including VideoView (has focus during whole runtime) and MediaController. In fact as long as MediaController is visible on screen the back button isn't working (isn't closing Activity nor hidding MediaController) and I can't figure out "who" consumes that event...

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);

when I remove above code everything works fine, but I need these media controls

someone had a similar problem year ago, without any answer... (note that Pie is younger...)

Android back button not working while playing video in VideoView

snachmsm
  • 17,866
  • 3
  • 32
  • 74
  • Having the same issue - have you found a solution? – tipa May 15 '19 at 10:10
  • sadly no... I've ended with X button in top-left corner. I'm considering replacing `VideoView` with ExoPlayer, maybe this will help, but currently I have more important tasks to do. But still: this will not resolve `VideoView`-`MediaConstroller`-pair issue... – snachmsm May 16 '19 at 11:41
  • Have the same issue. I assume dispatchKeyEvent must be getting events because the MediaController buttons still work in Pie, yet when I override it in a sub-class, no events are ever received... – PM4 May 22 '19 at 15:35

2 Answers2

2

I was also searching for a solution until i found it by myself:

In your MediaController you have to add an OnUnhandledKeyEventListener.

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

For me (using Xamarin) it looks like:

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;
    }
}
Zwawo
  • 21
  • 2
2

I extended the mediacontroller class so that it can handle the activity-backpressed properly for all versions of android (including android P). You can instantiate this class as a media controller.

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);
}


}
Raju
  • 82
  • 1
  • 5