WebView使用详解、H5网页视频全屏播放 、网页跳转空白

2023-10-25 06:20

本文主要是介绍WebView使用详解、H5网页视频全屏播放 、网页跳转空白,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载请注明出处:WebView使用详解、H5网页视频全屏播放 、网页跳转空白_fragment webview全屏播放视频_Mr_Leixiansheng的博客-CSDN博客

内容:介绍webview的使用方法,介绍WebViewClient、WebChromeClient,H5网页视频全屏播放,网页跳转空白问题

最近做项目老爱和H5打交道,遇到了很多问题也踩了许多坑,今天在这儿总结下,方便后人乘凉。

关于安卓和H5交互可参考我之前的文章:原生与H5交互介绍

WebView基础设置

private void initWebView() {mWebView.setWebViewClient(new MyWebViewClient());		//设置在WebView中打开链接,不设置则调用自带浏览器。主要针对View进行拦截处理mWebView.setWebChromeClient(new MyWebChromeClient());WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);		//支持JSwebSettings.setDomStorageEnabled(true);		  //启用dom内存,防止js加载失败webSettings.setAllowFileAccess(true);		//允许访问文件webSettings.setSupportZoom(true);		//支持缩放webSettings.setLoadWithOverviewMode(true);		//是否启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView。默认falsewebSettings.setGeolocationEnabled(false);		//是否允许定位webSettings.setLoadsImagesAutomatically(true);		//是否加载图片
//		webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);		//设置缓存模式
//		webSettings.setDefaultTextEncodingName("UTF-8");		//设置页面的编码格式,默认UTF-8}

WebViewClient主要是对view一系列操作进行监听拦截。包括:网页加载开始、网页加载完成、错误拦截处理。(代码中注释会详解,再次不多做介绍)

WebChromeClient主要是对浏览器进行监听。例如弹窗、是否显示支持全屏播放等。(代码中注释会详解,再次不多做介绍)

网页加载空白问题,我只在7.0及以上遇到,貌似是说证书错误,可能越往上安全性越高吧,按照下面处理下就行了

/*** HTTPS通信的网址(以https://开头的网站)出现错误时* 证书错误拦截处理* 安卓7.0需要*/@Overridepublic void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {if(error.getPrimaryError() == android.net.http.SslError.SSL_INVALID ){// 校验过程遇到了bughandler.proceed();		//忽略错误继续加载}else{handler.cancel();		//取消加载}}

视频全屏播放:安卓不像IOS一样可以直接全屏播放,需要在WebChromeClient对其进行设置,相当于是new 一个Fragment让其来进行全屏播放

	/*** 视频播放相关的方法 **/@Overridepublic View getVideoLoadingProgressView() {FrameLayout frameLayout = new FrameLayout(MainActivity.this);frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));return frameLayout;}@Overridepublic void onShowCustomView(View view, CustomViewCallback callback) {showCustomView(view, callback);}@Overridepublic void onHideCustomView() {hideCustomView();}

   

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_load"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="LOAD"/><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent"></WebView><ProgressBarandroid:id="@+id/pb_loading"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:visibility="gone"/></RelativeLayout></LinearLayout>
package com.example.leixiansheng.webviewtest;import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;import java.util.function.Consumer;import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;public class MainActivity extends AppCompatActivity {@BindView(R.id.btn_load)Button mBtnLoad;@BindView(R.id.web_view)WebView mWebView;@BindView(R.id.pb_loading)ProgressBar mPbLoading;/** 视频全屏参数 */protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);private View customView;private FrameLayout fullscreenContainer;private WebChromeClient.CustomViewCallback customViewCallback;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);initWebView();}private void initWebView() {mWebView.setWebViewClient(new MyWebViewClient());		//设置在WebView中打开链接,不设置则调用自带浏览器。主要针对View进行拦截处理mWebView.setWebChromeClient(new MyWebChromeClient());WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);		//支持JSwebSettings.setDomStorageEnabled(true);		  //启用dom内存,防止js加载失败webSettings.setAllowFileAccess(true);		//允许访问文件webSettings.setSupportZoom(true);		//支持缩放webSettings.setLoadWithOverviewMode(true);		//是否启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView。默认falsewebSettings.setGeolocationEnabled(false);		//是否允许定位webSettings.setLoadsImagesAutomatically(true);		//是否加载图片
//		webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);		//设置缓存模式
//		webSettings.setDefaultTextEncodingName("UTF-8");		//设置页面的编码格式,默认UTF-8}@OnClick(R.id.btn_load)public void onViewClicked() {mWebView.loadUrl("http://www.baidu.com");}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {//优先退出全屏播放if (customView != null) {hideCustomView();return true;} else {if (mWebView.canGoBack()) {mWebView.goBack();		//返回上个页面return true;} else {System.exit(0);		//退出程序}}}return super.onKeyDown(keyCode, event);}/*** 针对网页进行拦截处理*/public class MyWebViewClient extends WebViewClient{/***可以实现对网页中超链接的拦截*/@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {//例:拦截电话网址,直接调用本地电话if (url.contains("tel:")){startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));return true;}if (url.startsWith("http:") || url.startsWith("https:")) {view.loadUrl(url);return true;}/*	WebView.HitTestResult hitTestResult = view.getHitTestResult();//hitTestResult==null解决重定向问题if (!TextUtils.isEmpty(url) && hitTestResult == null) {view.loadUrl(url);return true;}*/return super.shouldOverrideUrlLoading(view, url);}/***开始加载*/@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);mPbLoading.setVisibility(View.VISIBLE);}/*** 结束加载*/@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);mPbLoading.setVisibility(View.GONE);}/*** 加载错误的时候会产生这个回调*/@Overridepublic void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {super.onReceivedError(view, errorCode, description, failingUrl);//TODO}/*** HTTPS通信的网址(以https://开头的网站)出现错误时* 证书错误拦截处理* 安卓7.0需要*/@Overridepublic void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {if(error.getPrimaryError() == android.net.http.SslError.SSL_INVALID ){// 校验过程遇到了bughandler.proceed();		//忽略错误继续加载}else{handler.cancel();		//取消加载}}}/*** 针对浏览器拦截处理*/public class MyWebChromeClient extends WebChromeClient{/*** 弹窗拦截*/@Overridepublic boolean onJsAlert(WebView view, String url, String message, JsResult result) {return super.onJsAlert(view, url, message, result);}/*** 弹窗拦截*/@Overridepublic boolean onJsConfirm(WebView view, String url, String message, JsResult result) {return super.onJsConfirm(view, url, message, result);}/*** 弹窗拦截*/@Overridepublic boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {return super.onJsPrompt(view, url, message, defaultValue, result);}/*** 加载进度拦截*/@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);}/*** 文件选择*/@Overridepublic boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {selectImage();return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);}/*** 视频播放相关的方法 **/@Overridepublic View getVideoLoadingProgressView() {FrameLayout frameLayout = new FrameLayout(MainActivity.this);frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));return frameLayout;}@Overridepublic void onShowCustomView(View view, CustomViewCallback callback) {showCustomView(view, callback);}@Overridepublic void onHideCustomView() {hideCustomView();}}/*** 图片选择*/private void selectImage() {//TODO}/*** 视频播放全屏*/private void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {// if a view already exists then immediately terminate the new oneif (customView != null) {callback.onCustomViewHidden();return;}getWindow().getDecorView();//获取虚拟按键高度,防止遮挡if(ScreenUtils.hasNavBar(this)){COVER_SCREEN_PARAMS.setMargins(0,0,0,ScreenUtils.getNavigationBarHeight(this));}FrameLayout decor = (FrameLayout) getWindow().getDecorView();fullscreenContainer = new FullscreenHolder(this);fullscreenContainer.addView(view, COVER_SCREEN_PARAMS);decor.addView(fullscreenContainer, COVER_SCREEN_PARAMS);customView = view;setStatusBarVisibility(false);customViewCallback = callback;}/*** 隐藏视频全屏*/private void hideCustomView() {if (customView == null) {return;}setStatusBarVisibility(true);FrameLayout decor = (FrameLayout) getWindow().getDecorView();decor.removeView(fullscreenContainer);fullscreenContainer = null;customView = null;customViewCallback.onCustomViewHidden();mWebView.setVisibility(View.VISIBLE);}/*** 全屏容器界面*/static class FullscreenHolder extends FrameLayout {public FullscreenHolder(Context ctx) {super(ctx);setBackgroundColor(ctx.getResources().getColor(android.R.color.black));}@Overridepublic boolean onTouchEvent(MotionEvent evt) {return true;}}private void setStatusBarVisibility(boolean visible) {int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);}
}

这篇关于WebView使用详解、H5网页视频全屏播放 、网页跳转空白的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/280601

相关文章

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.