diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 87e65cf..71ac3c4 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/README.md b/README.md
index 1732b4c..82aee78 100644
--- a/README.md
+++ b/README.md
@@ -40,17 +40,17 @@ ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成
com.king.zxing
zxing-lite
- 1.0.5
+ 1.0.6
pom
```
### Gradle:
```gradle
-implementation 'com.king.zxing:zxing-lite:1.0.5'
+implementation 'com.king.zxing:zxing-lite:1.0.6'
```
### Lvy:
```lvy
-
+
```
@@ -99,6 +99,14 @@ api 'com.google.zxing:core:3.3.3'
更多使用详情,请查看[app](app)中的源码使用示例
+## 版本记录
+#### v1.0.6:2019-1-16
+* 支持连续扫码
+* 支持横屏扫码(主要为了支持Pad)
+
+#### v1.0.5:2018-12-29
+* 支持自定义扫码框宽高
+
## 关于我
Name: Jenly
diff --git a/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java b/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java
index 054aa1c..ec9dc9e 100644
--- a/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java
+++ b/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java
@@ -21,6 +21,7 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
+import com.google.zxing.Result;
import com.king.zxing.CaptureActivity;
import com.king.zxing.app.util.StatusBarUtils;
@@ -46,6 +47,9 @@ public class CustomCaptureActivity extends CaptureActivity {
getBeepManager().setVibrate(true);
}
+ /**
+ * 关闭闪光灯(手电筒)
+ */
private void offFlash(){
Camera camera = getCameraManager().getOpenCamera().getCamera();
Camera.Parameters parameters = camera.getParameters();
@@ -53,6 +57,9 @@ public class CustomCaptureActivity extends CaptureActivity {
camera.setParameters(parameters);
}
+ /**
+ * 开启闪光灯(手电筒)
+ */
public void openFlash(){
Camera camera = getCameraManager().getOpenCamera().getCamera();
Camera.Parameters parameters = camera.getParameters();
@@ -60,6 +67,34 @@ public class CustomCaptureActivity extends CaptureActivity {
camera.setParameters(parameters);
}
+ /**
+ * 接收扫码结果,想支持连扫时,可将{@link #isContinuousScan()}返回为{@code true}并重写此方法
+ * 如果{@link #isContinuousScan()}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
+ * 请将{@link #isAutoRestartPreviewAndDecode()}返回为{@code false},并手动调用{@link #restartPreviewAndDecode()}
+ * @param result 扫码结果
+ */
+ @Override
+ public void onResult(Result result) {
+ super.onResult(result);
+ }
+
+ /**
+ * 是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
+ * @return 默认返回 false
+ */
+ @Override
+ public boolean isContinuousScan() {
+ return super.isContinuousScan();
+ }
+
+ /**
+ * 是否自动重启扫码和解码器,当支持连扫时才起作用。
+ * @return 默认返回 true
+ */
+ @Override
+ public boolean isAutoRestartPreviewAndDecode() {
+ return super.isAutoRestartPreviewAndDecode();
+ }
private void clickFlash(View v){
if(v.isSelected()){
diff --git a/lib/src/main/java/com/king/zxing/CaptureActivity.java b/lib/src/main/java/com/king/zxing/CaptureActivity.java
index 90e4b33..a56145f 100644
--- a/lib/src/main/java/com/king/zxing/CaptureActivity.java
+++ b/lib/src/main/java/com/king/zxing/CaptureActivity.java
@@ -38,6 +38,7 @@ import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
@@ -178,12 +179,6 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
handler = null;
lastResult = null;
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
- } else {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- }
-
resetStatusView();
@@ -443,6 +438,50 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
// do nothing
}
+ /**
+ * 重新启动扫码和解码器
+ */
+ public void restartPreviewAndDecode(){
+ if(handler!=null){
+ handler.restartPreviewAndDecode();
+ }
+ }
+
+ /**
+ * 接收扫码结果,想支持连扫时,可将{@link #isContinuousScan()}返回为{@code true}并重写此方法
+ * 如果{@link #isContinuousScan()}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
+ * 请将{@link #isAutoRestartPreviewAndDecode()}返回为{@code false},并手动调用{@link #restartPreviewAndDecode()}
+ * @param result 扫码结果
+ */
+ public void onResult(Result result){
+ if(isContinuousScan()){
+ if(isAutoRestartPreviewAndDecode()){
+ restartPreviewAndDecode();
+ }
+ }else{
+ Intent intent = new Intent();
+ intent.putExtra(KEY_RESULT,result.getText());
+ setResult(RESULT_OK,intent);
+ finish();
+ }
+ }
+
+ /**
+ * 是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
+ * @return 默认返回 false
+ */
+ public boolean isContinuousScan(){
+ return false;
+ }
+
+ /**
+ * 是否自动重启扫码和解码器,当支持连扫时才起作用。
+ * @return 默认返回 true
+ */
+ public boolean isAutoRestartPreviewAndDecode(){
+ return true;
+ }
+
/**
* A valid barcode has been found, so give an indication of success and show the results.
*
@@ -456,11 +495,9 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
if(isBeepSoundAndVibrate()){
beepManager.playBeepSoundAndVibrate();
}
- String resultString = rawResult.getText();
- Intent intent = new Intent();
- intent.putExtra(KEY_RESULT,resultString);
- setResult(RESULT_OK,intent);
- finish();
+
+ onResult(rawResult);
+
// ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
diff --git a/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java b/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java
index 8af9ccb..1af3c59 100644
--- a/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java
+++ b/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java
@@ -158,7 +158,7 @@ public final class CaptureActivityHandler extends Handler {
removeMessages(R.id.decode_failed);
}
- private void restartPreviewAndDecode() {
+ public void restartPreviewAndDecode() {
if (state == State.SUCCESS) {
state = State.PREVIEW;
cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
diff --git a/lib/src/main/java/com/king/zxing/DecodeHandler.java b/lib/src/main/java/com/king/zxing/DecodeHandler.java
index fd47e76..c6c5860 100644
--- a/lib/src/main/java/com/king/zxing/DecodeHandler.java
+++ b/lib/src/main/java/com/king/zxing/DecodeHandler.java
@@ -16,20 +16,26 @@ package com.king.zxing;
*/
+import android.content.Context;
import android.graphics.Bitmap;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
+import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
+import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
+import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
import java.io.ByteArrayOutputStream;
import java.util.Map;
@@ -54,7 +60,7 @@ final class DecodeHandler extends Handler {
return;
}
if (message.what == R.id.decode) {
- decode((byte[]) message.obj, message.arg1, message.arg2);
+ decode((byte[]) message.obj, message.arg1, message.arg2,isScreenPortrait());
} else if (message.what == R.id.quit) {
running = false;
@@ -63,6 +69,14 @@ final class DecodeHandler extends Handler {
}
}
+ private boolean isScreenPortrait(){
+ WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
+ Display display = manager.getDefaultDisplay();
+ Point screenResolution = new Point();
+ display.getSize(screenResolution);
+ return screenResolution.x < screenResolution.y;
+ }
+
/**
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
* reuse the same reader objects from one decode to the next.
@@ -71,24 +85,34 @@ final class DecodeHandler extends Handler {
* @param width The width of the preview frame.
* @param height The height of the preview frame.
*/
- private void decode(byte[] data, int width, int height) {
+ private void decode(byte[] data, int width, int height,boolean isScreenPortrait) {
long start = System.currentTimeMillis();
Result rawResult = null;
- byte[] rotatedData = new byte[data.length];
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++)
- rotatedData[x * height + height - y - 1] = data[x + y * width];
+ PlanarYUVLuminanceSource source;
+ if(isScreenPortrait){
+ byte[] rotatedData = new byte[data.length];
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++)
+ rotatedData[x * height + height - y - 1] = data[x + y * width];
+ }
+ int tmp = width;
+ width = height;
+ height = tmp;
+ source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
+ }else{
+ source = activity.getCameraManager().buildLuminanceSource(data, width, height);
}
- int tmp = width;
- width = height;
- height = tmp;
- PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
- } catch (ReaderException re) {
- // continue
+ } catch (Exception e) {
+ BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
+ try {
+ rawResult = multiFormatReader.decode(bitmap1);
+ } catch (NotFoundException ne) {
+
+ }
} finally {
multiFormatReader.reset();
}
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
index d6813d0..61b1576 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
@@ -108,8 +108,7 @@ final class CameraConfigurationManager {
}
*/
- cwRotationFromDisplayToCamera =
- (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
+ cwRotationFromDisplayToCamera = (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
Log.i(TAG, "Final display orientation: " + cwRotationFromDisplayToCamera);
if (camera.getFacing() == CameraFacing.FRONT) {
Log.i(TAG, "Compensating rotation for front camera");
@@ -162,7 +161,6 @@ final class CameraConfigurationManager {
parameters.setZoom(parameters.getMaxZoom() / 10);
}
- theCamera.setDisplayOrientation(90);
theCamera.setParameters(parameters);
initializeTorch(parameters, prefs, safeMode);
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
index ebddc20..15efb04 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
@@ -45,7 +45,7 @@ public final class CameraConfigurationUtils {
private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
- private static final double MAX_ASPECT_DISTORTION = 0.10;
+ private static final double MAX_ASPECT_DISTORTION = 0.05;
private static final int MIN_FPS = 10;
private static final int MAX_FPS = 20;
private static final int AREA_PER_1000 = 400;
@@ -292,10 +292,16 @@ public final class CameraConfigurationUtils {
Log.i(TAG, "Supported preview sizes: " + previewSizesString);
}
- double screenAspectRatio = screenResolution.x / (double) screenResolution.y;
+ double screenAspectRatio;
+ if(screenResolution.x < screenResolution.y){
+ screenAspectRatio = screenResolution.x / (double) screenResolution.y;
+ }else{
+ screenAspectRatio = screenResolution.y / (double) screenResolution.x;
+ }
Log.i(TAG, "screenAspectRatio: " + screenAspectRatio);
// Find a suitable size, with max resolution
int maxResolution = 0;
+
Camera.Size maxResPreviewSize = null;
for (Camera.Size size : rawSupportedSizes) {
int realWidth = size.width;
@@ -309,6 +315,7 @@ public final class CameraConfigurationUtils {
int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
Log.i(TAG, String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
+
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
Log.i(TAG, "aspectRatio: " + aspectRatio);
double distortion = Math.abs(aspectRatio - screenAspectRatio);
@@ -330,21 +337,6 @@ public final class CameraConfigurationUtils {
}
}
- if (!rawSupportedSizes.isEmpty()) {
- Collections.sort(rawSupportedSizes, new Comparator() {
- @Override
- public int compare(Camera.Size o1, Camera.Size o2) {
- int delta1 = Math.abs(o1.height-screenResolution.x);
- int delta2 = Math.abs(o2.height-screenResolution.x);
- return delta1 - delta2;
- }
- });
- Camera.Size bestPreview = rawSupportedSizes.get(0);
- Point bestSize = new Point(bestPreview.width, bestPreview.height);
- Log.i(TAG, "Using largest suitable bestSize: " + bestSize);
- return bestSize;
- }
-
// If no exact match, use largest preview size. This was not a great idea on older devices because
// of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
// the CPU is much more powerful.
diff --git a/lib/src/main/java/com/king/zxing/util/CodeUtils.java b/lib/src/main/java/com/king/zxing/util/CodeUtils.java
index b7bdc90..dfa9a8a 100644
--- a/lib/src/main/java/com/king/zxing/util/CodeUtils.java
+++ b/lib/src/main/java/com/king/zxing/util/CodeUtils.java
@@ -31,10 +31,12 @@ import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
@@ -188,7 +190,25 @@ public class CodeUtils {
*/
public static String parseQRCode(String bitmapPath, Map hints){
try {
- Result result = new QRCodeReader().decode(getBinaryBitmap(compressBitmap(bitmapPath)), hints);
+ QRCodeReader reader = new QRCodeReader();
+
+ Result result = null;
+ RGBLuminanceSource source = getRGBLuminanceSource(compressBitmap(bitmapPath));
+ if (source != null) {
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ try {
+ result = reader.decode(bitmap,hints);
+ } catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
+ BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
+ try {
+ result = reader.decode(bitmap1);
+ } catch (NotFoundException ne) {
+
+ }
+ } finally {
+ reader.reset();
+ }
+ }
return result.getText();
} catch (Exception e) {
e.printStackTrace();
@@ -223,10 +243,27 @@ public class CodeUtils {
* @return
*/
public static String parseCode(String bitmapPath, Map hints){
+
try {
MultiFormatReader reader = new MultiFormatReader();
reader.setHints(hints);
- Result result = reader.decodeWithState(getBinaryBitmap(compressBitmap(bitmapPath)));
+ Result result = null;
+ RGBLuminanceSource source = getRGBLuminanceSource(compressBitmap(bitmapPath));
+ if (source != null) {
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ try {
+ result = reader.decodeWithState(bitmap);
+ } catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
+ BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
+ try {
+ result = reader.decodeWithState(bitmap1);
+ } catch (NotFoundException ne) {
+
+ }
+ } finally {
+ reader.reset();
+ }
+ }
return result.getText();
} catch (Exception e) {
e.printStackTrace();
@@ -234,6 +271,8 @@ public class CodeUtils {
return null;
}
+
+
/**
* 压缩图片
* @param path
@@ -265,19 +304,18 @@ public class CodeUtils {
}
/**
- * 获取二进制图片
+ * 获取RGBLuminanceSource
* @param bitmap
* @return
*/
- private static BinaryBitmap getBinaryBitmap(@NonNull Bitmap bitmap){
+ private static RGBLuminanceSource getRGBLuminanceSource(@NonNull Bitmap bitmap){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
- RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
- //得到二进制图片
- return new BinaryBitmap(new HybridBinarizer(source));
+ return new RGBLuminanceSource(width, height, pixels);
+
}
/**
diff --git a/versions.gradle b/versions.gradle
index 9bf86aa..9ae88d2 100644
--- a/versions.gradle
+++ b/versions.gradle
@@ -1,7 +1,7 @@
//App
def app_version = [:]
-app_version.versionCode = 6
-app_version.versionName = "1.0.5"
+app_version.versionCode = 7
+app_version.versionName = "1.0.6"
ext.app_version = app_version
//build version