修改zxing里的CaptureManager,使扫描后不结束activity。
扫描activity的代码如下:
package com.byxc.scanning;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
/**
* 扫描二维码
* Created by ypp on 2018/5/16.
*/
public class ScanningActivity extends Activity {
private final String TAG="ScanningActivity";
private CustomerCaptureManager captureManager;//扫描
private DecoratedBarcodeView dbv_custom;
/**
* 当前闪光灯是否打开了
*/
private boolean isTorchOn=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_scanning);
dbv_custom=(DecoratedBarcodeView)findViewById(R.id.dbv_custom);
//重要代码,初始化捕获
initCapture();
// isScanHandler.sendEmptyMessageDelayed(0,30000);//30秒未扫描到,提示
}
/**
* 初始化捕捉
*/
private void initCapture(){
if(captureManager!=null){
captureManager.onDestroy();
captureManager=null;
}
captureManager = new CustomerCaptureManager(this,dbv_custom,scanningListener);
captureManager.initializeFromIntent(getIntent(),null);
captureManager.decode();
}
/**
* 扫描结果监听
*/
private CustomerCaptureManager.ScanningListener scanningListener=new CustomerCaptureManager.ScanningListener(){
@Override
public void scanResult(String result) {
HLog.toast(ScanningActivity.this,result);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
initCapture();
}
},500);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
captureManager.onSaveInstanceState(outState);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return dbv_custom.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
public void onResume()
{
super.onResume();
captureManager.onResume();
}
public void onPause()
{
super.onPause();
captureManager.onPause();
}
/**
* 切换闪光灯
* @param view
*/
public void openOrCloseTorch(View view) {
if(isTorchOn){
if(hasTorch()){
TextView flash_btn=(TextView)findViewById(R.id.flash_btn);
flash_btn.setBackgroundResource(R.drawable.close_flash_light_bg);
flash_btn.setText(getResources().getString(R.string.open_flash_light));
dbv_custom.setTorchOff();
}
}else{
if(hasTorch()){
TextView flash_btn=(TextView)findViewById(R.id.flash_btn);
flash_btn.setBackgroundResource(R.drawable.open_flash_light_bg);
flash_btn.setText(getResources().getString(R.string.close_flash_light));
dbv_custom.setTorchOn();
}
}
isTorchOn=!isTorchOn;
}
/**
* 判断是否有闪光灯
* @return
*/
public boolean hasTorch(){
return getApplication().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
}
CustomerCaptureManager代码:
package com.byxc.scanning;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.Window;
import android.view.WindowManager;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
import com.google.zxing.client.android.Intents;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.CameraPreview;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* 原CaptureManager不满足持续扫描的需求,所以进行修改
* Created by ypp on 2018/5/24.
*/
public class CustomerCaptureManager {
private static final String TAG = CaptureManager.class.getSimpleName();
private static int cameraPermissionReqCode = 250;
private Activity activity;
private DecoratedBarcodeView barcodeView;
private int orientationLock = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
private static final String SAVED_ORIENTATION_LOCK = "SAVED_ORIENTATION_LOCK";
private boolean returnBarcodeImagePath = false;
private boolean destroyed = false;
// Delay long enough that the beep can be played.
// TODO: play beep in background
private static final long DELAY_BEEP = 150;
// private InactivityTimer inactivityTimer;
private BeepManager beepManager;
private Handler handler;
private ScanningListener scanningListener;
private BarcodeCallback callback = new BarcodeCallback() {
@Override
public void barcodeResult(final BarcodeResult result) {
barcodeView.pause();
beepManager.playBeepSoundAndVibrate();
handler.postDelayed(new Runnable() {
@Override
public void run() {
returnResult(result);
}
}, DELAY_BEEP);
}
@Override
public void possibleResultPoints(List resultPoints) {
}
};
private final CameraPreview.StateListener stateListener = new CameraPreview.StateListener() {
@Override
public void previewSized() {
}
@Override
public void previewStarted() {
HLog.v(TAG,"previewStarted","预览开始");
}
@Override
public void previewStopped() {
HLog.v(TAG,"previewStarted","预览停止");
}
@Override
public void cameraError(Exception error) {
displayFrameworkBugMessageAndExit();
}
};
public CustomerCaptureManager(Activity activity, DecoratedBarcodeView barcodeView, ScanningListener scanningListener) {
this.activity = activity;
this.barcodeView = barcodeView;
this.scanningListener=scanningListener;
barcodeView.getBarcodeView().pause();//先停止,再重启
barcodeView.getBarcodeView().resume();
barcodeView.getBarcodeView().addStateListener(stateListener);
handler = new Handler();
// inactivityTimer = new InactivityTimer(activity, new Runnable() {
// @Override
// public void run() {
// Log.d(TAG, "Finishing due to inactivity");
// finish();
// }
// });
beepManager = new BeepManager(activity);
}
/**
* Perform initialization, according to preferences set in the intent.
*
* @param intent the intent containing the scanning preferences
* @param savedInstanceState saved state, containing orientation lock
*/
public void initializeFromIntent(Intent intent, Bundle savedInstanceState) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (savedInstanceState != null) {
// If the screen was locked and unlocked again, we may start in a different orientation
// (even one not allowed by the manifest). In this case we restore the orientation we were
// previously locked to.
this.orientationLock = savedInstanceState.getInt(SAVED_ORIENTATION_LOCK, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
if(intent != null) {
if (orientationLock == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
// Only lock the orientation if it's not locked to something else yet
boolean orientationLocked = intent.getBooleanExtra(Intents.Scan.ORIENTATION_LOCKED, true);
if (orientationLocked) {
lockOrientation();
}
}
if (Intents.Scan.ACTION.equals(intent.getAction())) {
barcodeView.initializeFromIntent(intent);
}
if (!intent.getBooleanExtra(Intents.Scan.BEEP_ENABLED, true)) {
beepManager.setBeepEnabled(false);
beepManager.updatePrefs();
}
if (intent.hasExtra(Intents.Scan.TIMEOUT)) {
Runnable runnable = new Runnable() {
@Override
public void run() {
returnResultTimeout();
}
};
handler.postDelayed(runnable, intent.getLongExtra(Intents.Scan.TIMEOUT, 0L));
}
if (intent.getBooleanExtra(Intents.Scan.BARCODE_IMAGE_ENABLED, false)) {
returnBarcodeImagePath = true;
}
}
}
/**
* Lock display to current orientation.
*/
protected void lockOrientation() {
// Only get the orientation if it's not locked to one yet.
if (this.orientationLock == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
// Adapted from http://stackoverflow.com/a/14565436
Display display = activity.getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
int baseOrientation = activity.getResources().getConfiguration().orientation;
int orientation = 0;
if (baseOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
} else if (baseOrientation == Configuration.ORIENTATION_PORTRAIT) {
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270) {
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else {
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
}
this.orientationLock = orientation;
}
//noinspection ResourceType
activity.setRequestedOrientation(this.orientationLock);
}
/**
* Start decoding.
*/
public void decode() {
barcodeView.decodeSingle(callback);
}
/**
* Call from Activity#onResume().
*/
public void onResume() {
if(Build.VERSION.SDK_INT >= 23) {
openCameraWithPermission();
} else {
barcodeView.resume();
}
beepManager.updatePrefs();
// inactivityTimer.start();
}
private boolean askedPermission = false;
@TargetApi(23)
private void openCameraWithPermission() {
if (ContextCompat.checkSelfPermission(this.activity, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
barcodeView.resume();
} else if(!askedPermission) {
ActivityCompat.requestPermissions(this.activity,
new String[]{Manifest.permission.CAMERA},
cameraPermissionReqCode);
askedPermission = true;
} else {
// Wait for permission result
}
}
/**
* Call from Activity#onRequestPermissionsResult
* @param requestCode
* @param permissions
* @param grantResults
*/
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if(requestCode == cameraPermissionReqCode) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
barcodeView.resume();
} else {
// TODO: display better error message.
displayFrameworkBugMessageAndExit();
}
}
}
/**
* Call from Activity#onPause().
*/
public void onPause() {
barcodeView.pause();
// inactivityTimer.cancel();
beepManager.close();
}
/**
* Call from Activity#onDestroy().
*/
public void onDestroy() {
destroyed = true;
// inactivityTimer.cancel();
}
/**
* Call from Activity#onSaveInstanceState().
*/
public void onSaveInstanceState(Bundle outState) {
outState.putInt(SAVED_ORIENTATION_LOCK, this.orientationLock);
}
/**
* Create a intent to return as the Activity result.
*
* @param rawResult the BarcodeResult, must not be null.
* @param barcodeImagePath a path to an exported file of the Barcode Image, can be null.
* @return the Intent
*/
public static Intent resultIntent(BarcodeResult rawResult, String barcodeImagePath) {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Intents.Scan.RESULT, rawResult.toString());
intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());
byte[] rawBytes = rawResult.getRawBytes();
if (rawBytes != null && rawBytes.length > 0) {
intent.putExtra(Intents.Scan.RESULT_BYTES, rawBytes);
}
Map metadata = rawResult.getResultMetadata();
if (metadata != null) {
if (metadata.containsKey(ResultMetadataType.UPC_EAN_EXTENSION)) {
intent.putExtra(Intents.Scan.RESULT_UPC_EAN_EXTENSION,
metadata.get(ResultMetadataType.UPC_EAN_EXTENSION).toString());
}
Number orientation = (Number) metadata.get(ResultMetadataType.ORIENTATION);
if (orientation != null) {
intent.putExtra(Intents.Scan.RESULT_ORIENTATION, orientation.intValue());
}
String ecLevel = (String) metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL);
if (ecLevel != null) {
intent.putExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL, ecLevel);
}
@SuppressWarnings("unchecked")
Iterable byteSegments = (Iterable) metadata.get(ResultMetadataType.BYTE_SEGMENTS);
if (byteSegments != null) {
int i = 0;
for (byte[] byteSegment : byteSegments) {
intent.putExtra(Intents.Scan.RESULT_BYTE_SEGMENTS_PREFIX + i, byteSegment);
i++;
}
}
}
if (barcodeImagePath != null) {
intent.putExtra(Intents.Scan.RESULT_BARCODE_IMAGE_PATH, barcodeImagePath);
}
return intent;
}
/**
* Save the barcode image to a temporary file stored in the application's cache, and return its path.
* Only does so if returnBarcodeImagePath is enabled.
*
* @param rawResult the BarcodeResult, must not be null
* @return the path or null
*/
private String getBarcodeImagePath(BarcodeResult rawResult) {
String barcodeImagePath = null;
if (returnBarcodeImagePath) {
Bitmap bmp = rawResult.getBitmap();
try {
File bitmapFile = File.createTempFile("barcodeimage", ".jpg", activity.getCacheDir());
FileOutputStream outputStream = new FileOutputStream(bitmapFile);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
barcodeImagePath = bitmapFile.getAbsolutePath();
} catch (IOException e) {
Log.w(TAG, "Unable to create temporary file and store bitmap! " + e);
}
}
return barcodeImagePath;
}
private void finish() {
activity.finish();
}
protected void returnResultTimeout() {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.putExtra(Intents.Scan.TIMEOUT, true);
activity.setResult(Activity.RESULT_CANCELED, intent);
finish();
}
protected void returnResult(BarcodeResult rawResult) {
if(scanningListener!=null){
scanningListener.scanResult(rawResult.toString());
}
// Intent intent = resultIntent(rawResult, getBarcodeImagePath(rawResult));
// activity.setResult(Activity.RESULT_OK, intent);
// finish();
}
protected void displayFrameworkBugMessageAndExit() {
if (activity.isFinishing() || this.destroyed) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(activity.getString(com.google.zxing.client.android.R.string.zxing_app_name));
builder.setMessage(activity.getString(com.google.zxing.client.android.R.string.zxing_msg_camera_framework_bug));
builder.setPositiveButton(com.google.zxing.client.android.R.string.zxing_button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
finish();
}
});
builder.show();
}
public static int getCameraPermissionReqCode() {
return cameraPermissionReqCode;
}
public static void setCameraPermissionReqCode(int cameraPermissionReqCode) {
CustomerCaptureManager.cameraPermissionReqCode = cameraPermissionReqCode;
}
public interface ScanningListener{
void scanResult(String result);
}
}
demo下载 https://download.csdn.net/download/a123473915/10437062