Android WebView实现长按保存图片及长按识别二维码功能

作者:大头呆 时间:2021-08-18 18:56:09 

先来简单说一下本文所要实现的功能:用户在浏览网页的时候,长按某一区域,识别如果是图片,则弹出弹框,出现保存图片的功能。同时识别图片是否是二维码,如果是则在弹框中追加识别二维码功能。

细节上:保存图片的弹框要显示在手指长按的位置;选择图片保存后,可以让用户直接去相册查看;选择识别二维码,判断是是不是网址,是的话可以让用户选择复制或访问,否则可以让用户选择复制或搜索。

然后再来看一下效果图:

保存图片

Android WebView实现长按保存图片及长按识别二维码功能

save.gif

识别包含普通文字的二维码:

Android WebView实现长按保存图片及长按识别二维码功能

text.gif

识别包含网址的二维码:

Android WebView实现长按保存图片及长按识别二维码功能

code.gif

上述功能所用到的类和库:

  • 获得长按内容: WebView.HitTestResult

  • 弹框列表: DialogFragment

  • 图片下载: Glide

  • 二维码识别: Zxing


实现要点

记录长按位置

继承 WebView 记录触摸位置:


@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
 touchX = (int) event.getRawX();
 touchY = (int) event.getRawY();
 return super.onInterceptTouchEvent(event);
}

弹框我选择 DialogFragment 而不是 poupwindow 的原因是 poupwindow 的显示通常需要依托另一个View,而且在7.0以上有兼容问题。

判断长按位置的内容类型是否是图片:

获取图片信息


setOnLongClickListener(new View.OnLongClickListener() {

public boolean onLongClick(View v) {
   WebView.HitTestResult result = getHitTestResult();
   if (null == result)
    return false;
   int type = result.getType();
   switch (type) {
    case WebView.HitTestResult.EDIT_TEXT_TYPE: // 选中的文字类型
     break;
    case WebView.HitTestResult.PHONE_TYPE: // 处理拨号
     break;
    case WebView.HitTestResult.EMAIL_TYPE: // 处理Email
     break;
    case WebView.HitTestResult.GEO_TYPE: // 地图类型
     break;
    case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超链接
     break;
    case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: // 带有链接的图片类型
    case WebView.HitTestResult.IMAGE_TYPE: // 处理长按图片的菜单项
     String url = result.getExtra();
     if (mOnSelectItemListener != null && url != null && URLUtil.isValidUrl(url))       mOnSelectItemListener.onSelected(touchX, touchY, result.getType(), url);
     }
     return true;
    case WebView.HitTestResult.UNKNOWN_TYPE: //未知
     break;
   }
   return false;
  }
 });

在手指长按位置处弹出弹框

HitTestResult 是一个实体类,只记录两个信息:当选选择内容的类型和内容的具体值。可以看到通过 WebView.HitTestResult ,我们可以获得除了图片外的很多内容类型。当然这里我们只需要判断是否是图片就好了,然后将长按位置和url一起回调给外层。在手指长按处显示弹框,主要就是 DialogFragment 显示位置的设定了:


public void onStart() {
 super.onStart();
 Dialog dialog = getDialog();
 if (dialog != null) {
  Window window = dialog.getWindow();
  if (window != null) {
   WindowManager.LayoutParams lp = window.getAttributes();
   window.setGravity(Gravity.LEFT | Gravity.TOP);
   lp.x = LocationX;//横坐标位置
   lp.y = LocationY;//纵坐标位置
   lp.width = UIHelper.dip2px(100);
   lp.dimAmount = 0.0f;//外层背景透明,默认变暗
   lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
   lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
   window.setAttributes(lp);
   window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//内部背景透明
  }
 }
}

保存到相册

利用 Glide 下载图片, Glide 自带预加载和图片缓存功能,不需要每次都从网络中下载:


GlideApp.with(appContext).asFile().load(url).submit().get();

可以在长按识别出图片的时候就行预加载:


GlideApp.with(appContext).asBitmap().load(url).preload();

将图片保存在相册:


public static void displayToGallery(Context context, File photoFile) {
 if (photoFile == null || !photoFile.exists()) {
  return;
 }
 String photoPath = photoFile.getAbsolutePath();
 String photoName = photoFile.getName();
 // 把文件插入到系统图库
 try {
  ContentResolver contentResolver = context.getContentResolver();
  MediaStore.Images.Media.insertImage(contentResolver, photoPath, photoName, null);
 } catch (FileNotFoundException e) {
  e.printStackTrace();
 }
 // 最后通知图库更新
 context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + photoPath)));
}

识别图片中的二维码

显示弹框的同时还要判断图片是否包含二维码,这部分就是 Zxing 自带的功能,所以代码就不贴了。注意不应该等是 Zxing 判断是不是二维码后再显示弹框,因为这部分操作耗时可能比较长(见图二)。应当在识别二维码内容后再去更新弹框列表的内容。

总结

总体来说这个功能实现注意的地方还是挺多的,好在都不复杂。当然本例还存在待优化的地方,以及实现更高级的功能,比如以图搜图,查看大图功能,也可以利用 WebView.HitTestResult 对获取到其他类型的内容进行处理,限于篇幅就不再展开了。

最后贴下本项目github地址,对 WebView 感兴趣的可以了解下:

github

总结

以上所述是小编给大家介绍的Android WebView实现长按保存图片及长按识别二维码网站的支持!

来源:https://www.jianshu.com/p/44f971744cb0?utm_source=tuicool&utm_medium=referral

标签:android,webview,保存图片,识别二维码
0
投稿

猜你喜欢

  • C#实现加密与解密详解

    2023-08-11 16:54:42
  • Recyclerview添加头布局和尾布局、item点击事件详解

    2022-04-19 12:38:12
  • Java快速掌握Vector类方法

    2023-11-24 22:49:18
  • 深入浅析SpringBoot中的自动装配

    2021-08-21 17:45:11
  • Spring Boot集成Ehcache缓存解决方式

    2023-05-13 08:27:27
  • Java 对象在 JVM 中的内存布局超详细解说

    2023-05-19 14:10:23
  • 从Python程序中访问Java类的简单示例

    2022-02-19 08:53:13
  • 使用spring框架中的组件发送邮件功能说明

    2022-12-29 03:53:55
  • Java使用openOffice对于word的转换及遇到的问题解决

    2021-12-03 00:01:16
  • java 发送邮件的实例代码(可移植)

    2022-09-23 15:53:44
  • Android自定义ActionProvider ToolBar实现Menu小红点

    2022-09-09 05:07:30
  • Android App自动更新之通知栏下载

    2023-11-07 16:56:45
  • Android 自定义返回按钮的实例详解

    2023-07-04 01:13:43
  • 深入理解C#序列化与反序列化的详解

    2022-06-23 05:11:58
  • java贪吃蛇游戏编写代码

    2023-06-16 02:41:10
  • Spring Boot将项目打包成war包的操作方法

    2022-01-02 22:30:50
  • Flutter 状态管理的实现

    2023-08-21 02:38:33
  • Springboot集成ClickHouse及应用场景分析

    2022-04-02 16:28:46
  • Android仿美团淘宝实现多级下拉列表菜单功能

    2022-07-24 18:42:18
  • java 数据类型有哪些取值范围多少

    2023-01-18 06:13:44
  • asp之家 软件编程 m.aspxhome.com