Android 开发中使用到二维码生成和解析
- 二维码生成
二维码解析
在项目的开发中, 使用二维码作为数据传递 交换 已经是常态了! 在这我也讲讲自己在项目开发中使用到的二维码.
生成二维码的开发流程
1 应用google 给我们提供的zxing.jar (
建议官网下载
)
2 使用zxing.jar 的MultiFormatWriter 类 生成一张二维码图片
核心代码块
/**
* 方法说明:生成无图片二维码
*/
@SuppressWarnings("unused")
private Bitmap createTwoCode(String content) throws WriterException {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 300, 300);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 方法说明:生成有图片二维码
*/
@SuppressWarnings("unused")
private Bitmap createTwoCode(String str, int widthAndHeight) throws WriterException {
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
BitMatrix matrix = new MultiFormatWriter().encode(str, BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
全整的demo 代码
(1) res/layout 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="create2Code"
android:text="生成二维码" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="create2Code"
android:text="扫码" />
<ImageView
android:id="@+id/activity_my_coupons_pic"
android:layout_width="300dip"
android:layout_height="300dip"
android:layout_gravity="center" />
</LinearLayout>
(2) activity 中代码块
package com.gghl.view.wheelcity;
import java.util.Hashtable;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.zf.iosdialog.R;
public class NagitestActivty extends Activity {
private ImageView activity_my_coupons_pic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nagi_testactivity);
activity_my_coupons_pic = (ImageView) this.findViewById(R.id.activity_my_coupons_pic);
}
//生成二维码
public void create2Code(View view) throws WriterException{
String content = "毅神之怒";
Bitmap bmp = createTwoCode(content,300);
Bitmap logoBmp = small(BitmapFactory.decodeResource(getResources(), R.drawable.app_icon));
Bitmap bitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bmp, 0, 0, null);
canvas.drawBitmap(logoBmp, bmp.getWidth() / 2 - logoBmp.getWidth() / 2, bmp.getHeight() / 2 - logoBmp.getHeight() / 2, null);
activity_my_coupons_pic.setImageBitmap(bitmap);
}
/**
* 方法说明:生成无图片二维码
*/
@SuppressWarnings("unused")
private Bitmap createTwoCode(String content) throws WriterException {
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 300, 300);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 方法说明:生成有图片二维码
*/
@SuppressWarnings("unused")
private Bitmap createTwoCode(String str, int widthAndHeight) throws WriterException {
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
BitMatrix matrix = new MultiFormatWriter().encode(str, BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = 0xff000000;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 方法说明:缩小Bitmap
*/
@SuppressWarnings("unused")
private static Bitmap small(Bitmap bitmap) {
Matrix matrix = new Matrix();
matrix.postScale(0.2f, 0.2f);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
return resizeBmp;
}
}
最后的效果:
呵呵, 可以试试使用微信或支付宝扫一扫~~~~ 但是当在真实的项目中,大家改吧改吧就是你们的了!
二维码的扫描
对于二维码的扫描,我只是简单说说原理;
其实在二维码扫描就是读取二维码图片中信息, zxing.jar 也一样的封装好在LuminanceSource.Java 中
// 解析QR图片
private void scanningImage() {
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
// 获得待解析的图片
Bitmap bitmap = ((BitmapDrawable) qr_image.getDrawable()).getBitmap();
RGBLuminanceSource source = new RGBLuminanceSource(bitmap);
BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result result;
try {
result = reader.decode(bitmap1);
result=reader.decode(bitmap1, hints );
// 得到解析后的文字
qr_result.setText(result.getText());
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
}
zxing.jar 中LuminanceSource 核心类
package com.example.ecodetest;
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.FileNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.google.zxing.LuminanceSource;
public final class RGBLuminanceSource extends LuminanceSource {
private final byte[] luminances;
public RGBLuminanceSource(String path) throws FileNotFoundException {
this(loadBitmap(path));
}
public RGBLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
// In order to measure pure decoding speed, we convert the entire image to a greyscale array
// up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
luminances = new byte[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = pixels[offset + x];
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
if (r == g && g == b) {
// Image is already greyscale, so pick any channel.
luminances[offset + x] = (byte) r;
} else {
// Calculate luminance cheaply, favoring green.
luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
}
}
}
}
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
System.arraycopy(luminances, y * width, row, 0, width);
return row;
}
// Since this class does not support cropping, the underlying byte array already contains
// exactly what the caller is asking for, so give it to them without a copy.
public byte[] getMatrix() {
return luminances;
}
private static Bitmap loadBitmap(String path) throws FileNotFoundException {
Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap == null) {
throw new FileNotFoundException("Couldn‘t open " + path);
}
return bitmap;
}
}
看到这里大家可能有一个疑问, 二维码支付是什么做的!
这个时候就是需要与服务器进行交互了, 在我做的这个第三方支付项目中,
我们通过一个Timer定时器不断从访问服务询问用户客户端是否已经支付,
这有点像tcp 协议中的三次握手;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() { // UI thread
@Override
public void run() {
recLen--;
if(recLen < 0){
//获得支付状态
getPayStatus();
recLen = 3;
}
}
});
}
};
timer.schedule(task, 1000, 1000);
如果大家在这一点还是不理解的话, 大家可以看看支付宝的支付宝二维码管理接口api 文档
里面的写的非常详细.
duang~~~ 最后相信大家基本了解二维码了吧!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。