无法在自定义 Webview 中全屏显示 Youtube 视频

Unable to Full Screen Youtube Video Inside Custom Webview

更新

我已更新我的问题以隐藏机密代码。

如果还有不明白的地方请在评论中给我留言。

问题

我已经编写了一个自定义 Webview 来播放我网站中嵌入的 youtube 视频以全屏播放。

但是还是不行.. . 请帮忙

   public class MainActivity extends Activity  implements OnClickListener {

          final Context context = this;
        private WebView webView;
         private ImageButton btnrefresh;    
         private TextView txtrefresh;
           private myWebChromeClient mWebChromeClient;
         private Menu optionsMenu;
         private WebChromeClient.CustomViewCallback customViewCallback;
            private View mCustomView;       
            private FrameLayout customViewContainer;


        @SuppressWarnings("deprecation")
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //Tushar
              customViewContainer = (FrameLayout) findViewById(R.id.customViewContainer);
            //Tushar
            //define button 
            btnrefresh = (ImageButton) findViewById(R.id.imageButton1);

            btnrefresh.setOnClickListener(this);
            btnrefresh.setVisibility(View.GONE);

            //define textView
            txtrefresh = (TextView)findViewById((R.id.textView1));
            txtrefresh.setVisibility(View.GONE);


            if(isConnected())
            {

                webView = (WebView) findViewById(R.id.webView1);
                webView.getSettings().setJavaScriptEnabled(true);       
                   webView.getSettings().setAppCacheEnabled(true);

                    webView.getSettings().setRenderPriority(RenderPriority.HIGH);
                    webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
                    webView.getSettings().setSaveFormData(true);
            //  webView.getSettings().setPluginState(PluginState.ON);
              webView.setWebViewClient(new WebViewClient()
              {
              @Override
              public boolean shouldOverrideUrlLoading(WebView view, String url) {


                  if (url.startsWith("mailto:")) {
                      sendEmail(url.substring(7));
                      return true;
                  }

                  return false;
              }

            });


                initWebView(webView);                         
                webView.loadUrl("http://Example.com/");             

                }


            else
            {

            RelativeLayout rel = (RelativeLayout)findViewById(R.id.relativelayout1);
            rel.setOnClickListener(new View.OnClickListener(){
               @Override
               public void onClick(View v){
                 refresh();
               }
           });
                btnrefresh.setVisibility(View.VISIBLE); 
                txtrefresh.setVisibility(View.VISIBLE);
                Toast.makeText(getBaseContext(), "No Internet Connection !!", Toast.LENGTH_SHORT).show();


            }       
        }

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

        //tushar
        class myWebChromeClient extends WebChromeClient {
            private Bitmap mDefaultVideoPoster;
            private View mVideoProgressView;

            @Override
            public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
               onShowCustomView(view, callback);    //To change body of overridden methods use File | Settings | File Templates.
            }

            @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 View getVideoLoadingProgressView() {

                if (mVideoProgressView == null) {
                    LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                    mVideoProgressView = inflater.inflate(R.layout.video_progress, null);
                }
                return mVideoProgressView;
            }

            @Override
            public void onHideCustomView() {
                super.onHideCustomView();    //To change body of overridden methods use File | Settings | File Templates.
                if (mCustomView == null)
                    return;

                webView.setVisibility(View.VISIBLE);
                customViewContainer.setVisibility(View.GONE);

                // Hide the custom view.
                mCustomView.setVisibility(View.GONE);

                // Remove the custom view from its container.
                customViewContainer.removeView(mCustomView);
                customViewCallback.onCustomViewHidden();

                mCustomView = null;
            }
        }

要做到这一点,您应该:

  1. 实现 WebChromeClientshowCustomViewhideCustomView 方法。
  2. android:hardwareAccelerated="true" 设置为 AndroidManifest.xml 中的 MainActivity

您的代码中有两个 类 继承了 WebChromeClientmyWebChromeClientMyWebChromeClient)。第一个实现 showCustomViewhideCustomView 方法,它似乎完全适用于全屏视频。第二个没有。但是你(不小心?)将第二个设置为 WebChromeClient 到你的 WebView.

要解决这个问题,只需更改行

webView.setWebChromeClient(new MyWebChromeClient());

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

在您的 initWebView() 方法中。

更新:

要在正常(非全屏)模式下在 纵向 上锁定方向,请将以下行添加到 onHideCustomView() 方法中:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

要让系统决定全屏模式下的最佳方向,请将此行添加到 onShowCustomView(View view, CustomViewCallback callback) 方法:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

工作完美。

在 Android 9.0 版本

上测试

这是最后的工作

在webview上设置setWebChromeClient

mWebView.setWebChromeClient(new MyChrome());

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;

public class MainActivity extends AppCompatActivity {

    WebView mWebView;


    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mWebView = (WebView) findViewById(R.id.webView);


        mWebView.setWebViewClient(new WebViewClient());
        mWebView.setWebChromeClient(new MyChrome());    // here
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setAppCacheEnabled(true);

       if (savedInstanceState == null) {
          mWebView.loadUrl("https://www.youtube.com/");
       }

    }


    private class MyChrome extends WebChromeClient {

        private View mCustomView;
        private WebChromeClient.CustomViewCallback mCustomViewCallback;
        protected FrameLayout mFullscreenContainer;
        private int mOriginalOrientation;
        private int mOriginalSystemUiVisibility;

        MyChrome() {}

        public Bitmap getDefaultVideoPoster()
        {
            if (mCustomView == null) {
                return null;
            }
            return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
        }

        public void onHideCustomView()
        {
            ((FrameLayout)getWindow().getDecorView()).removeView(this.mCustomView);
            this.mCustomView = null;
            getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
            setRequestedOrientation(this.mOriginalOrientation);
            this.mCustomViewCallback.onCustomViewHidden();
            this.mCustomViewCallback = null;
        }

        public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
        {
            if (this.mCustomView != null)
            {
                onHideCustomView();
                return;
            }
            this.mCustomView = paramView;
            this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
            this.mOriginalOrientation = getRequestedOrientation();
            this.mCustomViewCallback = paramCustomViewCallback;
            ((FrameLayout)getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
            getWindow().getDecorView().setSystemUiVisibility(3846 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        }
    }

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

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

在AndroidManifest.xml

<activity
  android:name=".MainActivity"
  android:configChanges="orientation|screenSize" />

Solution Original Source

参考 Sheharyar Ejaz 发布的代码,我替换了 2 行以改进结果。

我替换的第一行是在 onShowCustomView 中,所以当用户点击视频的 Youtube 全屏选项时,视频会像原生 Youtube 一样自动展开为 lansdcape 全屏。

为此,我替换了这一行:

this.mOriginalOrientation = getRequestedOrientation();

这一行:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

我替换的第二行是在 onHideCustomView 中,所以当用户最小化全屏视频时,它会恢复到 phone 的当前布局。

我所做的是替换了这一行:

this.mOriginalOrientation = getRequestedOrientation();

这一行:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

但是,与erakitin的建议完全不同,我没有在AndroidManifest.xml.

中将android:hardwareAccelerated="true"设置为我的MainActivity/WebViewActivity