(android 开源项目)二维码、条形码扫描——使用Google ZXing .
2013-10-28 15:59
417 查看
我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。
可以到http://code.google.com/p/zxing/下载ZXing项目的源码,然后按照官方文档进行开发,我这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程截图如下:
其中encoding包是我在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。
先来看看最后的效果:
首先是根据输入的字符串生成二维码图片(左图),然后扫描二维码图片可以在界面上显示扫描结果(右图):
点击Open Camera按钮代开扫描框(左图),扫描条形码结果如下(右图):
接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:
[html]
view plaincopyprint?
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
还有就是扫描界面Activity的配置:
[html]
view plaincopyprint?
<activity
android:configChanges="orientation|keyboardHidden"
android:name="com.zxing.activity.CaptureActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
接下来是我自己项目的布局文件:
[html]
view plaincopyprint?
<?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/btn_scan_barcode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="Open camera" />
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="10dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="18sp"
android:text="Scan result:" />
<TextView
android:id="@+id/tv_scan_result"
android:layout_width="fill_parent"
android:textSize="18sp"
android:textColor="@android:color/black"
android:layout_height="wrap_content" />
</LinearLayout>
<EditText
android:id="@+id/et_qr_string"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="Input the text"/>
<Button
android:id="@+id/btn_add_qrcode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Generate QRcode" />
<ImageView
android:id="@+id/iv_qr_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center"/>
</LinearLayout>
下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:
[java]
view plaincopyprint?
public class BarCodeTestActivity extends Activity {
/** Called when the activity is first created. */
private TextView resultTextView;
private EditText qrStrEditText;
private ImageView qrImgImageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
scanBarCodeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//打开扫描界面扫描条形码或二维码
Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);
startActivityForResult(openCameraIntent, 0);
}
});
Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
generateQRCodeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
String contentString = qrStrEditText.getText().toString();
if (!contentString.equals("")) {
//根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
qrImgImageView.setImageBitmap(qrCodeBitmap);
}else {
Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();
}
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
@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);
}
}
}
其中生成二维码图片的代码在EncodingHandler.java中:
[java]
view plaincopyprint?
public final class EncodingHandler {
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;
}
}
最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:
[java]
view plaincopyprint?
/**
* 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, "Scan failed!", 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();
}
以上过程没有把每一步的详细步骤写出来,整体思路基本大致如上
可以到http://code.google.com/p/zxing/下载ZXing项目的源码,然后按照官方文档进行开发,我这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程截图如下:
其中encoding包是我在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。
先来看看最后的效果:
首先是根据输入的字符串生成二维码图片(左图),然后扫描二维码图片可以在界面上显示扫描结果(右图):
点击Open Camera按钮代开扫描框(左图),扫描条形码结果如下(右图):
接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:
[html]
view plaincopyprint?
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
还有就是扫描界面Activity的配置:
[html]
view plaincopyprint?
<activity
android:configChanges="orientation|keyboardHidden"
android:name="com.zxing.activity.CaptureActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
<activity android:configChanges="orientation|keyboardHidden" android:name="com.zxing.activity.CaptureActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden" > </activity>
接下来是我自己项目的布局文件:
[html]
view plaincopyprint?
<?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/btn_scan_barcode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="Open camera" />
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="10dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="18sp"
android:text="Scan result:" />
<TextView
android:id="@+id/tv_scan_result"
android:layout_width="fill_parent"
android:textSize="18sp"
android:textColor="@android:color/black"
android:layout_height="wrap_content" />
</LinearLayout>
<EditText
android:id="@+id/et_qr_string"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="Input the text"/>
<Button
android:id="@+id/btn_add_qrcode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Generate QRcode" />
<ImageView
android:id="@+id/iv_qr_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center"/>
</LinearLayout>
<?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/btn_scan_barcode" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="Open camera" /> <LinearLayout android:orientation="horizontal" android:layout_marginTop="10dp" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/black" android:textSize="18sp" android:text="Scan result:" /> <TextView android:id="@+id/tv_scan_result" android:layout_width="fill_parent" android:textSize="18sp" android:textColor="@android:color/black" android:layout_height="wrap_content" /> </LinearLayout> <EditText android:id="@+id/et_qr_string" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:hint="Input the text"/> <Button android:id="@+id/btn_add_qrcode" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Generate QRcode" /> <ImageView android:id="@+id/iv_qr_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_gravity="center"/> </LinearLayout>
下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:
[java]
view plaincopyprint?
public class BarCodeTestActivity extends Activity {
/** Called when the activity is first created. */
private TextView resultTextView;
private EditText qrStrEditText;
private ImageView qrImgImageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
scanBarCodeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//打开扫描界面扫描条形码或二维码
Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);
startActivityForResult(openCameraIntent, 0);
}
});
Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
generateQRCodeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
String contentString = qrStrEditText.getText().toString();
if (!contentString.equals("")) {
//根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
qrImgImageView.setImageBitmap(qrCodeBitmap);
}else {
Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();
}
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
@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 class BarCodeTestActivity extends Activity { /** Called when the activity is first created. */ private TextView resultTextView; private EditText qrStrEditText; private ImageView qrImgImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); resultTextView = (TextView) this.findViewById(R.id.tv_scan_result); qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string); qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image); Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode); scanBarCodeButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //打开扫描界面扫描条形码或二维码 Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class); startActivityForResult(openCameraIntent, 0); } }); Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode); generateQRCodeButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { String contentString = qrStrEditText.getText().toString(); if (!contentString.equals("")) { //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350) Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350); qrImgImageView.setImageBitmap(qrCodeBitmap); }else { Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show(); } } catch (WriterException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } @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); } } }
其中生成二维码图片的代码在EncodingHandler.java中:
[java]
view plaincopyprint?
public final class EncodingHandler {
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;
}
}
public final class EncodingHandler { 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; } }
最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:
[java]
view plaincopyprint?
/**
* 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, "Scan failed!", 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();
}
/** * 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, "Scan failed!", 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(); }
以上过程没有把每一步的详细步骤写出来,整体思路基本大致如上
相关文章推荐
- 【android】二维码、条形码扫描——使用Google ZXing
- [置顶] Android移动开发-在Android项目里集成开源框架ZXing实现扫描二维码的功能
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
- 二维码、条形码扫描——使用Google ZXing
- 二维码、条形码扫描——使用Google ZXing
- Android二维码开源项目zxing用例简化和生成二维码、条形码
- 二维码、条形码扫描——使用Google ZXing
- 二维码、条形码扫描——使用Google ZXing
- 二维码、条形码扫描——使用Google ZXing
- 使用zxing生成QRCode二维码,在Android的webview中调用条形码扫描
- android开发(17) 扫描二维码 - 调用第三方APK来实现二维码扫描,参考自 开源项目zxing
- android 项目学习随笔二十一(IM、语音识别、机器人、统计、扫描二维码、条形码)
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
- android 5.1 api21以上怎么使用google zxing 扫描二维码
- 在Android中使用 Google ZXing 实现二维码、条形码扫描
- android 5.1 api21以上怎么使用google zxing 扫描二维码
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
- 二维码、条形码扫描——使用Google ZXing
- 在Android中使用 Google ZXing 实现二维码、条形码扫描