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

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

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

1.拦截长按事件

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

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

2,判断是否是图片类型

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

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

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

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

getExtra()   获取额外的信息

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

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

注意: 在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)
                            [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()
                }

            }

 

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

分析:

    第1点,注意判空,因为考虑到项目里不止这一处用到了H5页面,如果从其它入口进入H5页面,那么hitTestResult.extra会返回null或者hitTestResult.type返回0

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

 

为什么type会返回0,如下: 

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

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

 

  第2点,注意放到子线程进行处理

    第3点,注意需要去掉字符串的data:image/png;base64,因为返回的base64是这样子的,所以得先处理下

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

   第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
 

你可能感兴趣的:(H5界面长按保存图片到图库(base64去掉头部带data:image/png))