Android 开发中使用到二维码生成和解析

来源:互联网 发布:厦门网游网络 编辑:程序博客网 时间:2024/06/07 23:27
  • 二维码生成
  • 二维码解析

    在项目的开发中, 使用二维码作为数据传递 交换 已经是常态了! 在这我也讲讲自己在项目开发中使用到的二维码.

  • 生成二维码的开发流程

    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~~~ 最后相信大家基本了解二维码了吧!

0 0