Android WebView “ 曲线救国” 实现全屏播放 – 热爱改变生活
我的GitHub GitHub |     登录
  • If you can't fly, then run; if you can't run, then walk; if you can't walk, then crawl
  • but whatever you do, you have to keep moving forward。
  • “你骗得了我有什么用,这是你自己的人生”
  • 曾有伤心之地,入梦如听 此歌

Android WebView “ 曲线救国” 实现全屏播放

Android控件 sinvader 13971℃ 0评论

目的

实现在 webview 中视频全屏播放。

遇到的问题

点击全屏按钮时没有调用 onShowCustomView。导致在代码中无法处理全屏事件。

解决方法

使用加速度传感器,监控手机的方向变化,根据手机的方向变化来判断是否应该变为横向,如果是横向的话视频会全屏。

主要代码

  • 1,首先获得 SensorManager 对象
  • sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    
  • 2. 在 onResume 中进行注册
  • @Override
        protected void onResume() {
            sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
            super.onResume();
        }
    

    应为我的 activity 继承了 SensorEventListener,所以上面的代码中使用的是 this。

  • 3. 在 onSensorChanged 方法中根据 xyz 值进行判断修改横屏竖屏
  • @Override
        public void onSensorChanged(SensorEvent event) {
            final int sensorType = event.sensor.getType();
            //values[0]:X轴,values[1]:Y轴,values[2]:Z轴
            final float[] values = event.values;
            float x = values[0];
            float y = values[1];
            float z = values[2];
            x = Math.abs(x);
            y = Math.abs(y);
            z = Math.abs(z);
            if ((x >= 6 && z < = 6) || (x >= 6 && y >= 6)) {
                Log.i(TAG, "heng" + x + "--" + y + "--" + z);
                if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
                }
            } else if ((x < = 3 && z <= 6) || (z <= 6 && y <= 3)) {
                Log.i(TAG, "shu" + x + "--" + y + "--" + z);
                if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                }
            }
        }
    

    还有待解决的问题:

    这个解决的是网页内部有视频,但是没有视频都是文字呢?这样如果也横屏的话就不太好了,这个问题正在想(2015 年 8 月 31 日 12:11:25)
    想到了一个解决办法,不过可能会有点问题(网络加载慢或者重定向),下面是解决办法:

    在 WebViewClient 中的 onPageFinished 方法中获得 html 的整体代码,然后在里面寻找播放的关键词。

  • 第一步:
  • webView.addJavascriptInterface(jsif, "local_obj");
    
  • 第二步
  • webView.setWebViewClient(new WebViewClient() {
                           @Override
                public void onPageFinished(WebView view, String url) {
                    view.loadUrl("javascript:window.local_obj.showSource(''+" +
                            "document.getElementsByTagName('html')[0].innerHTML+'');");
                    super.onPageFinished(view, url);
                }
            });
    
  • 第三步
  • @JavascriptInterface
        public void showSource(String html) {
            if (html.contains("yk-player-inner")) {
                Log.d("sumile", "优酷播放器");
            } else if (html.contains("play-view")) {
                Log.d("sumile", "土豆播放器");
            }
        }
    
    可能会有问题,这只是我的一个想法。如果有什么更好的办法请下面留言告诉我,拜谢~
    测试代码下载(AndroidStudio 版) 测试代码下载(添加播放器判断)

    里面就 4 个类,Eclipse 直接拷过去就可以了。

    ¥ 有帮助么?打赏一下~

    转载请注明:热爱改变生活.cn » Android WebView “ 曲线救国” 实现全屏播放


    本博客只要没有注明“转”,那么均为原创。 转载请注明链接:sumile.cn » Android WebView “ 曲线救国” 实现全屏播放

    喜欢 (1)
    发表我的评论
    取消评论
    表情

    如需邮件形式接收回复,请注册登录

    Hi,你需要填写昵称和邮箱~

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址
    (6)个小伙伴在吐槽
    1. 哥,为什么我一点击全屏就崩溃了呢,横屏的话就没有问题,求解决啊
      zxf2015-09-09 14:45 回复
      • 错误时候的log,你打开的包含视频的网页,你的操作步骤。这些你得告诉我啊
        sinvader2015-09-09 17:33 回复
        • 我下载你的代码了,然后把4个类给copy进去了,然后我把HTML地址放入加载,进入后可以加载成功,但是当我屏幕是竖这的时候点击全屏按钮就会直接崩溃,横着屏的时候全屏没有问题。 报错信息: 09-09 17:36:46.880: E/WindowManager(9118): android.view.WindowLeaked: Activity com.example.demo.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{2967b3c8 V.E..... R.....ID 0,0-0,0} that was originally added here 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.(ViewRootImpl.java:354) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 09-09 17:36:46.880: E/WindowManager(9118): at android.widget.MediaController.show(MediaController.java:346) 09-09 17:36:46.880: E/WindowManager(9118): at android.widget.MediaController.show(MediaController.java:306) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView$FullScreenControls.show(ContentVideoView.java:161) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.onUpdateMediaMetadata(ContentVideoView.java:345) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.nativeUpdateMediaMetadata(Native Method) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.openVideo(ContentVideoView.java:404) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.surfaceCreated(ContentVideoView.java:365) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView.updateWindow(SurfaceView.java:572) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView.access$000(SurfaceView.java:86) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1890) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1019) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5713) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer.doCallbacks(Choreographer.java:596) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer.doFrame(Choreographer.java:565) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Handler.handleCallback(Handler.java:733) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Handler.dispatchMessage(Handler.java:95) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Looper.loop(Looper.java:136) 09-09 17:36:46.880: E/WindowManager(9118): at android.app.ActivityThread.main(ActivityThread.java:5098) 09-09 17:36:46.880: E/WindowManager(9118): at java.lang.reflect.Method.invokeNative(Native Method) 09-09 17:36:46.880: E/WindowManager(9118): at java.lang.reflect.Method.invoke(Method.java:515) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596) 09-09 17:36:46.880: E/WindowManager(9118): at dalvik.system.NativeStart.main(Native Method)
          zxf2015-09-09 17:37 回复
          • 我说下我猜想的几个点: 1.一般情况下,在特定的手机上,webview会出问题(我的小米4在加载土豆网的视频的时候就会直接崩掉,其他手机没问题,用我的小米4加载优酷的就没问题),这种情况不好弄,可能和是否启用硬件加速有关系。 2.从你上面的log看,是窗体泄露。现在的代码下,其实是打开了另一个窗口去播放的视频(如果不想打开新的窗口将SWebChromeClient中的onShowCustomView和onHideCustomView方法给注掉),给activity中尝试在activity finish的时候先把这个窗口给关掉。
            sinvader2015-09-10 10:48 回复
        • 我下载你的代码了,然后把4个类给copy进去了,然后我把HTML地址放入加载,进入后可以加载成功,但是当我屏幕是竖这的时候点击全屏按钮就会直接崩溃,横着屏的时候全屏没有问题。 报错信息: 09-09 17:36:46.880: E/WindowManager(9118): android.view.WindowLeaked: Activity com.example.demo.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{2967b3c8 V.E..... R.....ID 0,0-0,0} that was originally added here 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.(ViewRootImpl.java:354) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 09-09 17:36:46.880: E/WindowManager(9118): at android.widget.MediaController.show(MediaController.java:346) 09-09 17:36:46.880: E/WindowManager(9118): at android.widget.MediaController.show(MediaController.java:306) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView$FullScreenControls.show(ContentVideoView.java:161) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.onUpdateMediaMetadata(ContentVideoView.java:345) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.nativeUpdateMediaMetadata(Native Method) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.openVideo(ContentVideoView.java:404) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.org.chromium.content.browser.ContentVideoView.surfaceCreated(ContentVideoView.java:365) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView.updateWindow(SurfaceView.java:572) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView.access$000(SurfaceView.java:86) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1890) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1019) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5713) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer.doCallbacks(Choreographer.java:596) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer.doFrame(Choreographer.java:565) 09-09 17:36:46.880: E/WindowManager(9118): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Handler.handleCallback(Handler.java:733) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Handler.dispatchMessage(Handler.java:95) 09-09 17:36:46.880: E/WindowManager(9118): at android.os.Looper.loop(Looper.java:136) 09-09 17:36:46.880: E/WindowManager(9118): at android.app.ActivityThread.main(ActivityThread.java:5098) 09-09 17:36:46.880: E/WindowManager(9118): at java.lang.reflect.Method.invokeNative(Native Method) 09-09 17:36:46.880: E/WindowManager(9118): at java.lang.reflect.Method.invoke(Method.java:515) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780) 09-09 17:36:46.880: E/WindowManager(9118): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596) 09-09 17:36:46.880: E/WindowManager(9118): at dalvik.system.NativeStart.main(Native Method)
          zxf2015-09-09 17:37 回复
    2. 哥啊, 为什么我一点击横屏就崩溃了呢
      zxf2015-09-09 14:44 回复