-
Android二维码生成与扫描
2016-06-28 11:20:21Android二维码生成与扫描,完整代码。欢迎下载与使用。 -
Android中的二维码生成与扫描功能
2020-08-31 16:17:56二维码在我们身边真的非常普遍,今天小编给大家分享二维码生成与扫描功能,依然使用目前比较流行的zxing方法,具体实现思路大家通过本文一起学习吧 -
Android二维码生成与扫描(生成带个性图片)
2014-06-19 16:42:41Android二维码生成与扫描(生成带个性图片) 以前的例子现在用上了,现在需求嵌入logo图片,在以前那个domo上加了几句代码. 嵌入logo的像素建议不要太大,如果想要logo大点,相应的二维码生成的大小也要变大,否则生成的... -
Android之二维码生成与扫描
2016-04-27 13:32:32前言月底离开公司,准备月底休息一段时间,之前每天忙于工作,甚至连一些感兴趣的东西都没有研究过,趁着这段时间可以好好享受一下,今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,底部会给出整个...转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428
本文出自:【顾林海的博客】##前言
月底离开公司,准备月底休息一段时间,之前每天忙于工作,甚至连一些感兴趣的东西都没有研究过,趁着这段时间可以好好享受一下,今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,底部会给出整个项目的gitHub地址,为什么要讲二维码,因为二维码太普遍了,随便一个APP都会有二维码扫描。
##Zxing使用
从底部gitHub项目下载地址下载项目完后,可以看到整体代码结构如下:
我们只需将zxing包下的所有代码copy一份到我们的项目中去,除了这写代码以外,还需要zxing的jar包,也从项目中直接copy一份
全部copy完之后,还需要相应的资源文件
1、values文件下的ids文件
2、raw文件中的资源文件(可以替换)
3、layout文件下的activity_capture.xml(可以进行相应的订制)
4、图片资源##生成二维码
等上面工作全部准备完毕后,就可以创建我们的二维码了,如何生成二维码?这时需要EncodingUtils这个二维码生成工具类。通过调用工具类中的createQRCode方法来生成二维码。
public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm)
createQRCode方法参数如下:
content:二维码内容
widthPix:二维码宽度
heightPix:二维码高度
logoBm:二维码中间的logo/** * 创建二维码并将图片保存在本地 */ private void create() { int width = DensityUtil.dip2px(this, 200); Bitmap bitmap = EncodingUtils.createQRCode("http://www.baidu.com", width, width, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)); iv_zxing.setImageBitmap(bitmap); saveBitmap(bitmap); } /** * 将Bitmap保存在本地 * * @param bitmap */ public void saveBitmap(Bitmap bitmap) { // 首先保存图片 File appDir = new File(Environment.getExternalStorageDirectory(), "zxing_image"); if (!appDir.exists()) { appDir.mkdir(); } String fileName = "zxing_image" + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 通知图库更新 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "/sdcard/namecard/"))); }
这里生成的二维码内容是一个百度的地址,中间LOGO是默认的安卓小机器人。
运行程序可以看到如下效果:
##二维码扫描
二维码扫描需要借助于我们的CaptureActivity这个类,打开CaptureActivity界面并进行扫描,扫描完毕后回调onActivityResult方法,也就是我们可以通过onActivityResult得到扫描后的结果。详细代码如下:
/** * 打开二维码扫描 */ private void open() { config(); startActivityForResult(new Intent(MainActivity.this, CaptureActivity.class), 0); } /** * 提高屏幕亮度 */ private void config() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.screenBrightness = 1.0f; getWindow().setAttributes(lp); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); String result = bundle.getString("result"); tv_result.setText(result); } }
效果就不演示的,因为使用的是模拟器。
##扫描本地图片
扫描本地图片需要我们在CaptureActivity中进行相应的修改,为此我在扫描界面底部增加了一个按钮,用来选择本地图片。layout代码这里就不展示,我们直接看点击后的事件处理。
/** * 打开本地图片 */ private void openLocalImage() { // 打开手机中的相册 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); innerIntent.setType("image/*"); Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片"); this.startActivityForResult(wrapperIntent, 0x01); }
打开系统图片库后选择图片,这时需要重写onActivityResult方法用于返回图片信息。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case 0x01: // 获取选中图片的路径 Cursor cursor = getContentResolver().query(data.getData(), null, null, null, null); if (cursor.moveToFirst()) { photo_path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); new Thread(new Runnable() { @Override public void run() { Result result = scanningImage(photo_path); if (result != null) { handleDecode(result, new Bundle()); } } }).start(); break; } } }
获取图片路径photo_path后,调用scanningImage方法进行扫描,zxing源码中,扫描到的结果都是存放在Result这个结果集中。获取到Result后,就进行结果的回传,阅读CaptureActivity源码,可以得知最后Result结果集会传递给handleDecode方法。
/** * A valid barcode has been found, so give an indication of success and show * the results. * * @param rawResult * The contents of the barcode. * @param bundle * The extras */ public void handleDecode(Result rawResult, Bundle bundle) { inactivityTimer.onActivity(); beepManager.playBeepSoundAndVibrate(); Intent resultIntent = new Intent(); bundle.putInt("width", mCropRect.width()); bundle.putInt("height", mCropRect.height()); bundle.putString("result", rawResult.getText()); resultIntent.putExtras(bundle); this.setResult(RESULT_OK, resultIntent); CaptureActivity.this.finish(); }
获取到图片路径后需要将其二维码信息包装成Result对象,因此需要解析图片:
/** * 扫描二维码图片的方法 * * @param path * @return */ public Result scanningImage(String path) { if (TextUtils.isEmpty(path)) { return null; } Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 先获取原大小 scanBitmap = BitmapFactory.decodeFile(path, options); options.inJustDecodeBounds = false; // 获取新的大小 int sampleSize = (int) (options.outHeight / (float) 200); if (sampleSize <= 0) sampleSize = 1; options.inSampleSize = sampleSize; scanBitmap = BitmapFactory.decodeFile(path, options); int width = scanBitmap.getWidth(); int height = scanBitmap.getHeight(); int[] pixels = new int[width * height]; scanBitmap.getPixels(pixels, 0, width, 0, 0, width, height); /** * 第三个参数是图片的像素 */ RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e) { e.printStackTrace(); } catch (ChecksumException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } return null; }
根据路径获取Bitmap,最后通过QRCodeReader 中的decode方法解析成Result对象并返回,最终传递给handleDecode方法。
运行程序效果如下:
最后扫描出来的是之前定义的百度地址。
##权限与Activity
当二维码的生成与扫描完成后,别忘了权限:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.zxingtest" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.zxingtest.zxing.activity.CaptureActivity"></activity> </application> </manifest>
以下是完整的github项目地址
github项目源码地址:点击【项目源码】 -
Android开发——Android中的二维码生成与扫描
2017-01-13 16:04:080. 前言今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描。本篇旨在帮助有需求的同学快速完成二维码生成和扫描的功能。...0. 前言
今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描。本篇旨在帮助有需求的同学快速完成二维码生成和扫描的功能。
本篇转载自:http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428
1. Zxing的使用
从github上下载项目后,可以看到整体代码结构如下:
我们只需将Zxing包下的所有代码copy一份到我们的项目中去,除了这些还需要zxing的jar包,最后相应的资源文件,包括values文件下的ids文件、raw文件中的资源文件(可以替换)、layout文件下的activity_capture.xml(可以进行相应的订制) 和图片资源。
2. 生成二维码的实现
等上面工作全部准备完毕后,就可以创建我们的二维码了。如何生成二维码?
需要EncodingUtils这个二维码生成工具类。通过调用工具类中的createQRCode()方法来生成二维码。该方法参数介绍如下:
/* * content:二维码内容 * widthPix:二维码宽度 * heightPix:二维码高度 * logoBm:二维码中间的logo对应的Bitmap */ public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm)
下面完成的是生成的一个百度地址的二维码,中间LOGO是Android小机器人。并保存图片到本地,方便后续测试二维码的本地读取功能。
/** * 创建、展示二维码并将bitmap保存在本地 */ private void create() { int width = DensityUtil.dip2px(this, 200); Bitmap bitmap = EncodingUtils.createQRCode("http://www.baidu.com", width, width, BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher)); iv_zxing.setImageBitmap(bitmap); saveBitmap(bitmap); } /** * 将Bitmap保存在本地 * * @param bitmap */ public void saveBitmap(Bitmap bitmap) { // 首先保存图片 File appDir = new File(Environment.getExternalStorageDirectory(),"zxing_image"); if (!appDir.exists()) { appDir.mkdir(); } String fileName = "zxing_image" + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } // 把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(this.getContentResolver(),file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 通知图库更新 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "/sdcard/namecard/"))); }
看到如下效果:
3. 读取二维码的实现
3.1 摄像头扫描的方式
二维码扫描需要借助于CaptureActivity这个类,打开CaptureActivity界面并进行扫描,扫描完毕后回调onActivityResult()方法,从onActivityResult()中得到扫描后的结果。效果就不演示的,因为使用的是模拟器。详细代码如下:
/** * 打开二维码扫描 */ private void open() { config(); startActivityForResult(new Intent(MainActivity.this,CaptureActivity.class), 0); } /** * 提高屏幕亮度 */ private void config() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.screenBrightness = 1.0f; getWindow().setAttributes(lp); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); String result = bundle.getString("result"); tv_result.setText(result); } }
3.2 本地图片扫描的方式
扫描本地图片需要我们在CaptureActivity中进行相应的修改,为此我在扫描界面底部增加了一个按钮,用来选择本地图片。layout代码这里就不展示,我们直接看点击后的事件处理。
/** * 打开本地图片 */ private void openLocalImage() { // 打开手机中的相册 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); innerIntent.setType("image/*"); Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片"); this.startActivityForResult(wrapperIntent, 0x01); }
打开系统图片库后选择图片,这时需要重写onActivityResult()方法用于返回图片信息。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case 0x01: // 获取选中图片的路径 Cursor cursor = getContentResolver().query(data.getData(),null, null, null, null); if (cursor.moveToFirst()) { photo_path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); new Thread(new Runnable() { @Override public void run() { Result result = scanningImage(photo_path); if (result != null) { handleDecode(result, new Bundle()); } } }).start(); break; } } }
获取图片路径photo_path后,调用scanningImage()方法进行扫描,Zxing源码中,扫描到的结果都是存放在Result结果集中。获取到Result后,就进行结果的回传,阅读CaptureActivity源码可以得知最后Result结果集会传递给handleDecode()方法。
/** * A valid barcode has been found, so give an indication of success and show * the results. * * @param rawResult * The contents of the barcode. * @param bundle * The extras */ public void handleDecode(Result rawResult, Bundle bundle) { inactivityTimer.onActivity(); beepManager.playBeepSoundAndVibrate(); Intent resultIntent = new Intent(); bundle.putInt("width", mCropRect.width()); bundle.putInt("height", mCropRect.height()); bundle.putString("result", rawResult.getText()); resultIntent.putExtras(bundle); this.setResult(RESULT_OK, resultIntent); CaptureActivity.this.finish(); }
获取到图片路径后需要将其二维码信息包装成Result对象,因此需要解析图片:
/** * 扫描二维码图片的方法 * * @param path * @return */ public Result scanningImage(String path) { if (TextUtils.isEmpty(path)) { return null; } Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 先获取原大小 scanBitmap = BitmapFactory.decodeFile(path, options); options.inJustDecodeBounds = false; // 获取新的大小 int sampleSize = (int) (options.outHeight / (float) 200); if (sampleSize <= 0) sampleSize = 1; options.inSampleSize = sampleSize; scanBitmap = BitmapFactory.decodeFile(path, options); int width = scanBitmap.getWidth(); int height = scanBitmap.getHeight(); int[] pixels = new int[width * height]; scanBitmap.getPixels(pixels, 0, width, 0, 0, width, height); /** * 第三个参数是图片的像素 */ RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e) { e.printStackTrace(); } catch (ChecksumException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } return null; }
根据路径获取Bitmap,最后通过QRCodeReader 中的decode方法解析成Result对象并返回,最终传递给handleDecode方法。运行程序效果如下,扫描出来的是之前定义的百度地址。
最后不要忘了申明权限和CaptureActivity。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.VIBRATE"/> <activity android:name="com.example.zxingtest.zxing.activity.CaptureActivity"/>
-
Android:简单粗暴的二维码生成与扫描
2020-04-13 01:34:15Android:简单粗暴的二维码生成与扫描 之前写项目的时候有需求要生成和扫描二维码,我想弄的简单点,在网上找了好久终于在一个大佬的博客里找到了我所期待的简单粗暴,在这里记录一下。 在app目录下的build.gradle...Android:简单粗暴的二维码生成与扫描
- 之前写项目的时候有需求要生成和扫描二维码,我想弄的简单点,在网上找了好久终于在一个大佬的博客里找到了我所期待的简单粗暴,在这里记录一下。
- 在app目录下的build.gradle文件中添加:
implementation 'cn.yipianfengye.android:zxing-library:2.2'
- 在AndroidManifest.xml文件中添加:
<uses-permission android:name="android.permission.CAMERA" /> <!-- 权限:调用相机 --> <uses-permission android:name="android.permission.VIBRATE" /><!-- 权限:振动 -->
- 在Activity或Fragment中执行初始化操作:
ZXingLibrary.initDisplayOpinion(this); //初始化ZXingLibrary
- 向用户申请调用相机的权限 (android 6.0以上需要动态申请相机的调用权限)
//获取相机拍摄的权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//版本>=6.0 ? if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //向用户申请调用相机的权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1); } }
- 生成二维码
String codeStr = “hello world !”; Bitmap bitmap = CodeUtils.createImage(codeStr, 250, 250, null); //设置二维码的内容、宽、高、是否带有logo
- 启动CaptureActivity扫描二维码(二维码的扫描界面用户可以自行设计,这里使用默认界面扫描二维码)。注意要把QRCodeActivity换成自己的Context。
//启动CaptureActivity扫描二维码 startActivityForResult(new Intent(QRCodeActivity.this, CaptureActivity.class), CAPTURE_REQUEST_CODE);
- 在onActivityResult()方法中获取扫描二维码得到的信息
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //用户没有进行有效的设置操作,返回 if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplication(), "取消", Toast.LENGTH_SHORT).show(); return; } switch (requestCode) { case CAPTURE_REQUEST_CODE: { if (data != null) { Bundle bundle = data.getExtras(); if (bundle == null) { Log.d(TAG, "onActivityResult: bundle==null"); return; } if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) { String result = bundle.getString(CodeUtils.RESULT_STRING); Log.d(TAG, "onActivityResult: 解析结果:"+result); } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) { Log.d(TAG, "onActivityResult: 解析失败!"); } } else { Log.d(TAG, "onActivityResult: data==null"); } break; } }
我的部分代码:
QRCodeActivity.java
package com.example.test3project; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.uuzuche.lib_zxing.activity.CaptureActivity; import com.uuzuche.lib_zxing.activity.CodeUtils; import com.uuzuche.lib_zxing.activity.ZXingLibrary; public class QRCodeActivity extends AppCompatActivity { private ImageView imageQRCode; private EditText editCreateQRCode; private Button buttonCreateQRCode; private Button buttonScanQRCode; private TextView textQRCodeResult; private static final String TAG = "QRCodeActivity"; private static final int CAPTURE_REQUEST_CODE = 789; @RequiresApi(api = Build.VERSION_CODES.M) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qrcode); ZXingLibrary.initDisplayOpinion(this); //初始化ZXingLibrary //获取相机拍摄的权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//版本>=6.0 ? if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //向用户申请调用相机的权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1); } } imageQRCode = findViewById(R.id.imageQRCode); editCreateQRCode = findViewById(R.id.editCreateQRCode); buttonCreateQRCode = findViewById(R.id.buttonCreateQRCode); buttonScanQRCode = findViewById(R.id.buttonScanQRCode); textQRCodeResult = findViewById(R.id.textQRCodeResult); buttonCreateQRCode.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String codeStr = editCreateQRCode.getText().toString(); Bitmap bitmap = CodeUtils.createImage(codeStr, 250, 250, null); //设置二维码的内容、宽、高、是否带有logo imageQRCode.setImageBitmap(bitmap); } }); buttonScanQRCode.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //启动CaptureActivity扫描二维码 startActivityForResult(new Intent(QRCodeActivity.this, CaptureActivity.class), CAPTURE_REQUEST_CODE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //用户没有进行有效的设置操作,返回 if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplication(), "取消", Toast.LENGTH_SHORT).show(); return; } switch (requestCode) { case CAPTURE_REQUEST_CODE: { if (data != null) { Bundle bundle = data.getExtras(); if (bundle == null) { Log.d(TAG, "onActivityResult: bundle==null"); return; } if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) { String result = bundle.getString(CodeUtils.RESULT_STRING); textQRCodeResult.setText("解析结果:" + result); Log.d(TAG, "onActivityResult: 解析结果:"+result); } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) { textQRCodeResult.setText("解析二维码失败!"); Log.d(TAG, "onActivityResult: 解析失败!"); } } else { Log.d(TAG, "onActivityResult: data==null"); } break; } } super.onActivityResult(requestCode, resultCode, data); } }
activity_qrcode.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".QRCodeActivity"> <ImageView android:id="@+id/imageQRCode" android:layout_margin="10dp" android:layout_width="250dp" android:layout_height="250dp" android:layout_gravity="center_horizontal"/> <EditText android:hint="输入文字" android:gravity="center" android:id="@+id/editCreateQRCode" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/buttonCreateQRCode" android:text="生成二维码" android:layout_gravity="center_horizontal" android:layout_margin="5dp" android:layout_width="240dp" android:layout_height="wrap_content" /> <Button android:id="@+id/buttonScanQRCode" android:text="扫描二维码" android:layout_gravity="center_horizontal" android:layout_margin="5dp" android:layout_width="240dp" android:layout_height="wrap_content" /> <TextView android:layout_margin="10dp" android:hint="扫描结果" android:gravity="center" android:textSize="20sp" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/textQRCodeResult" /> </LinearLayout>
-
Android中的二维码生成与扫描
2017-09-29 16:18:30前言月底离开公司,准备月底休息一段时间,之前每天忙于工作,甚至连一些感兴趣的东西都没有研究过,趁着这段时间可以好好享受一下,今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,底部会给出整个...(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(′\n′).length;varnumbering = $('转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428
本文出自:【顾林海的博客】前言
月底离开公司,准备月底休息一段时间,之前每天忙于工作,甚至连一些感兴趣的东西都没有研究过,趁着这段时间可以好好享受一下,今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,底部会给出整个项目的gitHub地址,为什么要讲二维码,因为二维码太普遍了,随便一个APP都会有二维码扫描。
Zxing使用
从底部gitHub项目下载地址下载项目完后,可以看到整体代码结构如下:
我们只需将zxing包下的所有代码copy一份到我们的项目中去,除了这写代码以外,还需要zxing的jar包,也从项目中直接copy一份
全部copy完之后,还需要相应的资源文件
1、values文件下的ids文件
2、raw文件中的资源文件(可以替换)
3、layout文件下的activity_capture.xml(可以进行相应的订制)
4、图片资源生成二维码
等上面工作全部准备完毕后,就可以创建我们的二维码了,如何生成二维码?这时需要EncodingUtils这个二维码生成工具类。通过调用工具类中的createQRCode方法来生成二维码。
public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm)
- 1
createQRCode方法参数如下:
content:二维码内容
widthPix:二维码宽度
heightPix:二维码高度
logoBm:二维码中间的logo/** * 创建二维码并将图片保存在本地 */ private void create() { int width = DensityUtil.dip2px(this, 200); Bitmap bitmap = EncodingUtils.createQRCode("http://www.baidu.com", width, width, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)); iv_zxing.setImageBitmap(bitmap); saveBitmap(bitmap); } /** * 将Bitmap保存在本地 * * @param bitmap */ public void saveBitmap(Bitmap bitmap) { // 首先保存图片 File appDir = new File(Environment.getExternalStorageDirectory(), "zxing_image"); if (!appDir.exists()) { appDir.mkdir(); } String fileName = "zxing_image" + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 通知图库更新 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "/sdcard/namecard/"))); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
这里生成的二维码内容是一个百度的地址,中间LOGO是默认的安卓小机器人。
运行程序可以看到如下效果:
二维码扫描
二维码扫描需要借助于我们的CaptureActivity这个类,打开CaptureActivity界面并进行扫描,扫描完毕后回调onActivityResult方法,也就是我们可以通过onActivityResult得到扫描后的结果。详细代码如下:
/** * 打开二维码扫描 */ private void open() { config(); startActivityForResult(new Intent(MainActivity.this, CaptureActivity.class), 0); } /** * 提高屏幕亮度 */ private void config() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.screenBrightness = 1.0f; getWindow().setAttributes(lp); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); String result = bundle.getString("result"); tv_result.setText(result); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
效果就不演示的,因为使用的是模拟器。
扫描本地图片
扫描本地图片需要我们在CaptureActivity中进行相应的修改,为此我在扫描界面底部增加了一个按钮,用来选择本地图片。layout代码这里就不展示,我们直接看点击后的事件处理。
/** * 打开本地图片 */ private void openLocalImage() { // 打开手机中的相册 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); innerIntent.setType("image/*"); Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片"); this.startActivityForResult(wrapperIntent, 0x01); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
打开系统图片库后选择图片,这时需要重写onActivityResult方法用于返回图片信息。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case 0x01: // 获取选中图片的路径 Cursor cursor = getContentResolver().query(data.getData(), null, null, null, null); if (cursor.moveToFirst()) { photo_path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); new Thread(new Runnable() { @Override public void run() { Result result = scanningImage(photo_path); if (result != null) { handleDecode(result, new Bundle()); } } }).start(); break; } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
获取图片路径photo_path后,调用scanningImage方法进行扫描,zxing源码中,扫描到的结果都是存放在Result这个结果集中。获取到Result后,就进行结果的回传,阅读CaptureActivity源码,可以得知最后Result结果集会传递给handleDecode方法。
/** * A valid barcode has been found, so give an indication of success and show * the results. * * @param rawResult * The contents of the barcode. * @param bundle * The extras */ public void handleDecode(Result rawResult, Bundle bundle) { inactivityTimer.onActivity(); beepManager.playBeepSoundAndVibrate(); Intent resultIntent = new Intent(); bundle.putInt("width", mCropRect.width()); bundle.putInt("height", mCropRect.height()); bundle.putString("result", rawResult.getText()); resultIntent.putExtras(bundle); this.setResult(RESULT_OK, resultIntent); CaptureActivity.this.finish(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
获取到图片路径后需要将其二维码信息包装成Result对象,因此需要解析图片:
/** * 扫描二维码图片的方法 * * @param path * @return */ public Result scanningImage(String path) { if (TextUtils.isEmpty(path)) { return null; } Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 先获取原大小 scanBitmap = BitmapFactory.decodeFile(path, options); options.inJustDecodeBounds = false; // 获取新的大小 int sampleSize = (int) (options.outHeight / (float) 200); if (sampleSize <= 0) sampleSize = 1; options.inSampleSize = sampleSize; scanBitmap = BitmapFactory.decodeFile(path, options); int width = scanBitmap.getWidth(); int height = scanBitmap.getHeight(); int[] pixels = new int[width * height]; scanBitmap.getPixels(pixels, 0, width, 0, 0, width, height); /** * 第三个参数是图片的像素 */ RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e) { e.printStackTrace(); } catch (ChecksumException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } return null; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
根据路径获取Bitmap,最后通过QRCodeReader 中的decode方法解析成Result对象并返回,最终传递给handleDecode方法。
运行程序效果如下:
最后扫描出来的是之前定义的百度地址。
权限与Activity
当二维码的生成与扫描完成后,别忘了权限:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.zxingtest" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.zxingtest.zxing.activity.CaptureActivity"></activity> </application> </manifest>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
以下是完整的github项目地址
github项目源码地址:点击【项目源码】- ').addClass('pre-numbering').hide();
-
Android —— QR二维码生成与扫描
2016-09-19 15:59:56这里大概讲一下生成二维码zxing源码提供了生成二维码的方式:public class CreateQRImageTest { private ImageView sweepIV; private int QR_WIDTH = 200, QR_HEIGHT = 200; public void createQRImage(String url... -
二维码生成与扫描
2019-03-29 20:00:14二维码MianActivity !!! 注意要有zxinglibrary这个导包依赖 package com.example.www.erweima; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import ... -
Android开发-二维码生成与扫描
2017-09-13 10:20:36Zxing使用 从底部gitHub项目下载地址下载项目完后,可以看到整体代码结构如下: 我们只需将zxing包下的所有代码copy一份到我们的项目中去,除了这写代码以外,还需要zxing的jar包,也从项目中直接copy一份 ... -
第三方二维码生成与扫描
2019-03-03 19:41:52** 权限 ** <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ...uses-permission android:name="android.permission....//二维码的第三方库 implemen... -
Android平台上二维码的生成与扫描
2016-07-09 07:47:17二维码,在现实生活中有很多的应用,手机二维码功能更是最常见的了,今天我们就在Android平台上实现二维码的生成与扫描 一、准备 工具库下载:BarCodeTest (可点击直接下载或者去以下链接下载适合自己的版本:... -
android二维码的生成与扫描
2016-10-27 19:04:00生成二维码及扫描所需要的开源项目地址:https://github.com/zxing/zxing/releases 怎么配置可以自行百度或者参考本文下面其他博客的链接。代码分析如下:String info = "str"; //createQRCode(String str,int ... -
Android studio 生成二维码与扫描二维码
2017-10-08 11:34:08Android studio 生成二维码与扫描二维码点击libzing下载地址MainActivityimport android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app....
-
【2021】UI自动化测试框架(Selenium3)
-
北极圣诞节礼物网页模板
-
CG作品展示网页模板
-
绿色足球信息网页模板
-
后端——》 使用redis分布式锁解决集群环境下定时任务重复执行的问题
-
如何开发一个完善的 Kafka 生产者客户端?
-
苹果笔记本怎样设置解除屏保时不需要输入密码
-
Dom4j解析xml文件中sql时出异常,可能是项目路径包含中文
-
[LabVIEW]实现CRC校验
-
集合类(ArrayList、HashSet、HashMap)线程不安全例子及解决方案
-
伪代码和流程图
-
【数据分析-随到随学】Python数据获取
-
Python入门到项目直通车
-
瑜伽冥想网页模板
-
Selenium3分布式与虚拟化
-
儿童玩具乐园网页模板
-
linux安装docker
-
基于Android Tv制作一个Tv桌面(五)
-
核弹流苏烈详解
-
python数据分析基础