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中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是