问题描述:
android项目中集成了Zxing扫码功能,一般扫二维码和商品码。正常扫码都没问题,突然有一天反馈说客户扫出来的码不对(附上条码一张),扫描出来结果为“0887229990646”,比条码生成的具体值多了一个0在前面.
原因分析:
百度上搜寻一番之后都是说码的类型不对导致了自动补齐,找了一个在线生成条码网站试了一下生成其他类型条码都正常,发现是UPC-A的条码扫码后有问题,然后又搜了一下UPC-A相关内容有发现一篇文章中说到
UPC-A条码实际上是EAN-13条码的子集。如果一个EAN-13条码的第一位数字是0,那么这个条码既是EAN-13码也同样是是UPC-A码(去掉开头的0)
应该是条码解析的模式不对然后就去找项目中zxing对应的代码修改就好了。
Zxing代码的详细工作流程就不再重复了可以自行去百度上看一下其他的帖子,最关键的方法就是在DecodeHandler中decode()方法进行扫码解析。
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(
rotatedData, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
// 预览界面最终取到的是个bitmap,然后对其进行解码
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
}
可以看到multiFormatReader是控制用什么样的模式来进行解码的,
multiFormatReader是通过DecodeThread中传入的hints进行设置的,
DecodeHandler(ScanActivity activity, Map<DecodeHintType, Object> hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
this.activity = activity;
}
/**
* This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
* to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
* is important for performance in continuous scan clients.
*
* @param hints The set of hints to use for subsequent calls to decode(image)
*/
public void setHints(Map<DecodeHintType,?> hints) {
this.hints = hints;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
@SuppressWarnings("unchecked")
Collection<BarcodeFormat> formats =
hints == null ? null : (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);
Collection<Reader> readers = new ArrayList<>();
if (formats != null) {
boolean addOneDReader =
formats.contains(BarcodeFormat.UPC_A) ||
formats.contains(BarcodeFormat.UPC_E) ||
formats.contains(BarcodeFormat.EAN_13) ||
formats.contains(BarcodeFormat.EAN_8) ||
formats.contains(BarcodeFormat.CODABAR) ||
formats.contains(BarcodeFormat.CODE_39) ||
formats.contains(BarcodeFormat.CODE_93) ||
formats.contains(BarcodeFormat.CODE_128) ||
formats.contains(BarcodeFormat.ITF) ||
formats.contains(BarcodeFormat.RSS_14) ||
formats.contains(BarcodeFormat.RSS_EXPANDED);
// Put 1D readers upfront in "normal" mode
if (addOneDReader && !tryHarder) {
readers.add(new MultiFormatOneDReader(hints));
}
if (formats.contains(BarcodeFormat.QR_CODE)) {
readers.add(new QRCodeReader());
}
if (formats.contains(BarcodeFormat.DATA_MATRIX)) {
readers.add(new DataMatrixReader());
}
if (formats.contains(BarcodeFormat.AZTEC)) {
readers.add(new AztecReader());
}
if (formats.contains(BarcodeFormat.PDF_417)) {
readers.add(new