关于生成扫描二维码的操作可使用GitHub的开源库ZXing:https://github.com/zxing/zxing
我在项目中使用了Zxing的精简库https://github.com/azhong1011/libzxing
将libzxing作为module导入项目
一、生成二维码(可添加logo)
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.azhong);
/**
* 第一个参数:需要转换成二维码的内容
* 第二个参数:二维码的宽度
* 第三个参数:二维码的高度
* 第四个参数:Logo图片
*/
Bitmap bitmap = EncodingUtils.createQRCode("test", 500, 500, logo);
二、生成的二维码长按保存相册
ig_qrcode.setImageBitmap(bitmap);
ig_qrcode.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
String[] items = new String[]{"保存图片"};
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityQRCode.this);
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
saveImageToGallery(context,bitmap);
}
});
builder.show();
return true;
}
});
/**
* 将二维码图片保存到文件夹
*
*
* @param context
* @param bmp
*/
public static void saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片
String externalStorageState = Environment.getExternalStorageState();
//判断sd卡是否挂载
if (externalStorageState.equals(Environment.MEDIA_MOUNTED)) {
/*外部存储可用,则保存到外部存储*/
//创建一个文件夹
File appDir = new File(Environment.getExternalStorageDirectory(), "二维码");
//如果文件夹不存在
if (!appDir.exists()) {
//则创建这个文件夹
appDir.mkdir();
}
//将bitmap保存
save(context, bmp, appDir,parklot);
} else {
//外部不可用,将图片保存到内部存储中,获取内部存储文件目录
File filesDir = context.getFilesDir();
//保存
save(context, bmp, filesDir,imageName);
}
}
private static void save(Context context, Bitmap bmp, File appDir ,String name) {
//命名文件名称
String fileName = name + "_" + new Date().getTime() + ".jpg";
//创建图片文件,传入文件夹和文件名
File imagePath = new File(appDir, fileName);
try {
//创建文件输出流,传入图片文件,用于输入bitmap
FileOutputStream fos = new FileOutputStream(imagePath);
//将bitmap压缩成png,并保存到相应的文件夹中
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
//冲刷流
fos.flush();
//关闭流
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 其次把文件插入到系统图库
try {
MediaStore.Images.Media.insertImage(context.getContentResolver(),
imagePath.getAbsolutePath(), fileName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 最后通知图库更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + imagePath.getAbsolutePath())));
}
三、扫描二维码
//需要以带返回结果的方式启动扫描界面
Intent intent = new Intent(oneActivity.this, CaptureActivity.class);
startActivityForResult(intent, 0);
//重写onActivityResult方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0){
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
//获取扫描结果
String result = bundle.getString("result");
tv_result.setText(result);
}
}
}
四、扫描在相册中的二维码
1、在libzxing中layout activity_capture.xml中添加TextView“相册” tv_openpic
2、在CaptureActivity中为tv_openpic增加监听事件:
tv_openpic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent innerIntent = new Intent(); // "android.intent.action.GET_CONTENT"
if (Build.VERSION.SDK_INT < 19) {
innerIntent.setAction(Intent.ACTION_GET_CONTENT);
} else {
// innerIntent.setAction(Intent.ACTION_OPEN_DOCUMENT);
innerIntent.setAction(Intent.ACTION_PICK);
}
innerIntent.setType("image/*");
Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");
CaptureActivity.this
.startActivityForResult(wrapperIntent, 0);
}
});
重写onActivityResult方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 0:
String[] proj = { MediaStore.Images.Media.DATA };
// 获取选中图片的路径
Cursor cursor = getContentResolver().query(data.getData(),
proj, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int column_index = cursor
.getColumnIndexOrThrow(proj[0]);
photo_path = cursor.getString(column_index);
}
cursor.close();
new Thread(new Runnable() {
@Override
public void run() {
Result result = scanningImage(photo_path);
// String result = decode(photo_path);
if (result == null) {
Looper.prepare();
Toast.makeText(getApplicationContext(), "图片格式有误",Toast.LENGTH_SHORT).show();
Looper.loop();
} else {
// 数据返回
inactivityTimer.onActivity();
beepManager.playBeepSoundAndVibrate();
String recode = recode(result.toString());
Intent resultIntent = new Intent();
resultIntent.putExtra("result", recode);
setResult(RESULT_OK, resultIntent);
finish();
}
}
}).start();
break;
}
}
}
protected Result scanningImage(String path) {
if (TextUtils.isEmpty(path)) {
return null;
}
// DecodeHintType 和EncodeHintType
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码
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[] data = new int[scanBitmap.getWidth() * scanBitmap.getHeight()];
scanBitmap.getPixels(data, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap.getWidth(),scanBitmap.getHeight(),data);
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;
}
private String recode(String str) {
String formart = "";
try {
boolean ISO = Charset.forName("ISO-8859-1").newEncoder()
.canEncode(str);
if (ISO) {
formart = new String(str.getBytes("ISO-8859-1"), "GB2312");
Log.i("1234 ISO8859-1", formart);
} else {
formart = str;
Log.i("1234 stringExtra", str);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return formart;
}
五、二维码效果
在libzing中EncodingUtils类中可以看出生成二维码方法是
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
heightPix, hints);
encode方法:
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints)
EncodeHintType为二维码的一些设置:
public enum EncodeHintType {
ERROR_CORRECTION,
CHARACTER_SET,
DATA_MATRIX_SHAPE,
MIN_SIZE,
MAX_SIZE,
MARGIN,
PDF417_COMPACT,
PDF417_COMPACTION,
PDF417_DIMENSIONS,
AZTEC_LAYERS;
private EncodeHintType() {
}
}
其中ERROR_CORRECTION为容错级别
CHARACTER_SET为字符转码格式
MARGIN为二维码空白边框大小
可以如下配置参数
// 配置参数
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 容错级别
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN,1);
参考:https://blog.csdn.net/a_zhon/article/details/52551554
https://blog.csdn.net/qiuqi12/article/details/72270969
https://blog.csdn.net/cdhahaha/article/details/64439558