Android WebView with an embedded youtube video, full screen button freezes video

28,501

This is something I've spent the last day or so tearing my hair out over. Based on various bits of code from around the web I've managed to get it working.

First, you need to create a custom WebChromeClient class, which implements the onShowCustomView and onHideCustomView methods.

private class MyWebChromeClient extends WebChromeClient {
    FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT);

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
        // if a view already exists then immediately terminate the new one
        if (mCustomView != null) {
            callback.onCustomViewHidden();
            return;
        }
        mContentView = (RelativeLayout) findViewById(R.id.activity_main);
        mContentView.setVisibility(View.GONE);
        mCustomViewContainer = new FrameLayout(MainActivity.this);
        mCustomViewContainer.setLayoutParams(LayoutParameters);
        mCustomViewContainer.setBackgroundResource(android.R.color.black);
        view.setLayoutParams(LayoutParameters);
        mCustomViewContainer.addView(view);
        mCustomView = view;
        mCustomViewCallback = callback;
        mCustomViewContainer.setVisibility(View.VISIBLE);
        setContentView(mCustomViewContainer);
    }

    @Override
    public void onHideCustomView() {
        if (mCustomView == null) {
            return;
        } else {
            // Hide the custom view.  
            mCustomView.setVisibility(View.GONE);
            // Remove the custom view from its container.  
            mCustomViewContainer.removeView(mCustomView);
            mCustomView = null;
            mCustomViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();
            // Show the content view.  
            mContentView.setVisibility(View.VISIBLE);
            setContentView(mContentView);
        }
    }
}

Basically, what is happening here is when the full screen button gets pressed, we're creating a new view to hold the video and hiding the main view. And then when full screen is closed, we do the opposite - get rid of the new view and display the original view.

You'll need to also add all those properties to your activity class:

private MyWebChromeClient mWebChromeClient = null;
private View mCustomView;
private RelativeLayout mContentView;
private FrameLayout mCustomViewContainer;
private WebChromeClient.CustomViewCallback mCustomViewCallback;

And you probably want to make it close the fullscreen video when the back button is pressed:

@Override
public void onBackPressed() {
    if (mCustomViewContainer != null)
        mWebChromeClient.onHideCustomView();
    else if (myWebView.canGoBack())
        myWebView.goBack();
    else
        super.onBackPressed();
}

Then it's just a matter of using your new class when you create your webview:

myWebView = (WebView) findViewById(R.id.webView1);
mWebChromeClient = new WMWebChromeClient();
myWebView.setWebChromeClient(mWebChromeClient);

This works for me on Android 4.x. Not sure about earlier versions as my app isn't targeting them.

I found these links particularly useful: WebView and HTML5 <video> and http://code.google.com/p/html5webview/source/browse/trunk/HTML5WebView/src/org/itri/html5webview/HTML5WebView.java

Share:
28,501
wilxjcherokee
Author by

wilxjcherokee

Updated on November 21, 2020

Comments

  • wilxjcherokee
    wilxjcherokee over 3 years

    I have an android webview that loads a wordpress blog. Some blog posts contain youtube videos which I would like the user to be able to make full screen if they wish. The problem is the HTML5 full screen button does nothing when clicked but freeze up the view. Any ideas?

  • Andrew Weir
    Andrew Weir about 11 years
    In your code sample, what is mContentView in the context of a view for full screen? I imagine it's some kind of layout you've inflated, but how did you make it fullscreen. Can you post the XML for your mContentView object?
  • Mark Parnell
    Mark Parnell about 11 years
    mContentView is the main activity view, which gets hidden when the video is made fullscreen. I'm not making the video fullscreen automatically though; the user does that (if they want to) when watching the video.
  • anshul
    anshul almost 11 years
    @MarkParnell Please give your comments here also stackoverflow.com/questions/18533678/…
  • unknown
    unknown almost 10 years
    @MarkParnell Thanks for your solution but I am getting error "Attempt to call getDuration without a valid media player" also there is error ( -38,0). Any idea?
  • KiKo
    KiKo over 9 years
    Nice code, but when i press on video it also start playing in webview, how can i Cancel that?
  • Roman Black
    Roman Black over 9 years
    You can call WebView.reload(). But You can implement fullscreen video directly in app if You dont need to start foreign app.
  • Someone Somewhere
    Someone Somewhere over 9 years
    after exiting the activity, I see endless V/MediaPlayer(15998): isPlaying: 0 messages. Why is mediaplayer still active when the activity is exited ?
  • Someone Somewhere
    Someone Somewhere over 9 years
    another use case: pressing the power button when the video is playing in full screen. This really F's things up !
  • Sachin Thampan
    Sachin Thampan about 8 years
    How to handle orientation change?
  • Alexey Strakh
    Alexey Strakh almost 8 years
    Great solution and at least I came a little bit closer to the required functionality (youtube video playback when no native app is installed). I have my OnShow/OnHide handlers called but I'm getting black while screen (even though the background is black). I can hear the video in full mode but couldn't see it. Any suggestions?
  • madhuri H R
    madhuri H R about 7 years
    I have used this code in fragment. in Onhideview is forces me to remove parent views child view. This will remove the toolbar as well. How to do this ? @MarkParnell