最近又在倒腾二维码,发现网上的教程都不够用,所以把之前整合的二维码Demo有拿出来重新添加些功能,这里也算是重新学习吧!
当然对于二维码,相信大家都很熟悉了。这里就不多说。本项目是基于Zxing的开源项目开发的。
这里用的Demo是之前网上搜的教程。时间久了,也就忘了,大家网上应该可以搜到,当然如果不想那么麻烦,可以下载我的这个Demo,用的时候直接用就行了。这里我新添加了一些功能。
好吧不说废话了,进入主题:
首先写好布局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/white"
- android:orientation="vertical" >
- <Button
- android:id="@+id/bt_bigin_scan"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:text="开始扫描" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="二维码信息:"
- android:textColor="@android:color/black"
- android:textSize="18sp" />
- <EditText
- android:id="@+id/scan_result"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textColor="@android:color/black"
- android:textSize="18sp" />
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:onClick="checkResult"
- android:text="进入网页" />
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:onClick="Create2QR"
- android:text="生成二维码" />
- <ImageView
- android:id="@+id/iv_qr_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- />
- </LinearLayout>
- package com.androidzhang.zxingframe;
- import android.app.Activity;
- import android.content.Intent;
- import android.graphics.Bitmap;
- import android.net.Uri;
- import android.os.Bundle;
- import android.util.DisplayMetrics;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import com.google.zxing.WriterException;
- import com.zxing.activity.CaptureActivity;
- public class ZxingFrame extends Activity {
- private EditText resultTextView;
- private Button scanBarCodeButton;
- private ImageView iv_qr_image;
- protected int mScreenWidth ;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_zxing_frame);
- resultTextView = (EditText) this.findViewById(R.id.scan_result);
- scanBarCodeButton = (Button) this.findViewById(R.id.bt_bigin_scan);
- iv_qr_image = (ImageView)findViewById(R.id.iv_qr_image);
- DisplayMetrics dm = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(dm);
- mScreenWidth = dm.widthPixels;
- scanBarCodeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // 调用ZXIng开源项目源码 扫描二维码
- Intent openCameraIntent = new Intent(ZxingFrame.this,
- CaptureActivity.class);
- startActivityForResult(openCameraIntent, 0);
- }
- });
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- // 取得返回信息
- if (resultCode == RESULT_OK) {
- Bundle bundle = data.getExtras();
- String scanResult = bundle.getString("result");
- resultTextView.setText(scanResult);
- }
- }
- //调用浏览器打开,功能尚未完善、、、
- public void checkResult(View v){
- String result = resultTextView.getText().toString();
- // Intent intent = new Intent(ZxingFrame.this,
- // CheckResult.class);
- // intent.putExtra("result", result);
- // startActivity(intent);
- Intent i= new Intent();
- i.setAction("android.intent.action.VIEW");
- Uri content_url = Uri.parse(result);
- i.setData(content_url);
- i.setClassName("com.android.browser","com.android.browser.BrowserActivity");
- startActivity(i);
- }
- //生成二维码
- public void Create2QR(View v){
- String uri = resultTextView.getText().toString();
- // Bitmap bitmap = BitmapUtil.create2DCoderBitmap(uri, mScreenWidth/2, mScreenWidth/2);
- Bitmap bitmap;
- try {
- bitmap = BitmapUtil.createQRCode(uri, mScreenWidth);
- if(bitmap != null){
- iv_qr_image.setImageBitmap(bitmap);
- }
- } catch (WriterException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
上面每个函数都注释的很清楚了。
接着就是处理了:都在CaptureActivity
这里扫描二维码需要用到的结果:
- /**
- * Handler scan result
- *
- * @param result
- * @param barcode
- * 获取结果
- */
- public void handleDecode(Result result, Bitmap barcode) {
- inactivityTimer.onActivity();
- playBeepSoundAndVibrate();
- String resultString = result.getText();
- // FIXME
- if (resultString.equals("")) {
- Toast.makeText(CaptureActivity.this, "扫描失败!", Toast.LENGTH_SHORT)
- .show();
- } else {
- // System.out.println("Result:"+resultString);
- Intent resultIntent = new Intent();
- Bundle bundle = new Bundle();
- bundle.putString("result", resultString);
- resultIntent.putExtras(bundle);
- this.setResult(RESULT_OK, resultIntent);
- }
- CaptureActivity.this.finish();
- }
其中添加的是否打开闪光灯:
- // 是否开启闪光灯
- public void IfOpenLight(View v) {
- ifOpenLight++;
- switch (ifOpenLight % 2) {
- case 0:
- // 关闭
- CameraManager.get().closeLight();
- break;
- case 1:
- // 打开
- CameraManager.get().openLight(); // 开闪光灯
- break;
- default:
- break;
- }
- }
接着就是从相册中获取带有二维码的照片,然后解析二维码:(这个功能还不够强大,对于只有二维码的图片能解析成功,如果图片含有其他干扰就不一定能解析出来了。希望有大神能够指点指点。。。)
- /*
- * 获取带二维码的相片进行扫描
- */
- public void pickPictureFromAblum(View v) {
- // 打开手机中的相册
- Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
- innerIntent.setType("image/*");
- Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");
- this.startActivityForResult(wrapperIntent, 1);
- }
- String photo_path;
- ProgressDialog mProgress;
- Bitmap scanBitmap;
- /*
- * (non-Javadoc)
- *
- * @see android.app.Activity#onActivityResult(int, int,
- * android.content.Intent) 对相册获取的结果进行分析
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // TODO Auto-generated method stub
- if (resultCode == RESULT_OK) {
- switch (requestCode) {
- case 1:
- // 获取选中图片的路径
- Cursor cursor = getContentResolver().query(data.getData(),
- null, null, null, null);
- if (cursor.moveToFirst()) {
- photo_path = cursor.getString(cursor
- .getColumnIndex(MediaStore.Images.Media.DATA));
- Log.i("路径", photo_path);
- }
- cursor.close();
- mProgress = new ProgressDialog(CaptureActivity.this);
- mProgress.setMessage("正在扫描...");
- mProgress.setCancelable(false);
- mProgress.show();
- new Thread(new Runnable() {
- @Override
- public void run() {
- Result result = scanningImage(photo_path);
- if (result != null) {
- Message m = mHandler.obtainMessage();
- m.what = 1;
- m.obj = result.getText();
- mHandler.sendMessage(m);
- } else {
- Message m = mHandler.obtainMessage();
- m.what = 2;
- m.obj = "Scan failed!";
- mHandler.sendMessage(m);
- }
- }
- }).start();
- break;
- default:
- break;
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
- final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- switch (msg.what) {
- case 1:
- mProgress.dismiss();
- String resultString = msg.obj.toString();
- if (resultString.equals("")) {
- Toast.makeText(CaptureActivity.this, "扫描失败!",
- Toast.LENGTH_SHORT).show();
- } else {
- // System.out.println("Result:"+resultString);
- Intent resultIntent = new Intent();
- Bundle bundle = new Bundle();
- bundle.putString("result", resultString);
- resultIntent.putExtras(bundle);
- CaptureActivity.this.setResult(RESULT_OK, resultIntent);
- }
- CaptureActivity.this.finish();
- break;
- case 2:
- mProgress.dismiss();
- Toast.makeText(CaptureActivity.this, "解析错误!", Toast.LENGTH_LONG)
- .show();
- break;
- default:
- break;
- }
- super.handleMessage(msg);
- }
- };
- /**
- * 扫描二维码图片的方法
- *
- * 目前识别度不高,有待改进
- *
- * @param path
- * @return
- */
- public Result scanningImage(String path) {
- if (TextUtils.isEmpty(path)) {
- return null;
- }
- Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
- hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true; // 先获取原大小
- scanBitmap = BitmapFactory.decodeFile(path, options);
- options.inJustDecodeBounds = false; // 获取新的大小
- int sampleSize = (int) (options.outHeight / (float) 100);
- if (sampleSize <= 0)
- sampleSize = 1;
- options.inSampleSize = sampleSize;
- scanBitmap = BitmapFactory.decodeFile(path, options);
- RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);
- BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
- QRCodeReader reader = new QRCodeReader();
- try {
- return reader.decode(bitmap1, hints);
- } catch (NotFoundException e) {
- e.printStackTrace();
- } catch (ChecksumException e) {
- e.printStackTrace();
- } catch (FormatException e) {
- e.printStackTrace();
- }
- return null;
- }
剩下一个主要的功能就是生成二维码:
- package com.androidzhang.zxingframe;
- import java.util.Hashtable;
- import android.graphics.Bitmap;
- import android.util.Log;
- 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;
- import com.google.zxing.qrcode.QRCodeWriter;
- public class BitmapUtil {
- /**
- * 生成一个二维码图像
- *
- * @param url
- * 传入的字符串,通常是一个URL
- * @param QR_WIDTH
- * 宽度(像素值px)
- * @param QR_HEIGHT
- * 高度(像素值px)
- * @return
- */
- public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH,
- int QR_HEIGHT) {
- try {
- // 判断URL合法性
- if (url == null || "".equals(url) || url.length() < 1) {
- return null;
- }
- Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
- hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
- // 图像数据转换,使用了矩阵转换
- BitMatrix bitMatrix = new QRCodeWriter().encode(url,
- BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
- int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
- // 下面这里按照二维码的算法,逐个生成二维码的图片,
- // 两个for循环是图片横列扫描的结果
- for (int y = 0; y < QR_HEIGHT; y++) {
- for (int x = 0; x < QR_WIDTH; x++) {
- if (bitMatrix.get(x, y)) {
- pixels[y * QR_WIDTH + x] = 0xff000000;
- } else {
- pixels[y * QR_WIDTH + x] = 0xffffffff;
- }
- }
- }
- // 生成二维码图片的格式,使用ARGB_8888
- Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,
- Bitmap.Config.ARGB_8888);
- bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
- // 显示到一个ImageView上面
- // sweepIV.setImageBitmap(bitmap);
- return bitmap;
- } catch (WriterException e) {
- Log.i("log", "生成二维码错误" + e.getMessage());
- return null;
- }
- }
- private static final int BLACK = 0xff000000;
- /**
- * 生成一个二维码图像
- *
- * @param url
- * 传入的字符串,通常是一个URL
- * @param widthAndHeight
- * 图像的宽高
- * @return
- */
- 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;
- }
- }
这里写了两种方法,都能用。
这里功能基本上够用了,剩下的自己再琢磨琢磨吧!
还是那句话: 演示图:
源代码下载地址:http://download.csdn.net/detail/xiaorenwu1206/7785619
原文地址:http://blog.csdn.net/xiaorenwu1206/article/details/38684983
希望有高手指点其中的不足啊!小白谢过。。。