最近把二维码又弄了下,整出个Demo来,可以直接使用
项目地址:http://download.csdn.net/detail/hello_12413/8747919
项目编码:UTF-8
这个用的就是google提供的zxing包做的,内部算法就不说了,我也没细看。直接所说项目吧,希望对大家有帮助。
项目结构如图:
图中标出的直接拷到项目中,落了个“raw”文件夹。各位注意下。
首先加权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<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.FLASHLIGHT" />
注册扫描页面
<activity android:name="com.support.sdk.zxing.CaptureActivity"></activity>
扫描二维码,条形码
1、打开扫描页面
Intent intent = new Intent(this, CaptureActivity.class);
startActivityForResult(intent, 200);
2、在扫描结束接收返回数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 200) {
String res = data.getStringExtra("result");
res_qr.setText(res);
}
}
}
生成二维码
QRTools qrTools = new QRTools();
Bitmap qr = qrTools.createQRImage(uri);
QRTools.java
package com.support.sdk.zxing;
import java.util.Hashtable;
import android.graphics.Bitmap;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
/**
* 二维码工具类
*
* @author xugang
*
*/
public class QRTools {
/**
* 生成二维码 要转换的地址或字符串,可以是中文
*
* @param url
* @return
*/
public Bitmap createQRImage(String url) {
int width = 400;
int height = 400;
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, 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;
}
}
CaptureActivity.java
package com.support.sdk.zxing;
import java.io.IOException;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.support.sdk.zxing.camera.CameraManager;
import com.support.sdk.zxing.decoding.CaptureActivityHandler;
import com.support.sdk.zxing.decoding.InactivityTimer;
import com.support.sdk.zxing.view.ViewfinderView;
import com.xg.qr.R;
/**
* 扫描二维码,条形码页</br> permission:</br> uses-permission
* android:name="android.permission.CAMERA" </br>uses-permission
* android:name="android.permission.WRITE_EXTERNAL_STORAGE" <br>
* uses-feature android:name="android.hardware.camera" </br>uses-feature
* android:name="android.hardware.camera.autofocus" </br>uses-permission
* android:name="android.permission.VIBRATE" </br>uses-permission
* android:name="android.permission.FLASHLIGHT" </br> activity:</br>
* android:name="com.support.sdk.zxing.CaptureActivity"</br>
* android:clearTaskOnLaunch="true" </br>android:label="@string/app_name"</br>
* android:screenOrientation="sensorLandscape"
* </br>android:stateNotNeeded="true" ></br>
* intent-filter</br> action
* android:name="com.google.zxing.client.android.SCAN" </br>
* category android:name="android.intent.category.DEFAULT"
* </br> intent-filter</br> </activity></br>
*
* @author xugang
*
*/
public class CaptureActivity extends Activity implements Callback, OnClickListener {
public static final String QR_RESULT = "RESULT";
private CaptureActivityHandler handler;
private ViewfinderView viewfinderView;
private SurfaceView surfaceView;
private boolean hasSurface;
private Vector<BarcodeFormat> decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private MediaPlayer mediaPlayer;
private boolean playBeep;
// private static final float BEEP_VOLUME = 0.10f;
private boolean vibrate;
CameraManager cameraManager;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_capture);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinderview);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
findViewById(R.id.back).setOnClickListener(this);
((CheckBox)findViewById(R.id.light)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
if(arg1){
openLight();
}else{
closeLight();
}
}
});
}
//打开闪光灯,不需要再次调用Camera.open()打开摄像头,这样会冲突的,直接使用<span style="font-family: Arial, Helvetica, sans-serif;">cameraManager</span>
private void openLight() {
cameraManager.openFlashLight();
}
private void closeLight() {
cameraManager.offFlashLight();
}
@Override
protected void onResume() {
super.onResume();
if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// CameraManager.init(getApplication());
cameraManager = new CameraManager(getApplication());
viewfinderView.setCameraManager(cameraManager);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
decodeFormats = null;
characterSet = null;
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
}
@Override
protected void onPause() {
super.onPause();
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
cameraManager.closeDriver();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
private void initCamera(SurfaceHolder surfaceHolder) {
try {
// CameraManager.get().openDriver(surfaceHolder);
cameraManager.openDriver(surfaceHolder);
} catch (IOException ioe) {
return;
} catch (RuntimeException e) {
return;
}
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats, characterSet);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
public CameraManager getCameraManager() {
return cameraManager;
}
public ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
public void handleDecode(Result obj, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
showResult(obj, barcode);
}
/**
* 显示结果
*
* @param rawResult
* @param barcode
*/
private void showResult(final Result rawResult, Bitmap barcode) {
Intent intent = new Intent();
// intent.setClass(this, QRResultActivity.class);
intent.putExtra("result", rawResult.getText());
setResult(RESULT_OK, intent);
finish();
// startActivity(intent);
}
public void restartPreviewAfterDelay(long delayMS) {
if (handler != null) {
handler.sendEmptyMessageDelayed(MessageIDs.restart_preview, delayMS);
}
}
private void initBeepSound() {
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it
// too loud,
// so we now play on the music stream.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnCompletionListener(beepListener);
try {
AssetFileDescriptor fileDescriptor = getAssets().openFd("qrbeep.ogg");
this.mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
this.mediaPlayer.setVolume(0.1F, 0.1F);
this.mediaPlayer.prepare();
} catch (IOException e) {
this.mediaPlayer = null;
}
}
}
private static final long VIBRATE_DURATION = 200L;
private void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
/**
* When the beep has finished playing, rewind to queue up another one.
*/
private final OnCompletionListener beepListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(0);
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
setResult(RESULT_CANCELED);
finish();
return true;
} else if (keyCode == KeyEvent.KEYCODE_FOCUS || keyCode == KeyEvent.KEYCODE_CAMERA) {
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.back:
finish();
break;
default:
break;
}
}
}