Android使用WebView实现截图分享功能
作者:-仰望星空- 发布时间:2023-04-17 08:03:48
在APP项目的开发过程中,经常会用到分享图片的功能,有时候还需要根据当前用户信息获取指定的分享图片,比如要求在用户分享图中显示用户名、Uid、用户头像等信息。想到的实现方法主要有两点:
1.通过android SDK自带的Canvas方法进行绘制。
2.通过webView实现客户端与H5交互,然后将H5界面做截图处理。
本文主要介绍第二种方式的实现过程,第一种方式的实现方法,后续有时间会在博客中做说明,下面开始本文内容。
首先确定我们要实现的逻辑:
1.客户端与H5的交互,客户端将用户信息(用户名、Uid、用户头像等)发送给H5;
2.客户端截取WebView功能的实现;
3.分享功能的添加。
1.客户端与H5交互
在界面布局中添加webView布局,对WebView布局进行初始化操作(此处需要网络权限,不做单独处理)
wv_imgweb = (WebView) findViewById(R.id.h5_wv_imgweb);
WebSettings webSettings = wv_imgweb.getSettings();
//此处可更加具体的H5界面功能进行相应的WebSettings设置,本文只是演示基本效果
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(false);
wv_imgweb.requestFocusFromTouch();
wv_imgweb.setDrawingCacheEnabled(true);
wv_imgweb.setVerticalScrollBarEnabled(false);
wv_imgweb.setHorizontalScrollBarEnabled(false);
wv_imgweb.setVerticalScrollbarOverlay(false);
wv_imgweb.setHorizontalScrollbarOverlay(false);
wv_imgweb.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//加载逻辑的处理
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//加载逻辑的处理
}
});
//添加用户信息参数,加载H5分享地址
wv_imgweb.loadUrl(h5_url);
2.截图功能的实现
上文中的WebView页面加载完成后,即可调用截图功能,并将图片保存在本地指定文件夹(此处需要存储权限,不做单独处理)
android中WebView可以通过多种方式实现截图,下面分别做不同介绍:
2.1截取屏幕内内容
第一种方式是通过Bitmap bitmap = webView.getDrawingCache()截取屏幕内显示内容,注意调用此方法setDrawingCacheEnabled(true)必须设置为true;
2.2截取整个WebView内容
第二种方式是通过Picture snapShot = wv_imgweb.capturePicture()来截取整个WebView的内容
Picture snapShot = wv_imgweb.capturePicture();
if (snapShot != null && snapShot.getWidth() > 0 && snapShot.getHeight() > 0) {
Bitmap bitmap = Bitmap.createBitmap(snapShot.getWidth(), snapShot.getHeight(), Bitmap.Config.ARGB_8888);//设置相应的图片质量
Canvas canvas = new Canvas(bitmap);
snapShot.draw(canvas);
//将截取的图片保存到本地
try {
File appFile = new File(Environment.getExternalStorageDirectory() + "/testpic/app");
if (!appFile.exists() && !appFile.isDirectory()) {
appFile.mkdirs();
}
String fileName = Environment.getExternalStorageDirectory().getPath() + "/testpic/app/share.jpg";
FileOutputStream fos = new FileOutputStream(fileName);
//设置保存本地图片质量
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
fos.close();
} catch (Exception e) {
UIUtils.setLogInfo("eee", e.getMessage());
}
}
2.3截取整个WebView内容
Android 为了提高各方面的绘制速度(如滚动操作),为每一个 View 建立一个缓存,使用 View.buildDrawingCache 为自己的 View 建立相应的缓存, 这个 cache 就是一个 bitmap 对象。利用这个功能可以对整个屏幕视图进行截屏并生成 Bitmap ,也可以获得指定的 View 的 Bitmap 对象。
wv_imgweb.measure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
wv_imgweb.layout(0, 0, wv_imgweb.getMeasuredWidth(), wv_imgweb.getMeasuredHeight());
wv_imgweb.setDrawingCacheEnabled(true);
wv_imgweb.buildDrawingCache();
Bitmap longImage = Bitmap.createBitmap(wv_imgweb.getMeasuredWidth(),
wv_imgweb.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(longImage); // 画布的宽高和 WebView 保持一致
Paint paint = new Paint();
canvas.drawBitmap(longImage, 0, wv_imgweb.getMeasuredHeight(), paint);
wv_imgweb.draw(canvas);
//将截取的图片保存到本地
try {
File appFile = new File(Environment.getExternalStorageDirectory() + "/testpic/app");
if (!appFile.exists() && !appFile.isDirectory()) {
appFile.mkdirs();
}
String fileName = Environment.getExternalStorageDirectory().getPath() + "/testpic/app/share.jpg";
FileOutputStream fos = new FileOutputStream(fileName);
longImage.compress(Bitmap.CompressFormat.JPEG, 70, fos);
fos.close();
} catch (Exception e) {
UIUtils.setLogInfo("eee", e.getMessage());
}
问题:在5.0+上会发现,截取的快照只显示了webview中显示出来的那部分,没有显示出来的部分是空白的。通过google找到了原因,在5.0+版本上,Android对webview做了优化,旨在减少内存占用以提高性能。因此在默认情况下会智能的绘制html中需要绘制的部分,其实就是当前屏幕展示的html内容,因此会出现未显示的图像是空白的。解决办法是调用enableSlowWholeDocumentDraw()方法。这个方法需要在webview创建之前调用,在Activity里就是在setContentView前去调用,此方法会有显著的性能开销。
3.分享图片
通过原生或第三方分享功能,将上述生成的图片添加到代码中,完成分享。
如果有不同的见解,欢迎留言指正。
来源:https://blog.csdn.net/lhy349/article/details/79710468
猜你喜欢
- 本文主要介绍了idea中同一SpringBoot项目多端口启动,具体如下:现在已经有一个在跑着使用的默认端口 8080选中1,点击2.这个时
- 注:若是为了解决问题,可直接查看第二部分。1.安装与启动在下载安装前,请安装好JDK并配置好环境变量。ActiveMQ可到官网下载。点击进入
- java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象。在Java类库
- 问题描述平常用的是java8,最近在学习java的新特性。这就需要从java8往更高的java版本切换。由于还在使用java8,测试完新特性
- 导入thymeleaf<dependency> <groupId>org.springframework
- 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))一、反射的概述JA
- 本文实例为大家分享了RxJava Retrofit实现购物车展示的具体代码,供大家参考,具体内容如下先给大家展示一下效果图框架结构: 1.项
- 本文实例为大家分享了Java实现聊天机器人完善版的具体代码,供大家参考,具体内容如下Client代码:package GUISocket.c
- 前言有时候我们在项目中,会用到一些本地 jar 包文件,比如隔壁公司自己打包的;此时无法从maven远程仓库拉取;那么我们可以考虑把 jar
- 1、利用延迟队列延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才
- 本文实例讲述了JAVA获取任意http网页源代码。分享给大家供大家参考,具体如下:JAVA获取任意http网页源代码可实现如下功能:1. 获
- springboot版本:2.2.5一、filter注册springboot中添加filter有两种方式:1、实现方法一package co
- 插入排序原理①把所有元素分成已排序和未排序两组②找到未排序组的第一个元素,向已经排序的组中进行插入③倒序遍历已经排好的元素,依次和待插入的元
- 一、整合原理二、导包(41个)1.hibernate(1)hibernate/lib/required(2)hibernate/lib/jp
- 大家在银行交易某些业务时,都可以看到无论是身份证、银行账号中间部分都是用*号替换的,下面小编把代码整理如下:/// <summary&
- SpringBoot集成Freemarker主要特征:静态页面,无接 * 互数据实时性不高且体量小的网站可采用生成静态html的形式数据提前渲
- 参数和返回值得加密目的为了保证接口不被人拦截下来恶意请求,保证程序的稳定性,我们可以使用接口加密的方法来保证参数和返回值的保密性。具体实现方
- 异常与错误:异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通
- 本文实例为大家分享了java * 实现在线人数统计的具体代码,供大家参考,具体内容如下1.在工程中创建监听类SessionListener
- 一、概述 在C和C++语言中都有assert关键,表示断言。在Java中,同样也有assert关键字,表示断言,用法和含义都差不多