前面我还以为微信二维码按住会有识别图中二维码功能,结果去微信里面按住二维码是真心没有效果。

然后发现微信一般实现这功能都是在网页里,然后说是getHitTestResult()这个方法可以获取点击的内容,然后网上去搜了下这个。

在点击事件发现了下面这段代码:

if (v instanceof WebView) {WebView.HitTestResult result = ((WebView) v).getHitTestResult();if (result != null) {int type = result.getType();if (type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {imgurl = result.getExtra();}}}

可以看出触摸事件可以获得触摸的内容,上段代码就可以获得触摸图片的路径。
看下实现效果:


截屏效果不是很好有点卡顿,其实弹出识别图中二维码效果时还是有点动画效果的。
实现思路:先找一个带二维码图片的网页用webView来加载,然后长按图片读出二维码图片的位置,并且把图片下载下来,再用Zxing来判断是不是二维码,是呢才去进行二维码识别后续操作。

第一步:准备微信的依赖

dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])compile 'com.android.support:appcompat-v7:23.1.1'compile 'com.google.zxing:core:3.2.0'
}

当然了,你也可以导入jar放到libs下面。

第二步:添加应有的权限

<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

第三步:加载带二维码的webView

这里我们先封装个webView:

package com.richerpay.zxingcode.zxingcodeforwebview.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.webkit.WebSettings;
import android.webkit.WebSettings.RenderPriority;
import android.webkit.WebSettings.ZoomDensity;
import android.webkit.WebView;
import android.webkit.WebViewClient;
/*** 自定义WebView,长按图片获取图片url**/
public class CustomWebView extends WebView implements OnLongClickListener{private Context context;private LongClickCallBack mCallBack;public CustomWebView(Context context, LongClickCallBack mCallBack) {super(context);this.context = context;this.mCallBack = mCallBack;initSettings();}private void initSettings() {// 初始化设置WebSettings mSettings = this.getSettings();mSettings.setJavaScriptEnabled(true);//开启javascriptmSettings.setDomStorageEnabled(true);//开启DOMmSettings.setDefaultTextEncodingName("utf-8");//设置字符编码//设置web页面mSettings.setAllowFileAccess(true);//设置支持文件流mSettings.setSupportZoom(true);// 支持缩放mSettings.setBuiltInZoomControls(true);// 支持缩放mSettings.setUseWideViewPort(true);// 调整到适合webview大小mSettings.setLoadWithOverviewMode(true);// 调整到适合webview大小mSettings.setDefaultZoom(ZoomDensity.FAR);// 屏幕自适应网页,如果没有这个,在低分辨率的手机上显示可能会异常mSettings.setRenderPriority(RenderPriority.HIGH);//提高网页加载速度,暂时阻塞图片加载,然后网页加载好了,在进行加载图片mSettings.setBlockNetworkImage(true);mSettings.setAppCacheEnabled(true);//开启缓存机制setWebViewClient(new MyWebViewClient());setOnLongClickListener(this);}@Overridepublic boolean onLongClick(View v) {// 长按事件监听(注意:需要实现LongClickCallBack接口并传入对象)final HitTestResult htr = getHitTestResult();//获取所点击的内容if (htr.getType() == WebView.HitTestResult.IMAGE_TYPE) {//判断被点击的类型为图片mCallBack.onLongClickCallBack(htr.getExtra());}return false;}private class MyWebViewClient extends WebViewClient {/*** 加载过程中 拦截加载的地址url* @param view* @param url  被拦截的url* @return*/@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {return super.shouldOverrideUrlLoading(view, url);}/*** 页面加载过程中,加载资源回调的方法* @param view* @param url*/@Overridepublic void onLoadResource(WebView view, String url) {super.onLoadResource(view, url);}/*** 页面加载完成回调的方法* @param view* @param url*/@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);// 关闭图片加载阻塞view.getSettings().setBlockNetworkImage(false);}/*** 页面开始加载调用的方法* @param view* @param url* @param favicon*/@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);}@Overridepublic void onReceivedError(WebView view, int errorCode,                            String description, String failingUrl) {super.onReceivedError(view, errorCode, description, failingUrl);}@Overridepublic void onScaleChanged(WebView view, float oldScale, float newScale) {super.onScaleChanged(view, oldScale, newScale);CustomWebView.this.requestFocus();CustomWebView.this.requestFocusFromTouch();}}/*** 长按事件回调接口,传递图片地址* @author LinZhang*/public interface LongClickCallBack{/**用于传递图片地址*/void onLongClickCallBack(String imgUrl);}
}

从上面代码中我们可以看出HitTestResult htr = getHitTestResult()获取所点击的内容,然后用回调接口把识别的路径返回。
接下来就是加载webView:

    private void initWebView() {// 初始WebView化控件mCustomWebView = new CustomWebView(this, this);//这里借用翔哥的博客mCustomWebView.loadUrl("http://blog.csdn.net/lmj623565791/article/details/50709663");//加载页面mCustomWebView.setFocusable(true);mCustomWebView.setFocusableInTouchMode(true);LayoutParams lp= new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);addContentView(mCustomWebView, lp);}

第四步:把图片下载到本地,并且用微信校验是否是二维码

/*** 根据地址获取网络图片* @param sUrl 图片地址* @return* @throws IOException*/public  Bitmap getBitmap(String sUrl){try {URL url = new URL(sUrl);HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");if(conn.getResponseCode() == 200){InputStream inputStream = conn.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);saveMyBitmap(bitmap,"code");//先把bitmap生成jpg图片return bitmap;}} catch (Exception e) {e.printStackTrace();}return null;}

接下来我们就来校验是否是二维码图片:

public static Result handleQRCodeFormBitmap(Bitmap bitmap) {Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType,String>();hints.put(DecodeHintType.CHARACTER_SET, "utf-8");RGBLuminanceSource source =new RGBLuminanceSource(bitmap);BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));  QRCodeReader reader2= new QRCodeReader();Result result = null;try {try {result = reader2.decode(bitmap1,hints);} catch (ChecksumException e) {e.printStackTrace();} catch (FormatException e) {e.printStackTrace();}} catch (NotFoundException e) {e.printStackTrace();} return result;}

DecodeImage.handleQRCodeFormBitmap(getBitmap(sUrl));//返回二维码的结果
该做的都做好了

第五步:根据返回结果动态显示dialog是否要识别图中二维码

/*** 显示Dialog* param v*/private void  showDialog() {initAdapter();mCustomDialog = new CustomDialog(this) {@Overridepublic void initViews() {// 初始CustomDialog化控件ListView mListView = (ListView) findViewById(R.id.lv_dialog);mListView.setAdapter(adapter);mListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {// 点击事件switch (position) {case 0:sendToFriends();//把图片发送给好友closeDialog();break;case 1:saveImageToGallery(MainActivity.this);closeDialog();break;case 2:Toast.makeText(MainActivity.this, "已收藏", Toast.LENGTH_LONG).show();closeDialog();break;case 3:goIntent();closeDialog();break;}}});}};mCustomDialog.show();}

到此所有的步骤就讲完了,还是把主要代码贴出来下:

package com.richerpay.zxingcode.zxingcodeforwebview;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;import com.google.zxing.Result;
import com.richerpay.zxingcode.zxingcodeforwebview.widget.CustomDialog;
import com.richerpay.zxingcode.zxingcodeforwebview.widget.CustomWebView;
import com.richerpay.zxingcode.zxingcodeforwebview.widget.CustomWebView.LongClickCallBack;
import com.richerpay.zxingcode.zxingcodeforwebview.zxing.DecodeImage;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends Activity implements LongClickCallBack{private CustomWebView mCustomWebView;private CustomDialog mCustomDialog;private ArrayAdapter<String> adapter;private boolean isQR;//判断是否为二维码private Result result;//二维码解析结果private String url;private File file;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initWebView();}private void initWebView() {// 初始WebView化控件mCustomWebView = new CustomWebView(this, this);//这里借用翔哥的博客mCustomWebView.loadUrl("http://blog.csdn.net/lmj623565791/article/details/50709663");//加载页面mCustomWebView.setFocusable(true);mCustomWebView.setFocusableInTouchMode(true);LayoutParams lp= new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);addContentView(mCustomWebView, lp);}@Overridepublic void onLongClickCallBack(final String imgUrl) {url=imgUrl;// 获取到图片地址后做相应的处理MyAsyncTask mTask = new MyAsyncTask();mTask.execute(imgUrl);showDialog();}/*** 判断是否为二维码* param url 图片地址* return*/private boolean decodeImage(String sUrl){result = DecodeImage.handleQRCodeFormBitmap(getBitmap(sUrl));if(result == null){isQR = false;}else {isQR = true;}return isQR;}public class MyAsyncTask extends AsyncTask<String, Void, String>{@Overrideprotected void onPostExecute(String s) {super.onPostExecute(s);if (isQR){handler.sendEmptyMessage(0);}}@Overrideprotected String doInBackground(String... params) {decodeImage(params[0]);return null;}}/*** 根据地址获取网络图片* @param sUrl 图片地址* @return* @throws IOException*/public  Bitmap getBitmap(String sUrl){try {URL url = new URL(sUrl);HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");if(conn.getResponseCode() == 200){InputStream inputStream = conn.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);saveMyBitmap(bitmap,"code");//先把bitmap生成jpg图片return bitmap;}} catch (Exception e) {e.printStackTrace();}return null;}/*** 显示Dialog* param v*/private void  showDialog() {initAdapter();mCustomDialog = new CustomDialog(this) {@Overridepublic void initViews() {// 初始CustomDialog化控件ListView mListView = (ListView) findViewById(R.id.lv_dialog);mListView.setAdapter(adapter);mListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {// 点击事件switch (position) {case 0:sendToFriends();//把图片发送给好友closeDialog();break;case 1:saveImageToGallery(MainActivity.this);closeDialog();break;case 2:Toast.makeText(MainActivity.this, "已收藏", Toast.LENGTH_LONG).show();closeDialog();break;case 3:goIntent();closeDialog();break;}}});}};mCustomDialog.show();}/*** 初始化数据*/private void initAdapter() {adapter = new ArrayAdapter<String>(this, R.layout.item_dialog);adapter.add("发送给朋友");adapter.add("保存到手机");adapter.add("收藏");}/*** 是二维码时,才添加为识别二维码*/@SuppressLint("HandlerLeak")private Handler handler = new Handler(){public void handleMessage(Message msg) {if (msg.what == 0){if (isQR){adapter.add("识别图中二维码");}adapter.notifyDataSetChanged();}};};/*** 发送给好友*/private void sendToFriends() {Intent intent=new Intent(Intent.ACTION_SEND);Uri imageUri=  Uri.parse(file.getAbsolutePath());intent.setType("image/*");intent.putExtra(Intent.EXTRA_STREAM, imageUri);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(Intent.createChooser(intent, getTitle()));}/*** bitmap 保存为jpg 图片* @param mBitmap 图片源* @param bitName  图片名*/public void saveMyBitmap(Bitmap mBitmap,String bitName)  {file= new File( Environment.getExternalStorageDirectory()+"/"+bitName + ".jpg");FileOutputStream fOut = null;try {fOut = new FileOutputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();}mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);try {fOut.flush();} catch (IOException e) {e.printStackTrace();}try {fOut.close();} catch (IOException e) {e.printStackTrace();}}/*** 先保存到本地再广播到图库* */public  void saveImageToGallery(Context context) {// 其次把文件插入到系统图库try {MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), "code", null);// 最后通知图库更新context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+ file)));} catch (FileNotFoundException e) {e.printStackTrace();}}public void goIntent(){Uri uri = Uri.parse(result.toString());Intent intent = new Intent(Intent.ACTION_VIEW,uri);startActivity(intent);}
}

完整代码需要的请戳》》》ZxingCodeForWebView.rar

总结

通过写这篇让我了解了怎么从网页中去抓取图片的路径,至少以前不会,也顺便练习了下回掉接口和webView的使用,这里也用到了自定义dialog,哈哈感觉小小功能也是要付出点代价去学习的。

安卓webView实现长按二维码的自动识别功能相关推荐

  1. iphone微信长按二维码识别不了

    在安卓版的微信长按二维码可以识别(前提是你的微信版本到支持此功能),但是到了苹果版的微信就识别不了,经个人测试发现是缩放的问题: 1.设置了初始缩放设置为1,最大缩放值要>=1,不支持缩放.-- ...

  2. 小程序长按二维码识别获取信息

    给公司萌新普及顺便记录下, 我们在微信公众号和小程序中在文章后面会放有小程序或者个人企业微信的二维码,以此来引流,拥有自己的私域流量,这个场景就需要这个便捷操作的支持 这个时候想要实现长按二维码跳出添 ...

  3. 如何在H5页面中实现长按二维码关注微信公众号?

    一.平台 1.微信公众号平台 2.WPS的秀堂H5 3.在线二维码解码器 二.步骤 1.登录"微信公众平台" --> 左侧"设置"中的"公众号设 ...

  4. 微信网页开发-长按二维码无法识别问题解决

    微信网页开发-长按二维码无法识别问题解决 参考文章: (1)微信网页开发-长按二维码无法识别问题解决 (2)https://www.cnblogs.com/Tylerrrkd/p/9153949.ht ...

  5. 微信H5 长按二维码识别不了

    解决办法: .qrcode{padding:200px 0 0 200px !important;margin:-200px 0 0 -200px !important;position: relat ...

  6. 一个二维码扫描自动识别下载应用【微信提示】

    先前写了一个关于二维码扫描自动识别设备系统,并自动去下载相应版本的APP, 前一段时间微信扫描后,则不可再下载,原因是微信屏蔽了,只能提示用户从浏览器打开,并自动下载: 下载的界面效果: 下载的 do ...

  7. 关于扫描二维码下载app功能实现方法

    关于扫描二维码下载app功能实现方法   功能实现思路: Androidapk的下载本质上就是文件的下载,所以我们只需要在后台提供一个下载的方法,就能是实现apk的下载. 在实现后台代码以后,我们生成 ...

  8. vue实现二维码批量打印功能

    vue实现二维码批量打印功能 业务需求:客户需要给每个商品贴上二维码,为了更加高效的完成这项工作需要配合热敏打印机实现批量打印二维码的需求,因为是web项目后端会部署到服务器上,因此只能通过js的方式 ...

  9. 随机字符串解决大问题之腾讯网如何实现手机扫描二维码登录qq功能的

    随机字符串解决大问题之腾讯网如何实现手机扫描二维码登录qq功能的 腾讯网(www.qq.com)有一个扫码登录功能很有意思, 点击首页一键登录按钮,就会展现一个二维码,用手机qq扫描此二维码就可以使当 ...

最新文章

  1. AI 天气预报准确度高于气象台,一张 GPU 1秒预测未来 90 分钟天气
  2. NTU 课程笔记:MAS714(9) 动态规划
  3. Silverlight实用窍门系列:42.读取拖动到控件上的外部txt和jpg文件,多外部文件的拖动【附带实例源码】...
  4. 抽丝剥茧,深入剖析 Python 如何实现变量交换!
  5. mysql mgr监控_说MGR - MGR的监控
  6. 图像优化算法(HE、AHE、CLAHE)简单介绍
  7. java在线支付---06,07,08_在线支付_编写将数据提交给易宝支付的JSP页面,集成和测试向易宝发送支付请求,实现浏览器自动向易宝发送支付请求
  8. 阿里双十一数据库技术
  9. Nginx平滑升级与自定义错误页面
  10. Python使用turtle绘图中设置小乌龟(画笔)旋转的角度turtle.setheading()
  11. 洛谷P2058 海港(模拟,优先队列)
  12. 彻底卸载Tomcat
  13. 中国移动互联网公司10年战争史
  14. 面试题之——乐观锁和悲观锁区别
  15. xxl-job(大众点评-许雪里)
  16. 纯前端实现excel表格导入导出
  17. 借助于经济学数学计算机科学,借助于经济学、数学、计算机科学、统计学、概率论以及帮助决策的理论来进行逻辑分析和推论。这一概...
  18. Postman接口测试步骤
  19. pdf编辑阅读器PDF Reader Pro for Mac
  20. 使用jasypt3.0默认加密,启动时报:Failed to bind properties under ‘xxx.xxx.xxx‘ to java.lang.String

热门文章

  1. 安卓微信和平精英服务器,和平精英租号安卓微信区-和平精英安卓号被封了在苹果区还能玩吗...
  2. Map集合(超详解)
  3. 奇亿音乐来告诉你游戏配音的那些事儿
  4. 【独立开发一个2.5D游戏 】—— 2.5D视角构建
  5. idea uml图各符号含义_uml中,各种符号的意义总结
  6. adb 无法识别android手机
  7. arduino笔记26:8*8LED矩阵
  8. Android 10.0 根据包名默认授予app悬浮窗权限
  9. java excel 替换_Excel根据另一个工作表中的查找替换单元格值
  10. redis密码忘了怎么办?