package com.barcode;
import java.io.IOException;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Map;
import java.util.Vector;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.text.ClipboardManager;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import com.barcode.camera.CameraManager;
import com.barcode.decode.CaptureActivityHandler;
import com.barcode.decode.FinishListener;
import com.barcode.decode.InactivityTimer;
import com.barcode.view.ViewfinderView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.ResultMetadataType;
import com.txsc.R;
/**
* 扫描二维码
*
* @author 火蚁(http://my.oschina/LittleDY)
*
*/
@SuppressWarnings("deprecation")
public class CaptureAty extends Activity implements SurfaceHolder.Callback,
View.OnClickListener {
private boolean hasSurface;
private String characterSet;
private ViewfinderView viewfinderView;
private ImageView back;
private ImageView flash;
private ProgressDialog mProgress;
/**
* 活动监控器,用于省电,如果手机没有连接电源线,那么当相机开启后如果一直处于不被使用状态则该服务会将当前activity关闭。
* 活动监控器全程监控扫描活跃状态,与CaptureActivity生命周期相同.每一次扫描过后都会重置该监控,即重新倒计时。
*/
private InactivityTimer inactivityTimer;
private CameraManager cameraManager;
private Vector<BarcodeFormat> decodeFormats;// 编码格式
private CaptureActivityHandler mHandler;// 解码线程
private static final Collection<ResultMetadataType> DISPLAYABLE_METADATA_TYPES = EnumSet
.of(ResultMetadataType.ISSUE_NUMBER,
ResultMetadataType.SUGGESTED_PRICE,
ResultMetadataType.ERROR_CORRECTION_LEVEL,
ResultMetadataType.POSSIBLE_COUNTRY);
@Override
protected void onCreate(Bundle savedInstanceState) {
initSetting();
super.onCreate(savedInstanceState);
setContentView(R.layout.capture_layout_main);
initView();
}
/**
* 初始化窗口设置
*/
private void initSetting() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 保持屏幕处于点亮状态
// window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); // 全屏
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏标题栏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
}
/**
* 初始化视图
*/
private void initView() {
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
back = (ImageView) findViewById(R.id.capture_back);
flash = (ImageView) findViewById(R.id.capture_flash);
back.setOnClickListener(this);
flash.setOnClickListener(this);
}
/**
* 主要对相机进行初始化工作
*/
@Override
protected void onResume() {
inactivityTimer.onActivity();
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
// 如果SurfaceView已经渲染完毕,会回调surfaceCreated,在surfaceCreated中调用initCamera()
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
// 恢复活动监控器
inactivityTimer.onResume();
super.onResume();
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
/**
* 初始化摄像头。打开摄像头,检查摄像头是否被开启及是否被占用
*
* @param surfaceHolder
*/
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the mHandler starts the preview, which can also throw a
// RuntimeException.
if (mHandler == null) {
mHandler = new CaptureActivityHandler(this, decodeFormats,
characterSet, cameraManager);
}
} catch (IOException ioe) {
displayFrameworkBugMessageAndExit();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
displayFrameworkBugMessageAndExit();
}
}
/**
* 初始化照相机失败显示窗口
*/
private void displayFrameworkBugMessageAndExit() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("出错了");
builder.setMessage(getString(R.string.msg_camera_framework_bug));
builder.setPositiveButton("确定", new FinishListener(this));
builder.setOnCancelListener(new FinishListener(this));
builder.show();
}
/**
* 暂停活动监控器,关闭摄像头
*/
@Override
protected void onPause() {
if (mHandler != null) {
mHandler.quitSynchronously();
mHandler = null;
}
// 暂停活动监控器
inactivityTimer.onPause();
// 关闭摄像头
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
if (mProgress != null && mProgress.isShowing()) {
mProgress.dismiss();
}
super.onPause();
}
/**
* 停止活动监控器,保存最后选中的扫描类型
*/
@Override
protected void onDestroy() {
// 停止活动监控器
inactivityTimer.shutdown();
if (mProgress != null) {
mProgress.dismiss();
}
super.onDestroy();
}
/**
* 获取扫描结果
*
* @param rawResult
* @param barcode
* @param scaleFactor
*/
public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
// inactivityTimer.onActivity();
boolean fromLiveScan = barcode != null;
if (fromLiveScan) {
// Then not from history, so beep/vibrate and we have an image to
// draw on
}
Map<ResultMetadataType, Object> metadata = rawResult
.getResultMetadata();
StringBuilder metadataText = new StringBuilder(20);
if (metadata != null) {
for (Map.Entry<ResultMetadataType, Object> entry : metadata
.entrySet()) {
if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {
metadataText.append(entry.getValue()).append('\n');
}
}
if (metadataText.length() > 0) {
metadataText.setLength(metadataText.length() - 1);
}
}
parseBarCode(rawResult.getText());
}
// 解析二维码
private void parseBarCode(String msg) {
// 手机震动
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(100);
mProgress = ProgressDialog.show(CaptureAty.this, null, "已扫描,正在处理···",
true, true);
mProgress.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
restartPreviewAfterDelay(1l);
}
});
// 判断是否符合基本的json格式
if (!msg.matches("^\\{.*")) {
showDialog(msg);
} else {
// TODO
/**
*
* 解析二维码
*/
}
}
/**
* 扫描结果对话框
*
* @param msg
*/
private void showDialog(final String msg) {
new AlertDialog.Builder(CaptureAty.this)
.setTitle("扫描结果")
.setMessage("非天下食材支付二维码\n内容:" + msg)
.setPositiveButton("复制", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mProgress.dismiss();
dialog.dismiss();
// 获取剪贴板管理服务
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
// 将文本数据复制到剪贴板
cm.setText(msg);
}
})
.setNegativeButton("返回", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mProgress.dismiss();
dialog.dismiss();
restartPreviewAfterDelay(0L);
}
}).show();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
/**
* 闪光灯调节器。自动检测环境光线强弱并决定是否开启闪光灯
*/
public ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return mHandler;
}
public CameraManager getCameraManager() {
return cameraManager;
}
/**
* 在经过一段延迟后重置相机以进行下一次扫描。 成功扫描过后可调用此方法立刻准备进行下次扫描
*
* @param delayMS
*/
public void restartPreviewAfterDelay(long delayMS) {
if (mHandler != null) {
mHandler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void setFlash() {
if (flash.getTag() != null) {
cameraManager.setTorch(true);
flash.setTag(null);
flash.setBackgroundResource(R.drawable.qrcode_flash_open);
} else {
cameraManager.setTorch(false);
flash.setTag("1");
flash.setBackgroundResource(R.drawable.qrcode_flash_default);
}
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.capture_back) {
finish();
} else if (id == R.id.capture_flash) {
setFlash();
}
}
}