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

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的