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

相关文章

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE