目录
- 一.zxing是什么?
- 二.集成zxing框架
- 三.界面设计
- 四.二维码生成
- 五.二维码扫描
- 附:Android使用Zxing识别图片多个二维码
- 总结
一.zxing是什么?
zxing是google推出的一个开源的二维码框架,可以实现使用手机的摄像头完成二维码的扫描和解码
二.集成zxing框架
1. 将获取的jar包复制到工程的app/libs目录下,刷新,然后去添加依赖
2. 集成java源码,将demo工程QrScan中app/src/main/java/目录下包中的zxing和util复制到此工程对应的app/src/main/java的包下
3. 修改package包名,修改import路径,修改类包名
4. 同步资源,复制资源目录
drawable:btn_back.png flash_off.png flash_on.png
layout:复制activity_capture.xml,activity_scanner.xml,toolbar_scanner.xml
raw:全部复制
values:复制 / 替换其中的attrs.xml,ids.xml,colors.xml
5.修改工具栏框架包和ViewFinderView包路径
6.打开开发权限,在清单文件中添加开发权限
<!--摄像机权限--> | |
<uses-permission android:name="android.permission.CAMERA" /> | |
<!--手机震动权限--> | |
<uses-permission android:name="android.permission.VIBRATE" /> | |
<!--读取本地图片权限--> | |
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
7.最后运行一下工程,如果没报错的话就成功了
三.界面设计
activity_main.xml代码如下:
<com.google.android.material.appbar.AppBarLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:theme="@style/AppTheme.AppBarOverlay"> | |
<androidx.appcompat.widget.Toolbar | |
android:id="@+id/toolbar" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/actionBarSize" | |
android:background="?attr/colorPrimary" | |
app:popupTheme="@style/AppTheme.PopupOverlay" /> | |
</com.google.android.material.appbar.AppBarLayout> | |
<include layout="@layout/content_main" /> | |
<com.google.android.material.floatingactionbutton.FloatingActionButton | |
android:id="@+id/fab" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="bottom|end" | |
app:srcCompat="@android:drawable/ic_dialog_email" /> |
content.xml代码如下:
<TextView | |
android:id="@+id/myTextView" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="48dp" | |
android:hint="扫描结果" | |
android:textSize="24sp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0.0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/myScanButton" | |
app:layout_constraintVertical_bias="0.0" /> | |
<EditText | |
android:id="@+id/myEditText" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="16dp" | |
android:ems="10" | |
android:hint="输入要生成二维码的字符" | |
android:inputType="textPersonName" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0.0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<Button | |
android:id="@+id/myCreateButton" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:text="开始生成" | |
android:textSize="18sp" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/myEditText" /> | |
<ImageView | |
android:id="@+id/myImageView" | |
android:layout_width="202dp" | |
android:layout_height="196dp" | |
android:layout_marginTop="64dp" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0.497" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/myCreateButton" | |
app:srcCompat="@android:drawable/screen_background_light_transparent" /> | |
<Button | |
android:id="@+id/myScanButton" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="36dp" | |
android:text="开始扫描" | |
android:textSize="18sp" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="0.0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/myImageView" /> |
四.二维码生成
创建类CreateUtil,并编写createQRCode()方法来实现
public class CreateUtil { | |
//String codestring:要生成二维码的字符串 | |
// int width:二维码图片的宽度 | |
// int height:二维码图片的高度 | |
public static Bitmap createQRCode(String codestring,int width,int height){ | |
try { | |
//首先判断参数的合法性,要求字符串内容不能为空或图片长宽必须大于0 | |
if (TextUtils.isEmpty(codestring)||width<=0||height<=0){ | |
return null; | |
} | |
//设置二维码的相关参数,生成BitMatrix(位矩阵)对象 | |
Hashtable<EncodeHintType,String> hashtable=new Hashtable<>(); | |
hashtable.put(EncodeHintType.CHARACTER_SET,"utf-8"); //设置字符转码格式 | |
hashtable.put(EncodeHintType.ERROR_CORRECTION,"H"); //设置容错级别 | |
hashtable.put(EncodeHintType.MARGIN,"2"); //设置空白边距 | |
//encode需要抛出和处理异常 | |
BitMatrix bitMatrix=new QRCodeWriter().encode(codestring, BarcodeFormat.QR_CODE,width,height,hashtable); | |
//再创建像素数组,并根据位矩阵为数组元素赋颜色值 | |
int[] pixel=new int[width*width]; | |
for (int h=0;h<height;h++){ | |
for (int w=0;w<width;w++){ | |
if (bitMatrix.get(w,h)){ | |
pixel[h*width+w]= Color.BLACK; //设置黑色色块 | |
}else{ | |
pixel[h*width+w]=Color.WHITE; //设置白色色块 | |
} | |
} | |
} | |
//创建bitmap对象 | |
//根据像素数组设置Bitmap每个像素点的颜色值,之后返回Bitmap对象 | |
Bitmap qrcodemap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); | |
qrcodemap.setPixels(pixel,0,width,0,0,width,height); | |
return qrcodemap; | |
}catch (WriterException e){ | |
return null; | |
} | |
} | |
} |
在MainActivity中编写代码——生成二维码
//点击开始生成按钮监听事件 | |
startBt1.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
String input=inputEt.getText().toString(); //获取用户输入的字符串 | |
//调用CreateUtil类生成二维码后显示在界面上 | |
contentIv.setImageBitmap(CreateUtil.createQRCode(input,contentIv.getWidth(),contentIv.getHeight())); | |
} | |
}); |
五.二维码扫描
MainActivity中编写代码
//开始扫描按钮点击事件监听 | |
startBt2.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
scanQRCode(); | |
} | |
}); | |
//实现扫描二维码的方法 | |
private void scanQRCode() { | |
//申请相机权限 | |
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, Constant.REQ_PERM_CAMERA); | |
return; | |
} | |
//申请文件(相册)读写权限 | |
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | |
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Constant.REQ_PERM_EXTERNAL_STORAGE); | |
return; | |
} | |
//二维码扫码 | |
//然后通过Intent机制启动zxing框架的CaptureActivity,请求返回结果 | |
Intent intent = new Intent(this, CaptureActivity.class); | |
startActivityForResult(intent, Constant.REQ_QR_CODE); | |
} | |
protected void onActivityResult(int requestCode, int resultCode, ) { Intent data | |
super.onActivityResult(requestCode, resultCode, data); | |
//扫描结果回调 | |
if (requestCode == Constant.REQ_QR_CODE && resultCode == RESULT_OK) { | |
Bundle bundle = data.getExtras(); | |
String scanResult = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN); | |
//将扫描出的信息显示出来 | |
resultTv.setText(scanResult); | |
} | |
} | |
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { | |
super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |
switch (requestCode){ | |
case Constant.REQ_PERM_CAMERA: | |
//摄像头权限申请 | |
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
//获得授权 | |
scanQRCode(); | |
} else { | |
//被禁止授权 | |
Toast.makeText(this, "请至权限中心打开本应用的相机访问权限", Toast.LENGTH_LONG).show(); | |
} | |
break; | |
case Constant.REQ_PERM_EXTERNAL_STORAGE: | |
//文件读写权限申请 | |
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
//获得授权 | |
scanQRCode(); | |
} else { | |
//被禁止授权 | |
Toast.makeText(this, "请至权限中心打开本应用的文件读写权限", Toast.LENGTH_LONG).show(); | |
} | |
break; | |
} | |
} | |
} |
到此,一个简易的二维码生成与扫描就完成了
附:Android使用Zxing识别图片多个二维码
android通过zxing可识别bitmap多个二维码,具体使用如下
1.首先build文件添加依赖
implementation 'com.google.zxing:core:3.3.3'
2.使用 QRCodeMultiReader 来解析 Bitmap获取Result数组(二维码图片地址集合)
public static com.google.zxing.Result[] decodeQR(Bitmap srcBitmap) { | |
com.google.zxing.Result[] result = null; | |
if (srcBitmap != null) { | |
int width = srcBitmap.getWidth(); | |
int height = srcBitmap.getHeight(); | |
int[] pixels = new int[width * height]; | |
srcBitmap.getPixels(pixels, 0, width, 0, 0, width, height); | |
// 新建一个RGBLuminanceSource对象 | |
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels); | |
// 将图片转换成二进制图片 | |
BinaryBitmap binaryBitmap = new BinaryBitmap(new | |
GlobalHistogramBinarizer(source)); | |
QRCodeMultiReader reader = new QRCodeMultiReader();// 初始化解析对象 | |
try { | |
result = reader.decodeMultiple(binaryBitmap, | |
CodeHintsUtils.getDefaultDecodeHints());// 解析获取一个Result数组 | |
} catch (NotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
return result; | |
} |
3.通过获取数组下的Result对象,result.getText();//得到二维码信息地址