I
I
Ilya2016-11-29 10:22:07
YouTube
Ilya, 2016-11-29 10:22:07

How to implement showing youtube video in webview from version 4.4.4?

The application required a built-in browser. The bottom line is to display various videos in the "Help" section (not only youtube - so there is no point in using the youtube api.). No autoplay is needed. Just open the link in a browser and let the user decide to watch/not watch.
In the Manifesto

<?xml version="1.0" encoding="utf-8"?>
    <application
           ...
            android:hardwareAccelerated="true"
          ...>
    </application>

MainActivity
public class MainActivity extends Activity {

    private WebView webView;
    private FrameLayout customViewContainer;
    private WebChromeClient.CustomViewCallback customViewCallback;
    private View mCustomView;
    private myWebChromeClient mWebChromeClient;
    private myWebViewClient mWebViewClient;

    @SuppressLint("SetJavaScriptEnabled")

    @SuppressWarnings("deprecation")
    public static void clearCookies(Context context)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            CookieManager.getInstance().removeAllCookies(null);
            CookieManager.getInstance().flush();
        } else
        {
            CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(context);
            cookieSyncMngr.startSync();
            CookieManager cookieManager=CookieManager.getInstance();
            cookieManager.removeAllCookie();
            cookieManager.removeSessionCookie();
            cookieSyncMngr.stopSync();
            cookieSyncMngr.sync();
        }
    }
    @Override
    @JavascriptInterface
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        customViewContainer = (FrameLayout) findViewById(R.id.customViewContainer);
        webView = (WebView) findViewById(R.id.webView);

        webView.clearCache(true);
        webView.clearHistory();

        clearCookies(this);

        mWebViewClient = new myWebViewClient();
        webView.setWebViewClient(mWebViewClient);

        mWebChromeClient = new myWebChromeClient();
        webView.setWebChromeClient(mWebChromeClient);

        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        webView.getSettings().setSupportMultipleWindows(true);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setSupportZoom(true);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setPluginState(WebSettings.PluginState.ON);

        if (savedInstanceState == null)
        {
            webView.loadUrl("https://www.youtube.com/watch?v=7mOduxyaZp4");

        } else {
            webView.restoreState(savedInstanceState);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState )
    {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onRestoreInstanceState(savedInstanceState);
        webView.restoreState(savedInstanceState);
    }

    public boolean inCustomView() {
        return (mCustomView != null);
    }

    public void hideCustomView() {
        mWebChromeClient.onHideCustomView();
    }

    @Override
    protected void onPause() {
        super.onPause();    //To change body of overridden methods use File | Settings | File Templates.
        webView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();    //To change body of overridden methods use File | Settings | File Templates.
        webView.onResume();
    }

    @Override
    protected void onStop() {
        super.onStop();    //To change body of overridden methods use File | Settings | File Templates.
        if (inCustomView()) {
            hideCustomView();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (inCustomView()) {
                hideCustomView();
                return true;
            }
            if ((mCustomView == null) && webView.canGoBack()) {
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    class myWebChromeClient extends WebChromeClient {
        @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;
            }
            mCustomView = view;
            webView.setVisibility(View.GONE);
            customViewContainer.setVisibility(View.VISIBLE);
            customViewContainer.addView(view);
            customViewCallback = callback;
        }

        @Override
        public void onHideCustomView() {
            super.onHideCustomView();   
            if (mCustomView == null)
                return;

            webView.setVisibility(View.VISIBLE);
            customViewContainer.setVisibility(View.GONE);
            mCustomView.setVisibility(View.GONE);
            customViewContainer.removeView(mCustomView);
            customViewCallback.onCustomViewHidden();

            mCustomView = null;
        }
    }

    class myWebViewClient extends WebViewClient {

        private String mUrl;
        private final long LOADING_ERROR_TIMEOUT = TimeUnit.SECONDS.toMillis(45);
        private WeakReference<WebView> mReference;
        private boolean mLoadingFinished = false;
        private boolean mLoadingError = false;
        private long mLoadingStartTime = 0;

        // Helps to handle case when onReceivedError get called before onPageStarted
        // Problem cached on Nexus 7; Android 5
        private String mOnErrorUrl;


        private String removeLastSlash(String url) {
            while (url.endsWith("/")) {
                url = url.substring(0, url.length() - 1);
            }
            return url;
        }

        private boolean startsWith(String str, String prefix) {
            return str != null && prefix != null && str.startsWith(prefix);
        }

        private final Runnable mPageLoadingTimeoutHandlerTask = new Runnable() {
            @Override
            public void run() {
                mUrl = null;
                mLoadingFinished = true;
                long loadingTime = System.currentTimeMillis() - mLoadingStartTime;
                if (mReference != null) {
                    WebView webView = mReference.get();
                    if (webView != null) {
                        webView.stopLoading();
                    }
                }

            }
        };

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String url) {
            if (mUrl != null && !mLoadingError) {
                mLoadingError = true;
            } else {
                mOnErrorUrl = removeLastSlash(url);
            }
        }


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            url = removeLastSlash(url);
            if (!startsWith(url, mUrl) && !mLoadingFinished) {

                mUrl = null;
                onPageStarted(view, url, null);
            }
            return false;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favIcon) {
            url = removeLastSlash(url);
            if (startsWith(url, mOnErrorUrl)) {
                mUrl = url;
                mLoadingError = true;
                mLoadingFinished = false;
                onPageFinished(view, url);
            }
            if (mUrl == null) {
                mUrl = url;
                mLoadingError = false;
                mLoadingFinished = false;
                mLoadingStartTime = System.currentTimeMillis();
                view.removeCallbacks(mPageLoadingTimeoutHandlerTask);
                view.postDelayed(mPageLoadingTimeoutHandlerTask, LOADING_ERROR_TIMEOUT);
                mReference = new WeakReference<>(view);
            }
        }

        public void onData(String value) {
            //.. do something with the data
        }

        @JavascriptInterface
        @Override
        public void onPageFinished(final WebView view, String url) {

            url = removeLastSlash(url);

            if (startsWith(url, mUrl) && !mLoadingFinished) {
                mLoadingFinished = true;
                view.removeCallbacks(mPageLoadingTimeoutHandlerTask);

                mOnErrorUrl = null;
                mUrl = null;
                Log.e("UA",view.getSettings().getUserAgentString());

            } else if (mUrl == null) {
                // On some devices (e.g. Lg Nexus 5) onPageStarted sometimes not called at all
                // The only way I found to fix it is to reset WebViewClient
                view.setWebViewClient(new myWebViewClient());
                mLoadingFinished = true;
            }
        }
    }

}

in versions higher than 4.4.4 after clicking on play I get this 89fdfc008b0b4f6b9f2d1453fd9eb30b.png
And tries to download to infinity
Thank you!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ilya, 2016-11-29
@postnik

UPDATE. Most likely it all depends on the input format of the video on youtube. If the video is mp4, then there are no problems. If m4v - it will not be displayed. Why so - I do not know, I'm not strong in this matter. There may still be formats that will not be able to work out

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question