Android ZXing二維碼、條形碼的生成和解析
阿新 • • 發佈:2019-01-31
ZXing(Zebra Crossing)是Google開發的一個二維碼解析和生成的開源庫。
近期的一個手錶專案需要用到二維碼生成,於是就研究了一下。實現起來很簡便,將jar包放入工程,就可以直接使用API了。
裝置將位置資訊更新給伺服器,在瀏覽器輸入URL訪問指定ID裝置的位置資訊。這個URL可以用二維碼的形式展示出來。
1.生成二維碼:
private void initialLayout() { ImageView imageQRCode = (ImageView) findViewById(R.id.imageQRCode); String contentQRCode = Constant.Server.URL_MAP_INDEX + MyApp.deviceId; try { // 根據字串生成二維碼圖片並顯示在介面上,第二個引數為圖片的大小(310*310) Bitmap bitmapQRCode = QRCodeUtil.createQRCode(contentQRCode, 310); imageQRCode.setImageBitmap(bitmapQRCode); } catch (WriterException e) { e.printStackTrace(); } }
QRCodeUtil:
import java.util.Hashtable; import android.graphics.Bitmap; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; public final class QRCodeUtil { private static final int BLACK = 0xff000000; public static Bitmap createQRCode(String str, int widthAndHeight) throws WriterException { Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); hints.put(EncodeHintType.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] = BLACK; } } } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } }
效果圖:
可以用微信掃一掃,也可以用自己寫的解析程式掃描,進入指定的URL。
2.生成條形碼
條形碼有很多種類,二維(條形)碼就是其中一種。表示內容也有不同,有的只能表示純數字,不能表示字母。
BarcodeFormat.CODE_128; // 表示高密度資料, 字串可變長,符號內含校驗碼 BarcodeFormat.CODE_39; BarcodeFormat.CODE_93; BarcodeFormat.CODABAR; // 可表示數字0 - 9,字元$、+、 -、還有隻能用作起始/終止符的a,b,c d四個字元,可變長度,沒有校驗位 BarcodeFormat.DATA_MATRIX; BarcodeFormat.EAN_8; BarcodeFormat.EAN_13; BarcodeFormat.ITF; BarcodeFormat.PDF417; // 二維碼 BarcodeFormat.QR_CODE; // 二維碼 BarcodeFormat.RSS_EXPANDED; BarcodeFormat.RSS14; BarcodeFormat.UPC_E; // 統一產品程式碼E:7位數字,最後一位為校驗位 BarcodeFormat.UPC_A; // 統一產品程式碼A:12位數字,最後一位為校驗位 BarcodeFormat.UPC_EAN_EXTENSION;
ublic static Bitmap creatBarcode(Context context, String contents,
int desiredWidth, int desiredHeight, boolean displayCode) {
Bitmap ruseltBitmap = null;
int marginW = 20;
BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
if (displayCode) {
Bitmap barcodeBitmap = encodeAsBitmap(contents, barcodeFormat,
desiredWidth, desiredHeight);
Bitmap codeBitmap = creatCodeBitmap(contents, desiredWidth + 2
* marginW, desiredHeight, context);
ruseltBitmap = mixtureBitmap(barcodeBitmap, codeBitmap, new PointF(
0, desiredHeight));
} else {
ruseltBitmap = encodeAsBitmap(contents, barcodeFormat,
desiredWidth, desiredHeight);
}
return ruseltBitmap;
}
protected static Bitmap encodeAsBitmap(String contents,
BarcodeFormat format, int desiredWidth, int desiredHeight) {
final int WHITE = 0xFFFFFFFF;
final int BLACK = 0xFF000000;
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix result = null;
try {
result = writer.encode(contents, format, desiredWidth,
desiredHeight, null);
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
// All are 0, or black, by default
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
protected static Bitmap creatCodeBitmap(String contents, int width,
int height, Context context) {
TextView tv = new TextView(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(layoutParams);
tv.setText(contents);
tv.setHeight(height);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setWidth(width);
tv.setDrawingCacheEnabled(true);
tv.setTextColor(Color.BLACK);
tv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
tv.buildDrawingCache();
Bitmap bitmapCode = tv.getDrawingCache();
return bitmapCode;
}
protected static Bitmap mixtureBitmap(Bitmap first, Bitmap second,
PointF fromPoint) {
if (first == null || second == null || fromPoint == null) {
return null;
}
int marginW = 20;
Bitmap newBitmap = Bitmap.createBitmap(
first.getWidth() + second.getWidth() + marginW,
first.getHeight() + second.getHeight(), Config.ARGB_4444);
Canvas cv = new Canvas(newBitmap);
cv.drawBitmap(first, marginW, 0, null);
cv.drawBitmap(second, fromPoint.x, fromPoint.y, null);
cv.save(Canvas.ALL_SAVE_FLAG);
cv.restore();
return newBitmap;
}
creatBarcode的最後一個引數:是否要在條形碼下方顯示生成的內容。
ImageView imageBarCode = (ImageView) findViewById(R.id.imageBarCode);
imageBarCode.setImageBitmap(QRCodeUtil.creatBarcode(
getApplicationContext(), "78480000b4a5", 600, 400, true));
生成結果:
3.解析-zxing.CaptureActivity中handleDecode處理解析好的資料即可:
/**
* A valid barcode has been found, so give an indication of success and show
* the results.
*
* @param rawResult The contents of the barcode.
* @param scaleFactor amount by which thumbnail was scaled
* @param barcode A greyscale bitmap of the camera data which was decoded.
*/
public void handleDecode(final Result rawResult, Bitmap barcode,
float scaleFactor) {
inactivityTimer.onActivity();
boolean fromLiveScan = barcode != null;
if (fromLiveScan) {
beepManager.playBeepSoundAndVibrate();
}
finish();
String scanResult = rawResult.getText();
if (null != scanResult && scanResult.trim().length() > 0) {
Intent intentBind = new Intent(CaptureActivity.this,
BindActivity.class);
intentBind.putExtra("physicalId", scanResult);
startActivity(intentBind);
}
switch (source) {
case NATIVE_APP_INTENT:
case PRODUCT_SEARCH_LINK:
break;
case ZXING_LINK:
break;
case NONE:
break;
}
}