ZXing 是一个比较完善的与二维码相关的框架,里面有很多有趣的东西,现在我要实现的只是其中最基础的扫描二维码功能和生成二维码功能。
1、通过添加模块的方式将 ZXing 添加到项目中
2、使用 ZXing 实现想要的扫码和生成二维码功能
1、通过添加模块的方式将 ZXing 添加到项目中
添加方式为:
File > New > Import Module…
然后选择要添加的模块
选中要添加的模块之后
这里我已经添加过了所以模块名字起冲突了
下面是添加好之后的项目目录
添加好之后需要进行简单的配置
第一步:在 settings.gradle 中添加 模块名称
第二步:File > Project Structurn… 进入依赖设置
选中项目(app) 选择 Dependencies 点击 + 号添加,选择 Module dependency,将里面的 zxinglib 添加到 app 的Dependencies 里面,如上图所示,这时就完成了 ZXing 模块添加
2、使用 ZXing 实现想要的扫码和生成二维码功能
效果
扫码(MP4转gif的,看起来有点卡)
生成
不多说,直接上代码
需要权限 AndroidManifest.xml (可能有些用不到)
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!-- unavailable in API 23 -->
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_sweepCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击扫码二维码" />
<EditText
android:id="@+id/tv_codeReturn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="数据"
app:layout_constraintTop_toBottomOf="@+id/btn_sweepCode"/>
<Button
android:id="@+id/btn_generateCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击生成二维码"
app:layout_constraintTop_toBottomOf="@+id/tv_codeReturn"/>
<Button
android:id="@+id/btn_generateCodeImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击有图生成二维码"
app:layout_constraintTop_toBottomOf="@+id/btn_generateCode"/>
<ImageView
android:id="@+id/iv_code"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_generateCodeImage" />
</android.support.constraint.ConstraintLayout>
MainActivity
package com.example.zxing;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.zxing.utils.QRCodeUtil;
import com.skateboard.zxinglib.CaptureActivity;
public class MainActivity extends AppCompatActivity {
private Button btn_sweepCode;
private TextView tv_codeReturn;
private Button btn_generateCode;
private ImageView iv_code;
private Button btn_generateCodeImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
setPermissions();//动态权限
//点击扫码
btn_sweepCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent,1001);
}
});
//点击生成普通二维码
btn_generateCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String generateCode = tv_codeReturn.getText().toString();
QRCodeUtil.createQRcodeImage(generateCode, iv_code);
}
});
//点击生成中间带图片的二维码
btn_generateCodeImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String generateCode = tv_codeReturn.getText().toString();
QRCodeUtil.createQRcodeImage(MainActivity.this,generateCode, iv_code);
}
});
}
public void init(){
btn_sweepCode = findViewById(R.id.btn_sweepCode);
tv_codeReturn = findViewById(R.id.tv_codeReturn);
btn_generateCode = findViewById(R.id.btn_generateCode);
iv_code = findViewById(R.id.iv_code);
btn_generateCodeImage = findViewById(R.id.btn_generateCodeImage);
}
/**
* 动态权限申请(相机)
*/
private void setPermissions() {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
else{
Log.i("Jurisdiction","权限申请ok");
}
}
//扫码回掉
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1001 && resultCode== Activity.RESULT_OK) {
String result = data.getStringExtra(CaptureActivity.KEY_DATA);
tv_codeReturn.setText(result);//显示在输入框中
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
}
QRCodeUtil (生成二维码的工具类)
package com.example.zxing.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.widget.ImageView;
import com.example.zxing.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.util.Hashtable;
public class QRCodeUtil {
//无图
public static void createQRcodeImage(String url, ImageView im1) {
int w= im1.getWidth();
int h= im1.getHeight();
try {
//判断URL合法性
if (url == null || "".equals(url) || url.length() < 1) {
return;
}
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, w, h, hints);
int[] pixels = new int[w * h];
//下面这里按照二维码的算法,逐个生成二维码的图片,
//两个for循环是图片横列扫描的结果
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * w + x] = 0xff000000;
} else {
pixels[y * w + x] = 0xffffffff;
}
}
}
//生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
//显示到我们的ImageView上面
im1.setImageBitmap(bitmap);
}
catch (WriterException e) {
e.printStackTrace();
}
}
//有图
public static void createQRcodeImage(Context context, String url, ImageView im1) {
int w= im1.getWidth();
int h= im1.getHeight();
try {
//判断URL合法性
if (url == null || "".equals(url) || url.length() < 1) {
return;
}
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, w, h, hints);
int[] pixels = new int[w * h];
//下面这里按照二维码的算法,逐个生成二维码的图片,
//两个for循环是图片横列扫描的结果
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * w + x] = 0xff000000;
} else {
pixels[y * w + x] = 0xffffffff;
}
}
}
//生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
//显示到我们的ImageView上面s
bitmap = addLogo(bitmap, BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher_round));
im1.setImageBitmap(bitmap);
}
catch (WriterException e) {
e.printStackTrace();
}
}
//给二维码添加图片
//第一个参数为原二维码,第二个参数为添加的logo
private static Bitmap addLogo(Bitmap src, Bitmap logo) {
//如果原二维码为空,返回空
if (src ==null ) {
return null;
}
//如果logo为空,返回原二维码
if (src ==null ||logo ==null) {
return src;
}
//这里得到原二维码bitmap的数据
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
//logo的Width和Height
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();
//同样如果为空,返回空
if (srcWidth == 0 || srcHeight == 0) {
return null;
}
//同样logo大小为0,返回原二维码
if (logoWidth == 0 || logoHeight == 0) {
return src;
}
//logo大小为二维码整体大小的1/5,也可以自定义多大,越小越好
//二维码有一定的纠错功能,中间图片越小,越容易纠错
float 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.restore();
} catch (Exception e) {
bitmap = null;
e.getStackTrace();
}
return bitmap;
}
}
最后,附上github链接 https://github.com/iscopy/ZXing 可以直接拷贝使用我项目中的 zxinglib