Android开发 生成和扫描二维码
导入库
implementation ("com.google.zxing:core:3.4.1")
implementation ("com.journeyapps:zxing-android-embedded:4.3.0")
添加权限
<!--摄像机权限-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<!--手机震动权限-->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<!--读取本地图片权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- 自动聚焦权限 -->
<uses-feature android:name="android.hardware.camera.autofocus" />
需要的导入库
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.provider.MediaStore;
import com.google.zxing.WriterException;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.common.BitMatrix;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.widget.ImageView;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
生成二维码
String encodedInfo = "二维码内容";
// 二维码宽度
int width = 320;
// 二维码高度
int height = 320;
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(encodedInfo, BarcodeFormat.QR_CODE, width, height);
int matrixWidth = bitMatrix.getWidth();
int matrixHeight = bitMatrix.getHeight();
Bitmap bitmap = Bitmap.createBitmap(matrixWidth, matrixHeight, Bitmap.Config.RGB_565);
for (int x = 0; x < matrixWidth; x++) {
for (int y = 0; y < matrixHeight; y++) {
bitmap.setPixel(x, y, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
bitmap 就是生成的二维码,这样二维码确实生成了,但是看不到,我们找个图片控件显示出来。
显示二维码图片到界面中
在界面中有一个图片控件。
<ImageView
android:id="@+id/btn_main_generate_qr_code_img"
android:layout_width="320dp"
android:layout_height="320dp"
android:layout_gravity="center"
android:importantForAccessibility="no"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
/>
bitmap 就是上面生成二维码的bitmap
... 生成二维码代码
// 将生成的二维码显示在ImageView中
ImageView imageView = findViewById(R.id.btn_main_generate_qr_code_img);
imageView.setImageBitmap(bitmap);
这样图片就会显示出来,我们再开发一个点击按钮后,保存在手机相册功能,不然不能扫描和保存。
二维码添加底部文字
... 生成二维码代码
// 在生成二维码的代码块中添加以下代码来绘制文字
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(18); // 设置文字大小
paint.setTextAlign(Paint.Align.CENTER); // 设置文字居中
// 绘制文字在二维码底部中间位置
String text = "长城6矿二维码最近遇上了扫描条码的需求,在查找资料过程中不是那么地顺利";
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
int xText = (bitmap.getWidth() - bounds.width())/2;
int yText = bitmap.getHeight() - 4; // 调整文字距离底部的位置
canvas.drawText(text, 40, yText, paint);
// 裁剪Bitmap,去除多余的空白
int sideCut = 36; // 左右两边裁剪宽度
Bitmap trimmedBitmap = Bitmap.createBitmap(bitmap, sideCut, sideCut, width - 2 * sideCut, height - sideCut);
... 保存图片代码,保存图片传递最新的trimmedBitmap,而不是bitmap
保存图片到手机相册中
在界面有一个
// 保存在相册
Button btnMainSaveQrCodeImg = findViewById(R.id.btn_main_save_qr_code_img);
btnMainSaveQrCodeImg.setOnClickListener(v -> {
// 在按钮点击事件中添加以下代码
ImageView imageView = findViewById(R.id.btn_main_generate_qr_code_img);
imageView.setDrawingCacheEnabled(true);
Bitmap qrImage = imageView.getDrawingCache();
String savedImagePath = MediaStore.Images.Media.insertImage(getContentResolver(), qrImage, "QRCode", "Generated QR Code");
Uri savedImageURI = Uri.parse(savedImagePath);
if (savedImageURI != null) {
Log.d("IVESTAG", "btnMainSaveQrCodeImg:" + "二维码已保存到相册");
} else {
Log.d("IVESTAG", "btnMainSaveQrCodeImg:" + "保存失败");
}
});
扫描二维码
// 扫描二维码
Button btnMainScanQrCode = findViewById(R.id.btn_main_scan_qr_code);
btnMainScanQrCode.setOnClickListener(v -> {
IntentIntegrator integrator = new IntentIntegrator(this);
//:设置扫描时的提示信息。
integrator.setPrompt("请扫描设备中的二维码");
// 设置是否锁定扫描器的方向。
integrator.setOrientationLocked(true);
// 设置使用的相机ID,0为后置摄像头,1为前置摄像头。
integrator.setCameraId(0);
// 设置是否开启闪光灯。
integrator.setTorchEnabled(true);
// 设置是否开启扫描成功时的蜂鸣提示。
integrator.setBeepEnabled(true);
// 设置是否在扫描时显示扫描的条码图像。
integrator.setBarcodeImageEnabled(true);
// 设置期望扫描的条码格式,如QR_CODE、CODE_39等
integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
integrator.initiateScan();
});
如果这样写了会发现扫描时横屏,于是需要创建一个空的ScanPage的页面,只要创建java文件即可,不用创建xml
解决扫描横屏问题
创建ScanPage.java
文件,继承CaptureActivity
package com.hxtx.august.Page;
import android.os.Bundle;
import com.journeyapps.barcodescanner.CaptureActivity;
public class ScanPage extends CaptureActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
在AndroidManifest.xml
文件中添加action
<activity android:name=".Page.ScanPage" android:screenOrientation="fullSensor" />
在扫描二维码代码中添加ScanPage类即可
// 设置自定义的扫描Activity
integrator.setCaptureActivity(ScanPage.class);
解决二维码中中文乱码问题
import java.net.URLDecoder;
// 加码 生成二维码时使用
combinedInfo = URLEncoder.encode(combinedInfo, "UTF-8");
// 解码,扫描二维码时使用
scannedData = URLDecoder.decode(scannedData, "UTF-8");