先看图说话:

1.二维码生成:

 public void generateQRcode() throws FileNotFoundException {String mLink = text.getText().toString();if (mLink.length()==0){mLink=text.getHint().toString();}Log.v("MainActivity","mLink:" + mLink);//generateCode(mLink);
//生成图片二维码boolean success = false;success = createQRImage(mLink, qrImgImageView);if (success) {isQrImgShow = true;Toast.makeText(getBaseContext(), "二维码成功生成,请长按识别", Toast.LENGTH_SHORT).show();}//设置图片长按识别readImagePicture(qrImgImageView);}/** 生成二维码*///要转换的地址或字符串,可以是中文public boolean createQRImage(String url, final ImageView qrImgImageView) throws FileNotFoundException {int QR_WIDTH = 300;int QR_HEIGHT = 300;try {//判断URL合法性if (url == null || "".equals(url) || url.length() < 1) {return false;}Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//图像数据转换,使用了矩阵转换BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);int[] pixels = new int[QR_WIDTH * QR_HEIGHT];//下面这里按照二维码的算法,逐个生成二维码的图片,//两个for循环是图片横列扫描的结果for (int y = 0; y < QR_HEIGHT; y++) {for (int x = 0; x < QR_WIDTH; x++) {if (bitMatrix.get(x, y)) {pixels[y * QR_WIDTH + x] = 0xff000000;} else {pixels[y * QR_WIDTH + x] = 0xffffffff;}}}//生成二维码图片的格式,使用ARGB_8888Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);if (checkBox.isChecked()) {//获取要设置的logo的bitmapImageView imageView_logo = new ImageView(this);imageView_logo.setImageResource(R.drawable.ic_launcher);Bitmap obmp = ((BitmapDrawable) (imageView_logo).getDrawable()).getBitmap();int width = obmp.getWidth();int height = obmp.getHeight();int[] data = new int[width * height];obmp.getPixels(data, 0, width, 0, 0, width, height);if (obmp != null) {bitmap = addLogo(bitmap, obmp);}}boolean b_need_save_first = false;if (!b_need_save_first) {qrImgImageView.setImageBitmap(bitmap);} else {if (bitmap != null) {//必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!final String filePath = getFileRoot(getBaseContext()) + File.separator+ "qr_" + System.currentTimeMillis() + ".jpg";final boolean success = bitmap.compress(Bitmap.CompressFormat.JPEG, 30, new FileOutputStream(filePath));//二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中new Thread(new Runnable() {@Overridepublic void run() {if (success) {//显示到一个ImageView上面runOnUiThread(new Runnable() {@Overridepublic void run() {qrImgImageView.setImageBitmap(BitmapFactory.decodeFile(filePath));}});}}}).start();}}return true;} catch (WriterException e) {e.printStackTrace();}return false;}//文件存储根目录private String getFileRoot(Context context) {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {File external = context.getExternalFilesDir(null);if (external != null) {return external.getAbsolutePath();}}return context.getFilesDir().getAbsolutePath();}

2.生成的二维码中间添加logo

(这个添加了logo的二维码只有超链接可以识别)

 /*** 在二维码中间添加Logo图案*/@SuppressWarnings("deprecation")private static Bitmap addLogo(Bitmap src, Bitmap logo) {if (src == null) {return null;}if (logo == null) {return src;}//获取图片的宽高int srcWidth = src.getWidth();int srcHeight = src.getHeight();int logoWidth = logo.getWidth();int logoHeight = logo.getHeight();if (srcWidth == 0 || srcHeight == 0) {return null;}if (logoWidth == 0 || logoHeight == 0) {return src;}//logo大小为二维码整体大小的1/5float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);try {Canvas canvas = new Canvas(bitmap);canvas.drawBitmap(src, 0, 0, null);canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);canvas.save(Canvas.ALL_SAVE_FLAG);canvas.restore();} catch (Exception e) {bitmap = null;e.getStackTrace();}return bitmap;}

3.是否添加logo通过一个checkbox 来获取状态,并在生成的过程中判断这个checkbox状态

 @Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (buttonView == checkBox) {   //自动登陆选框发生改变时if (isChecked) {checkBox.setChecked(true);}}}
 if (checkBox.isChecked()) {//获取要设置的logo的bitmapImageView imageView_logo = new ImageView(this);imageView_logo.setImageResource(R.drawable.ic_launcher);Bitmap obmp = ((BitmapDrawable) (imageView_logo).getDrawable()).getBitmap();int width = obmp.getWidth();int height = obmp.getHeight();int[] data = new int[width * height];obmp.getPixels(data, 0, width, 0, 0, width, height);if (obmp != null) {bitmap = addLogo(bitmap, obmp);}}

4.长按二维码图片选择识别或者保存到手机相册:

 /** 长按图片解析二维码*/private void readImagePicture(final ImageView imageView) {// TODO Auto-generated method stub//长按,通过zxing读取图片,判断是否有二维码imageView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View viewm) {Bitmap obmp = ((BitmapDrawable) (imageView).getDrawable()).getBitmap();recogQRcode(obmp);return false;}});}//识别二维码的函数public void recogQRcode(Bitmap obmp){int width = obmp.getWidth();int height = obmp.getHeight();int[] data = new int[width * height];obmp.getPixels(data, 0, width, 0, 0, width, height);RGBLuminanceSource source = new RGBLuminanceSource(width, height, data);BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));QRCodeReader reader = new QRCodeReader();Result re = null;try {re = reader.decode(bitmap1);} catch (NotFoundException e) {e.printStackTrace();} catch (ChecksumException e) {e.printStackTrace();} catch (FormatException e) {e.printStackTrace();}if (re == null) {showAlert(obmp);} else {showSelectAlert(obmp, re);}}private void showAlert(final Bitmap bitmap) {Toast.makeText(MainActivity.this,"添加了logo,无法识别",Toast.LENGTH_SHORT).show();AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage("保存图片").setCancelable(false);builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterfacem, int i) {saveImageToGallery(bitmap);}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterfacem, int i) {}});builder.show();}protected void saveImageToGallery(Bitmap bitmap) {// 首先保存图片String path = Environment.getExternalStorageDirectory()+"/QRcodeImage/";File fileDir;/*** 文件目录如果不存在,则创建*/fileDir = new File(path);if (!fileDir.exists()) {fileDir.mkdirs();}String bitName = System.currentTimeMillis()+".JPG";String filePath =Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"+ bitName;Log.e(Debug.filename(new Exception()), Debug.funAndLine(new Exception())+filePath);File file=new File(filePath);if(file.exists()){file.delete();}FileOutputStream out;try{out = new FileOutputStream(file);// 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中if(bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)){out.flush();out.close();
// 插入图库MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), bitName, null);}}catch (FileNotFoundException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}// 发送广播,通知刷新图库的显示this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + filePath)));Toast.makeText(getBaseContext(), "图片保存成功", Toast.LENGTH_SHORT).show();System.out.println("图片保存成功");}private void showSelectAlert(final Bitmap bitmap,final Result re) {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("请选择");String str[] = {"保存图片", "识别二维码"};builder.setItems(str, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterfacem, int i) {switch (i) {case 0: {saveImageToGallery(bitmap);}break;case 1: {//Toast出内容Toast.makeText(MainActivity.this,re.getText(),Toast.LENGTH_SHORT).show();scanResult.setText("识别结果:"+re);//利用正则表达式判断内容是否是URL,是的话则打开网页String regex = "(((https|http)?://)?([a-z0-9]+[.])|(www.))"+ "\\w+[.|\\/]([a-z0-9]{0,})?[[.]([a-z0-9]{0,})]+((/[\\S&&[^,;\u4E00-\u9FA5]]+)+)?([.][a-z0-9]{0,}+|/?)";//设置正则表达式Pattern pat = Pattern.compile(regex.trim());//比对Matcher mat = pat.matcher(re.getText().trim());if (mat.matches()){Uri uri = Uri.parse(re.getText());Intent intent = new Intent(Intent.ACTION_VIEW, uri);//打开浏览器startActivity(intent);}}break;}}});builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterfacem, int i) {}});builder.show();}

生成的效果图:

5.扫描二维码:

这部分采用了第三方的识别库:https://blog.csdn.net/ky1996/article/details/79502358

我是添加到了自己的工程中。上面说的方法很好,这里就不贴了,只说下要注意的地方:

1) 在manifest 添加权限:

    <uses-permission android:name="android.permission.WAKE_LOCK" /><!--获取sd卡写的权限,用于文件上传和下载--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--允许读取手机状态 用于创建BmobInstallation--><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.CAMERA"/><uses-feature android:name="android.hardware.camera"/><uses-feature android:name="android.hardware.camera.autofocus" /><uses-permission android:name="android.permission.FLASHLIGHT" /><uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

2) 在main Activity中获取权限:

 /*** 动态获取权限,Android 6.0 新特性,一些保护权限,除了要在AndroidManifest中声明权限,还要使用如下代码动态获取*/if (Build.VERSION.SDK_INT >= 23) {int REQUEST_CODE_CONTACT = 101;String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS,Manifest.permission.VIBRATE};//验证是否许可权限for (String str : permissions) {if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {//申请权限this.requestPermissions(permissions, REQUEST_CODE_CONTACT);return;}}}

下面是效果图:

从相册获取的gif图

下面是整个demo的下载链接https://download.csdn.net/download/linzihahaha/10777476

Android 养成记-1.5 二维码生成+添加logo+识别+扫码相关推荐

  1. Android PAD扫描枪扫描二维码条形码

    Android PAD扫描枪扫描二维码条形码 1,目前扫描条码只有通过按键触发,按下按键会发送F12的键值,可以通过监听F12键判断是否触发扫描 2,扫到的条码我们会在当前光标处显示出来,同时也发了一 ...

  2. 【Android】扫描条形码和二维码

    [Android]扫描条形码和二维码 原文链接:https://blog.csdn.net/xu_weijie/article/details/80763848 步骤一: 在gradle集成Zxing ...

  3. Android将apk转换成二维码提供给别人扫描并下载

    这两天在网上查找了大量的资料,希望能够将我的Android的apk转换成二维码,提供给客户扫描并下载应用,查找了很久,都没有看到有合适的,他们说的都是要自己提供apk给后台,让后台帮忙弄一个下载链接, ...

  4. android悬浮窗、收款二维码、相机处理、事件通知库、NFC读取等源码

    Android精选源码 一个漂亮而强大的自定义view SeekBar 适用于Android的简单NFC读取源码 安卓任意界面悬浮窗实现源码 android实现收款二维码保存代码 RxBus 一个简易 ...

  5. 鼎捷ERP二维码整体解决方案 Tiptop GP条码管理系统 鼎捷ERP移动解决方案 鼎捷条码扫描 鼎捷WMS仓库移动扫码 鼎捷安卓PDA扫码方案 Tiptop 出入库盘点出货条码扫码

    本人在ERP实施公司做顾问四五年,参与企业实施ERP十多个项目,非常熟悉企业ERP流程,在实施过程遇到众多问题,提出了不少根据企业具体情况的解决方案. 最近定制开发了一套适合企业的条码扫码平台,基于鼎 ...

  6. 怎样在二维码中间添加logo

    我们在外面扫二维码付款的时候会发现有些商家的二维码做得很漂亮,在二维码的中间部分添加了自己的logo,这种二维码就更具有品牌识别性.还有在使用微信加好友时,可以看到对方的二维码中间放有微信头像,这种个 ...

  7. 07二维数组生成扫雷游戏地图

    运用二维数组生成扫雷游戏地图     要求:a,定义10*10的数组,把所有元素初始化为0               b,随机生成10个雷,不能重复(一定要有10个) -1表示雷          ...

  8. ArcGIS Pro如何实现已入库二维数据生成三维模型

    ArcGIS Pro如何实现已入库二维数据生成三维模型 二维要素是否带高程Z判断 如何判断要素是否带有高程Z信息 : 二维要素进行三维的展示 二维要素生成三维模型 常规状态下已入库的数据一般是二维的点 ...

  9. 使用码上登录实现微信扫码登录

    现如今使用微信的人越来越多,很多网站都实现了让用户直接扫码就能登录网站,正是这种方式给用户带来了极多的好处,最重要的是用户不用担心自己总记不住账户密码,从而登录不了网站. 为了方便用户登录,我也想接入 ...

最新文章

  1. php模拟post上传图片,php模拟post上传图片解决方法
  2. netty源码分析服务器启动 NioEventLoop创建
  3. Poj-1088-滑雪
  4. oracle 增长型分区,oracle表分区增加分区
  5. plsql连接oracle数据库
  6. 猿团专访云信CTO阙杭宁——网易云信“稳定”背后的秘密
  7. Java17-day08【File(创建和删除文件、判断和获取功能、遍历目录)、IO流(字节流写数据、异常处理、字节流读数据、复制文本文件、复制图片)】
  8. Drools 在告警关联分析中的应用
  9. VISTA中释放系统还原占用的硬盘空间
  10. 北京某打工子弟学校之二
  11. 红黑树的红黑标志有什么用
  12. click js自动点击 vue_vue.js2.0点击获取自己的属性和jquery方法
  13. InstallShield 2020
  14. linux常用命令技巧--更新中
  15. edit控件自动换行 mfc_VS2010/MFC编程入门:如何创建对话框模板和修改对话框属性?...
  16. get请求是否 csrf认证流程_CORS和CSRF修炼宝典
  17. Win10之WSL编译Android7.1源码
  18. paip.网站扫描安全工具hp WebInspect 使用指南
  19. 视屏剪辑软件(Pr)Premiere Pro CC 2018安装教程:
  20. 金山安全报告:十大病毒危害排行出炉

热门文章

  1. 广州大学计算机考研资料汇总
  2. 遗传算法原理简介及其MATLAB实践
  3. 【UE4】视角制作相关知识点(蓝图)
  4. 数据库两时间类型相减_sql中两个时间类型相减得到的值
  5. 完美支持--WIN11--Crack--LightningChart-10.3.2.2
  6. qq协议 0825 和 0836 udp 登录包解析
  7. RS232转RS484接线图
  8. 详解状态压缩动态规划算法
  9. java中excel上传_java对excel表格的上传和下载处理
  10. 数字信号处理第一章:离散时间信号与离散时间系统