我们都知道,IOS与Android在对H5页面上的处理是有区别的,举个例子:
最近公司要做一个在webView界面长按保存图片到图库里的一个功能。看起来,很简单嘛,我上个厕所的功夫,H5小哥刷刷的写完了,快啊(到底是谁快)。接着开始调试,IOS打开手机,进到这个界面,长按了下,OK,没有问题,调试完成。我去,好快,我也试了下,好吧,有问题,于是我就戴上放大镜似的眼镜研究了起来。在这一点上,android的webView没有IOS处理的好,IOS已经实现了长按保存,android苦了,得自己实现,好吧,撸起袖子干起来!
通过查看源码我们知道webView也是View的一个子类,那就好办了,按照其他控件的一样写出长按事件
通过查看webView的源码,我们知道,webView的getHitTestResult()函数可以获取到点击页面元素的类型,哈哈,这样我们就可以根据类型进行相应的处理了。
通过源码我们可以看到,HitTestResult有这两个方法:
getType() 获取所选目标的类型,如超链接,电话,图片,邮件等
getExtra() 获取额外的信息
再接着看,HitTestResult下的枚举类型
注意: 在H5页面,加载的图片有两种情况,一种是直接放置的图片Url,一种是Base64编码。
通过HitTestResult的枚举类型,我们知道判断webView.HitTestResult.IMAGE_TYPE和webView.HitTestResult.-SRC_ANCHOR_TYPE即可,废话不多说,开干。
我们都知道Android6.0以上加入了动态权限,这个时候就得判断是否是6.0以上的手机了
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 手机系统6.0(23)以上动态申请权限
}else{//6.0以下不需要
}
在if里面加入权限判断,这个我就省略不写了,很简单。项目里返的是base64编码,所以敲黑板,重点来了:
private var bitmapFile: Bitmap? = null
val hitTestResult = mBinding.bwebView.hitTestResult
if (hitTestResult.extra!=null){
if (hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE || hitTestResult.type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
Thread(Runnable {
try {
val bitmapArray: ByteArray = Base64.decode(hitTestResult.extra.split(",")[1], Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
[email protected] = bitmap
try {
val isSaveSuccess = FileUtils.saveImageToGallery(applicationContext, bitmapFile)
if (isSaveSuccess) {
Looper.prepare()
ToastUtils.show("图片已保存到手机相册!")
Looper.loop()
} else {
Looper.prepare()
ToastUtils.show("保存图片失败,请稍后重试!")
Looper.loop()
}
} catch (e: IOException) {
e.printStackTrace()
}
} catch (e: MalformedURLException) {
e.printStackTrace()
}
}).start()
}
}
分析:
第1点,注意判空,因为考虑到项目里不止这一处用到了H5页面,如果从其它入口进入H5页面,那么hitTestResult.extra会返回null或者hitTestResult.type返回0
为什么type会返回0,如下:
第2点,注意放到子线程进行处理
第3点,注意需要去掉字符串的data:image/png;base64,
因为返回的base64是这样子的,所以得先处理下
第4点,转码保存图片,工具类在下面:
//保存文件到指定路径
public static boolean saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "jj";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
//通过io流的方式来压缩保存图片
boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
//把文件插入到系统图库
//MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
//保存图片后发送广播通知更新数据库
Uri uri = Uri.fromFile(file);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
if (isSuccess) {
return true;
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
如果解决了你的问题,烦请点个赞,点个关注再走呗