【问题标题】:Android WebView with an embedded youtube video, full screen button freezes video带有嵌入式 youtube 视频的 Android WebView,全屏按钮冻结视频
【发布时间】:2013-01-23 16:22:51
【问题描述】:

我有一个加载 wordpress 博客的 android webview。一些博客文章包含 youtube 视频,我希望用户能够根据需要制作全屏。问题是 HTML5 全屏按钮在单击时什么都不做,而是冻结视图。 有什么想法吗?

【问题讨论】:

    标签: android html webview youtube


    【解决方案1】:

    这是我在最后一天左右把头发扯下来的东西。基于来自网络的各种代码,我设法让它工作。

    首先,您需要创建一个自定义的WebChromeClient 类,它实现了onShowCustomViewonHideCustomView 方法。

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

    基本上,这里发生的是当按下全屏按钮时,我们正在创建一个新视图来保存视频并隐藏主视图。然后当全屏关闭时,我们会做相反的事情——去掉新视图并显示原始视图。

    您还需要将所有这些属性添加到您的活动类中:

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

    您可能希望在按下后退按钮时关闭全屏视频:

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

    那么在你创建 webview 时使用你的新类就很简单了:

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

    这适用于我在 Android 4.x 上。不确定早期版本,因为我的应用没有针对它们。

    我发现这些链接特别有用:WebView and HTML5 <video>http://code.google.com/p/html5webview/source/browse/trunk/HTML5WebView/src/org/itri/html5webview/HTML5WebView.java

    【讨论】:

    • 在您的代码示例中,全屏视图上下文中的 mContentView 是什么?我想这是您夸大的某种布局,但是您是如何使其全屏显示的。您可以为您的 mContentView 对象发布 XML 吗?
    • mContentView 是主要的活动视图,当视频全屏时它会被隐藏。不过,我不会自动全屏播放视频;用户在观看视频时会这样做(如果他们愿意)。
    • @MarkParnell 请在这里也给您的 cmets stackoverflow.com/questions/18533678/…
    • @MarkParnell 感谢您的解决方案,但我收到错误“尝试在没有有效媒体播放器的情况下调用 getDuration”也有错误(-38,0)。有什么想法吗?
    • 退出活动后,我看到无穷无尽的V/MediaPlayer(15998): isPlaying: 0 消息。为什么退出活动时媒体播放器仍然处于活动状态?
    【解决方案2】:

    如果在应用程序中直接显示 YouTube 视频并不重要,当您将视频信息 URL 插入时,您可以启动外部 YouTube 应用程序。

    要捕获视频信息 URL,您需要使用 onLoadResource 方法:

    new WebViewClient() {
    
        @Override
        public void onLoadResource(WebView view, String url) {
    
            if (url.startsWith("http://www.youtube.com/get_video_info?")) {
                try {
                    String path = url.replace("http://www.youtube.com/get_video_info?", "");
    
                    String[] parqamValuePairs = path.split("&");
    
                    String videoId = null;
    
                    for (String pair : parqamValuePairs) {
                        if (pair.startsWith("video_id")) {
                            videoId = pair.split("=")[1];
                            break;
                        }
                    }
    
                    if(videoId != null){
                        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com"))
                                .setData(Uri.parse("http://www.youtube.com/watch?v=" + videoId)));
                        needRefresh = true;
    
                        return;
                    }
                } catch (Exception ex) {
                }
            } else {
                super.onLoadResource(view, url);
            }
        }
    }
    

    【讨论】:

    • 不错的代码,但是当我按下视频时,它也开始在 webview 中播放,我该如何取消呢?
    • 你可以调用WebView.reload()。但是如果你不需要启动外国应用程序,你可以直接在应用程序中实现全屏视频。
    【解决方案3】:

    感谢@Mark Parnell 的回复,但他正在艰难地进行大量 UI 更改,也许这种方式更简洁、更容易理解:

    当点击全屏按钮时,chrome 客户端会为我们提供全屏视图,然后我们应该将其添加到我们的活动视图中:

    定义这个全局变量以在我们的活动中保存全屏视图引用:

    public class MyAmazingActivity extends AppCompatActivity {
        private View fullscreenView;
        //...
    }
    

    然后 web chrome 客户端将通知我们在 onShowCustomViewonHideCustomView 方法中显示和隐藏全屏视图:

    WebChromeClient webChromeClient = new WebChromeClient() {
    
                private ViewGroup rootView;
                private WebChromeClient.CustomViewCallback customViewCallback;
    
                @Override
                public void onShowCustomView(View view, CustomViewCallback callback) {
    
                    //Destroy full screen view if already exists
                    if (fullscreenView != null) {
                        callback.onCustomViewHidden();
                        return;
                    }
    
                    //Layout params to fit fullscreen view in our activity
                    ViewGroup.LayoutParams layoutParams = 
                            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                    ViewGroup.LayoutParams.MATCH_PARENT);
                    //Catch root of current activity to add fullscreen view
                    rootView = (ViewGroup) WebViewBaseActivity.this.webView.getRootView();
                    
                    //Store full screen view, we need it to destroy it out of scope
                    fullscreenView = view;
    
                    customViewCallback = callback;
                    rootView.addView(fullscreenView, layoutParams);
                }
    
                @Override
                public void onHideCustomView() {
                    //Make sure fullscreen view exists
                    if (fullscreenView != null) {
                        
                        //Remove fullscreen view from activity root view
                        rootView.removeView(fullscreenView);
                        fullscreenView = null;
    
                        //Tell browser we did remove fullscreen view
                        customViewCallback.onCustomViewHidden();
                    }
                }
    
            };
    

    最后按下后删除全屏视图(用户期望这种行为):

    @Override
    public void onBackPressed() {
        if (fullscreenView != null) {
            webChromeClient.onHideCustomView();
        }
    }       
    

    【讨论】:

      猜你喜欢
      • 2014-07-11
      • 1970-01-01
      • 2017-02-22
      • 2016-09-07
      • 1970-01-01
      • 2014-10-26
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多