H5界面长按保存图片到图库(base64去掉头部带data:image/png)

Dora ·
更新时间:2024-09-20
· 694 次阅读

我们都知道,IOS与Android在对H5页面上的处理是有区别的,举个例子:

最近公司要做一个在webView界面长按保存图片到图库里的一个功能。看起来,很简单嘛,我上个厕所的功夫,H5小哥刷刷的写完了,快啊(到底是谁快)。接着开始调试,IOS打开手机,进到这个界面,长按了下,OK,没有问题,调试完成。我去,好快,我也试了下,好吧,有问题,于是我就戴上放大镜似的眼镜研究了起来。在这一点上,android的webView没有IOS处理的好,IOS已经实现了长按保存,android苦了,得自己实现,好吧,撸起袖子干起来!

1.拦截长按事件

  通过查看源码我们知道webView也是View的一个子类,那就好办了,按照其他控件的一样写出长按事件

2,判断是否是图片类型

通过查看webView的源码,我们知道,webView的getHitTestResult()函数可以获取到点击页面元素的类型,哈哈,这样我们就可以根据类型进行相应的处理了。

通过源码我们可以看到,HitTestResult有这两个方法:

getType()   获取所选目标的类型,如超链接,电话,图片,邮件等

getExtra()   获取额外的信息

再接着看,HitTestResult下的枚举类型

注意: 在H5页面,加载的图片有两种情况,一种是直接放置的图片Url,一种是Base64编码。

通过HitTestResult的枚举类型,我们知道判断webView.HitTestResult.IMAGE_TYPE和webView.HitTestResult.-SRC_ANCHOR_TYPE即可,废话不多说,开干。

3、保存到相册,Android6.0以上要考虑动态权限(读写权限)

我们都知道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) this@BridgeWebViewActivity3.bitmapFile = 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; }

如果解决了你的问题,烦请点个赞,点个关注再走呗

界面长按保存图片到图库 [Jièmiàn zhǎng àn bǎocún túpiàn dào túkù] Interface Press to save the image gallery
作者:Jason~JiaoJiaoOne



界面 图片 image base64 png

需要 登录 后方可回复, 如果你还没有账号请 注册新账号