博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android二维码开源项目zxing用例简化和生成二维码、条形码
阅读量:6255 次
发布时间:2019-06-22

本文共 9611 字,大约阅读时间需要 32 分钟。

上一篇讲到:,编译出来后有一个自带的測试程序:CaptureActivity比較复杂,我仅仅要是把一些不用的东西去掉,用看起来更方便,二维码和条形码的流行性自不必说了。

自带的样例,文件夹结构例如以下:

改动后的程序文件夹结构,去掉了非常多功能,假设分享、设置等。

先上效果图

        

扫描ZXing生成的条形码和二维码结果

扫描界面

扫描商品的条码

整个程序仅仅改动了下面两个类,其他都是直接从原来的Demo中复制出来的

生成二维码的代码

/**	 * 生成二维码 要转换的地址或字符串,能够是中文	 * 	 * @param url	 * @param width	 * @param height	 * @return	 */	public Bitmap createQRImage(String url, final int width, final int height) {		try {			// 推断URL合法性			if (url == null || "".equals(url) || url.length() < 1) {				return null;			}			Hashtable
hints = new Hashtable
(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 图像数据转换,使用了矩阵转换 BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints); int[] pixels = new int[width * height]; // 以下这里依照二维码的算法,逐个生成二维码的图片, // 两个for循环是图片横列扫描的结果 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (bitMatrix.get(x, y)) { pixels[y * width + x] = 0xff000000; } else { pixels[y * width + x] = 0xffffffff; } } } // 生成二维码图片的格式,使用ARGB_8888 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } catch (WriterException e) { e.printStackTrace(); } return null; }
能够生成中文

生成条形码关键代码,下面代码是把条形码和条形码下的文字合并成一张图片显示。

/**	 * 生成条形码	 * 	 * @param context	 * @param contents	 *            须要生成的内容	 * @param desiredWidth	 *            生成条形码的宽带	 * @param desiredHeight	 *            生成条形码的高度	 * @param displayCode	 *            是否在条形码下方显示内容	 * @return	 */	public 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;	}	/**	 * 生成条形码的Bitmap	 * 	 * @param contents	 *            须要生成的内容	 * @param format	 *            编码格式	 * @param desiredWidth	 * @param desiredHeight	 * @return	 * @throws WriterException	 */	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;	}	/**	 * 生成显示编码的Bitmap	 * 	 * @param contents	 * @param width	 * @param height	 * @param context	 * @return	 */	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;	}	/**	 * 将两个Bitmap合并成一个	 * 	 * @param first	 * @param second	 * @param fromPoint	 *            第二个Bitmap開始绘制的起始位置(相对于第一个Bitmap)	 * @return	 */	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;	}
CaptureActivity.java是扫描二维码和条形码的界面,对Camera进行初始化和开启扫描线程

private void initCamera(SurfaceHolder surfaceHolder) {		if (surfaceHolder == null) {			throw new IllegalStateException("No SurfaceHolder provided");		}		if (cameraManager.isOpen()) {			ZXingApplication					.print_i("CaptureActivity",							"initCamera() while already open -- late SurfaceView callback?");			return;		}		try {			cameraManager.openDriver(surfaceHolder);		} catch (IOException ioe) {			return;		} catch (RuntimeException e) {			return;		}		if (handler == null) {			handler = new CaptureActivityHandler(this, decodeFormats,					decodeHints, characterSet, cameraManager);		}		ZXingApplication.print_i("CaptureActivity",				"initCamera-----------finish");	}
在CaptureActivityHandler.java类中会处理扫描的结果

@Override	public void handleMessage(Message message) {		switch (message.what) {		case R.id.restart_preview:			restartPreviewAndDecode();			break;		case R.id.decode_succeeded:			state = State.SUCCESS;			Bundle bundle = message.getData();			Bitmap barcode = null;			float scaleFactor = 1.0f;			if (bundle != null) {				byte[] compressedBitmap = bundle						.getByteArray(DecodeThread.BARCODE_BITMAP);				if (compressedBitmap != null) {					barcode = BitmapFactory.decodeByteArray(compressedBitmap,							0, compressedBitmap.length, null);					// Mutable copy:					barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);				}				scaleFactor = bundle						.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);			}			activity.handleDecode((Result) message.obj, barcode, scaleFactor);			break;		case R.id.decode_failed:			// We're decoding as fast as possible, so when one decode fails,			// start another.			state = State.PREVIEW;			cameraManager.requestPreviewFrame(decodeThread.getHandler(),					R.id.decode);			break;		case R.id.return_scan_result:			activity.setResult(Activity.RESULT_OK, (Intent) message.obj);			activity.finish();			break;		case R.id.launch_product_query:			String url = (String) message.obj;			Intent intent = new Intent(Intent.ACTION_VIEW);			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);			intent.setData(Uri.parse(url));			ResolveInfo resolveInfo = activity.getPackageManager()					.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);			String browserPackageName = null;			if (resolveInfo != null && resolveInfo.activityInfo != null) {				browserPackageName = resolveInfo.activityInfo.packageName;				Log.d(TAG, "Using browser in package " + browserPackageName);			}			// Needed for default Android browser / Chrome only apparently			if ("com.android.browser".equals(browserPackageName)					|| "com.android.chrome".equals(browserPackageName)) {				intent.setPackage(browserPackageName);				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);				intent.putExtra(Browser.EXTRA_APPLICATION_ID,						browserPackageName);			}			try {				activity.startActivity(intent);			} catch (ActivityNotFoundException ignored) {				Log.w(TAG, "Can't find anything to handle VIEW of URI " + url);			}			break;		}	}
在case R.id.decode_succeeded 分支会通过activity.handleDecode((Result) message.obj, barcode, scaleFactor);回传结果给Activity

/**	 * 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();		// ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(		// this, rawResult);		boolean fromLiveScan = barcode != null;		AlertDialog.Builder dialog = new AlertDialog.Builder(this);		if (barcode == null) {			dialog.setIcon(null);		} else {			Drawable drawable = new BitmapDrawable(barcode);			dialog.setIcon(drawable);		}		dialog.setTitle("扫描结果");		dialog.setMessage(rawResult.getText());		dialog.setNegativeButton("确定", new DialogInterface.OnClickListener() {			@Override			public void onClick(DialogInterface dialog, int which) {				// 用默认浏览器打开扫描得到的地址				Intent intent = new Intent();				intent.setAction("android.intent.action.VIEW");				Uri content_url = Uri.parse(rawResult.getText());				intent.setData(content_url);				startActivity(intent);				finish();			}		});		dialog.setPositiveButton("取消", new DialogInterface.OnClickListener() {			@Override			public void onClick(DialogInterface dialog, int which) {				finish();			}		});		dialog.create().show();	}
这里仅仅是把扫描的结果显示出来,实际上能够依据不同的须要来处理,假设扫描出二维码能够用HTTP来打开,有一点要注意的,我的ADT版本号是V23.0.2.1259578,须要执行的4.0的系统上

演示样例代码:

你可能感兴趣的文章
JavaScript "use strict" 使用
查看>>
MySQL主从自动配置脚本
查看>>
速度发射点发射点发
查看>>
物联网智能硬件设备常见攻击方法
查看>>
[转]异常争论
查看>>
利用Boost::Python实现C++调用python接口
查看>>
将sublime打造成python的IDE开发工具
查看>>
Enterprise Architect(EA)的一些使用技巧和心得(逐渐添加)
查看>>
Apache的安全性,SSL在Solaris 10
查看>>
CentOS 5.11开启VNC访问
查看>>
Mac Homebrew 利器
查看>>
源码安装apache 虚拟主机
查看>>
discuz 数据库密码修改后 管理后台不能登录问题
查看>>
ISA Server 2006简介
查看>>
TCP-IP协议详解(13) DNS协议
查看>>
httpd网站服务
查看>>
mysql启动报错处理
查看>>
4 ways to pass parameter from JSF page to backi...
查看>>
Delphi中获取Unix时间戳及注意事项
查看>>
rvm使用
查看>>