赞
踩
内容:介绍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); //支持JS
- webSettings.setDomStorageEnabled(true); //启用dom内存,防止js加载失败
- webSettings.setAllowFileAccess(true); //允许访问文件
- webSettings.setSupportZoom(true); //支持缩放
- webSettings.setLoadWithOverviewMode(true); //是否启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView。默认false
- webSettings.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需要
- */
- @Override
- public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
- if(error.getPrimaryError() == android.net.http.SslError.SSL_INVALID ){// 校验过程遇到了bug
- handler.proceed(); //忽略错误继续加载
- }else{
- handler.cancel(); //取消加载
- }
- }
视频全屏播放:安卓不像IOS一样可以直接全屏播放,需要在WebChromeClient对其进行设置,相当于是new 一个Fragment让其来进行全屏播放
- /*** 视频播放相关的方法 **/
- @Override
- public View getVideoLoadingProgressView() {
- FrameLayout frameLayout = new FrameLayout(MainActivity.this);
- frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- return frameLayout;
- }
-
- @Override
- public void onShowCustomView(View view, CustomViewCallback callback) {
- showCustomView(view, callback);
- }
-
- @Override
- public 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">
-
- <Button
- android:id="@+id/btn_load"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="LOAD"/>
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <WebView
- android:id="@+id/web_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- </WebView>
-
- <ProgressBar
- android: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;
-
- @Override
- protected 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); //支持JS
- webSettings.setDomStorageEnabled(true); //启用dom内存,防止js加载失败
- webSettings.setAllowFileAccess(true); //允许访问文件
- webSettings.setSupportZoom(true); //支持缩放
- webSettings.setLoadWithOverviewMode(true); //是否启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView。默认false
- webSettings.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");
- }
-
- @Override
- public 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{
-
- /**
- *可以实现对网页中超链接的拦截
- */
- @Override
- public 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);
- }
-
- /**
- *开始加载
- */
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- mPbLoading.setVisibility(View.VISIBLE);
- }
-
- /**
- * 结束加载
- */
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- mPbLoading.setVisibility(View.GONE);
- }
-
- /**
- * 加载错误的时候会产生这个回调
- */
- @Override
- public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
- super.onReceivedError(view, errorCode, description, failingUrl);
- //TODO
- }
-
- /**
- * HTTPS通信的网址(以https://开头的网站)出现错误时
- * 证书错误拦截处理
- * 安卓7.0需要
- */
- @Override
- public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
- if(error.getPrimaryError() == android.net.http.SslError.SSL_INVALID ){// 校验过程遇到了bug
- handler.proceed(); //忽略错误继续加载
- }else{
- handler.cancel(); //取消加载
- }
- }
- }
-
- /**
- * 针对浏览器拦截处理
- */
- public class MyWebChromeClient extends WebChromeClient{
-
- /**
- * 弹窗拦截
- */
- @Override
- public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
- return super.onJsAlert(view, url, message, result);
- }
-
- /**
- * 弹窗拦截
- */
- @Override
- public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
- return super.onJsConfirm(view, url, message, result);
- }
-
- /**
- * 弹窗拦截
- */
- @Override
- public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
- return super.onJsPrompt(view, url, message, defaultValue, result);
- }
-
- /**
- * 加载进度拦截
- */
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- }
-
- /**
- * 文件选择
- */
- @Override
- public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
- selectImage();
- return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
- }
-
- /*** 视频播放相关的方法 **/
- @Override
- public View getVideoLoadingProgressView() {
- FrameLayout frameLayout = new FrameLayout(MainActivity.this);
- frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- return frameLayout;
- }
-
- @Override
- public void onShowCustomView(View view, CustomViewCallback callback) {
- showCustomView(view, callback);
- }
-
- @Override
- public 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 one
- if (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));
- }
-
- @Override
- public 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);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。