diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index d7a1447..97ee803 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 65f38c1..4e07666 100644
--- a/README.md
+++ b/README.md
@@ -45,17 +45,17 @@ ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成
com.king.zxing
zxing-lite
- 1.0.7
+ 1.1.0
pom
```
### Gradle:
```gradle
-implementation 'com.king.zxing:zxing-lite:1.0.7'
+implementation 'com.king.zxing:zxing-lite:1.1.0'
```
### Lvy:
```lvy
-
+
```
@@ -79,16 +79,20 @@ api 'com.google.zxing:core:3.3.3'
布局示例 (可自定义布局,布局内至少要保证有SurfaceView和ViewfinderView,控件id可根据重写CaptureActivity 的 getPreviewViewId 和 getViewFinderViewId方法自定义)
```Xml
-
+
+
-
+
+
```
代码示例 (二维码/条形码)
@@ -102,9 +106,25 @@ api 'com.google.zxing:core:3.3.3'
CodeUtils.createBarCode(content, BarcodeFormat.CODE_128,800,200);
```
+### 快速实现扫码有以下几种方式:
+
+> 1、直接使用CaptureActivity或者CaptureFragment。(纯洁的扫码,无任何添加剂)
+
+> 2、通过继承CaptureActivity或者CaptureFragment并自定义布局。(适用于大多场景,并无需关心扫码相关逻辑)
+
+> 3、在你项目的Activity或者Fragment中创建创建一个CaptureHelper并在相应的生命周期中调用CaptureHelper的周期。(适用于想在扫码界面写交互逻辑,又因为项目架构或其它原因,无法直接或间接继承CaptureActivity或CaptureFragment时使用)
+
+> 4、参照CaptureHelper写一个自定义的扫码帮助类,其它步骤同方式3。(扩展高级用法,谨慎使用)
+
+
更多使用详情,请查看[app](app)中的源码使用示例
## 版本记录
+
+#### v1.1.0:2019-4-19
+* 将扫码相关逻辑与界面分离,ZXingLite使用更容易扩展。
+* 新增CaptureFragment
+
#### v1.0.7:2019-4-9
* 新增网格样式的扫描激光(类似支付宝扫码样式)
* 升级Gradle至v4.6
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index ece8e6a..0c3126a 100644
Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ
diff --git a/app/release/output.json b/app/release/output.json
index dced801..90a54ae 100644
--- a/app/release/output.json
+++ b/app/release/output.json
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":8,"versionName":"1.0.7","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":9,"versionName":"1.1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 494edf2..51e3d6f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,12 +21,25 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/king/zxing/app/CaptureFragmentActivity.java b/app/src/main/java/com/king/zxing/app/CaptureFragmentActivity.java
new file mode 100644
index 0000000..6155c18
--- /dev/null
+++ b/app/src/main/java/com/king/zxing/app/CaptureFragmentActivity.java
@@ -0,0 +1,39 @@
+package com.king.zxing.app;
+
+import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.widget.TextView;
+
+import com.king.zxing.CaptureFragment;
+import com.king.zxing.app.util.StatusBarUtils;
+
+/**
+ * Fragment扫码
+ * @author Jenly
+ */
+public class CaptureFragmentActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.fragment_activity);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ StatusBarUtils.immersiveStatusBar(this,toolbar,0.2f);
+ TextView tvTitle = findViewById(R.id.tvTitle);
+ tvTitle.setText(getIntent().getStringExtra(MainActivity.KEY_TITLE));
+
+ replaceFragment(CaptureFragment.newInstance());
+ }
+
+ public void replaceFragment(Fragment fragment){
+ replaceFragment( R.id.fragmentContent,fragment);
+ }
+
+ public void replaceFragment(@IdRes int id, Fragment fragment) {
+ getSupportFragmentManager().beginTransaction().replace(id, fragment).commit();
+ }
+}
diff --git a/app/src/main/java/com/king/zxing/app/CustomActivity.java b/app/src/main/java/com/king/zxing/app/CustomActivity.java
new file mode 100644
index 0000000..feffd43
--- /dev/null
+++ b/app/src/main/java/com/king/zxing/app/CustomActivity.java
@@ -0,0 +1,143 @@
+package com.king.zxing.app;
+
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.app.Activity;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.Toolbar;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.king.zxing.CaptureHelper;
+import com.king.zxing.OnCaptureCallback;
+import com.king.zxing.ViewfinderView;
+import com.king.zxing.app.util.StatusBarUtils;
+
+/**
+ * 自定义扫码:当直接使用CaptureActivity
+ * 自定义扫码,切记自定义扫码需在{@link Activity}或者{@link Fragment}相对应的生命周期里面调用{@link #mCaptureHelper}对应的生命周期
+ * @author Jenly
+ */
+public class CustomActivity extends AppCompatActivity implements OnCaptureCallback {
+
+ private boolean isContinuousScan;
+
+ private CaptureHelper mCaptureHelper;
+
+ private SurfaceView surfaceView;
+
+ private ViewfinderView viewfinderView;
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.custom_activity);
+
+ initUI();
+ }
+
+ private void initUI(){
+
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ StatusBarUtils.immersiveStatusBar(this,toolbar,0.2f);
+ TextView tvTitle = findViewById(R.id.tvTitle);
+ tvTitle.setText(getIntent().getStringExtra(MainActivity.KEY_TITLE));
+
+
+ surfaceView = findViewById(R.id.surfaceView);
+ viewfinderView = findViewById(R.id.viewfinderView);
+
+ isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
+
+ mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
+ mCaptureHelper.onCreate();
+ mCaptureHelper.vibrate(true)
+ .continuousScan(isContinuousScan);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mCaptureHelper.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mCaptureHelper.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mCaptureHelper.onDestroy();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ mCaptureHelper.onTouchEvent(event);
+ return super.onTouchEvent(event);
+ }
+
+ /**
+ * 关闭闪光灯(手电筒)
+ */
+ private void offFlash(){
+ Camera camera = mCaptureHelper.getCameraManager().getOpenCamera().getCamera();
+ Camera.Parameters parameters = camera.getParameters();
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ camera.setParameters(parameters);
+ }
+
+ /**
+ * 开启闪光灯(手电筒)
+ */
+ public void openFlash(){
+ Camera camera = mCaptureHelper.getCameraManager().getOpenCamera().getCamera();
+ Camera.Parameters parameters = camera.getParameters();
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
+ camera.setParameters(parameters);
+ }
+
+
+ /**
+ * 扫码结果回调
+ * @param result 扫码结果
+ * @return
+ */
+ @Override
+ public boolean onResultCallback(String result) {
+ if(isContinuousScan){
+ Toast.makeText(this,result,Toast.LENGTH_SHORT).show();
+ }
+ return false;
+ }
+
+
+ private void clickFlash(View v){
+ if(v.isSelected()){
+ offFlash();
+ v.setSelected(false);
+ }else{
+ openFlash();
+ v.setSelected(true);
+ }
+
+ }
+
+ public void OnClick(View v){
+ switch (v.getId()){
+ case R.id.ivLeft:
+ onBackPressed();
+ break;
+ case R.id.ivFlash:
+ clickFlash(v);
+ break;
+ }
+ }
+}
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 fe51539..010e3cf 100644
--- a/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java
+++ b/app/src/main/java/com/king/zxing/app/CustomCaptureActivity.java
@@ -27,6 +27,7 @@ import com.king.zxing.CaptureActivity;
import com.king.zxing.app.util.StatusBarUtils;
/**
+ * 自定义继承CaptureActivity
* @author Jenly Jenly
*/
public class CustomCaptureActivity extends CaptureActivity {
@@ -46,9 +47,10 @@ public class CustomCaptureActivity extends CaptureActivity {
tvTitle.setText(getIntent().getStringExtra(MainActivity.KEY_TITLE));
isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
-
- getBeepManager().setPlayBeep(true);
- getBeepManager().setVibrate(true);
+ //获取CaptureHelper,里面有扫码相关的配置设置
+ getCaptureHelper().playBeep(true)//播放音效
+ .vibrate(true)//震动
+ .continuousScan(isContinuousScan);//是否连扫
}
/**
@@ -71,37 +73,21 @@ public class CustomCaptureActivity extends CaptureActivity {
camera.setParameters(parameters);
}
+
/**
- * 接收扫码结果,想支持连扫时,可将{@link #isContinuousScan()}返回为{@code true}并重写此方法
- * 如果{@link #isContinuousScan()}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
- * 请将{@link #isAutoRestartPreviewAndDecode()}返回为{@code false},并手动调用{@link #restartPreviewAndDecode()}
+ * 扫码结果回调
* @param result 扫码结果
+ * @return
*/
@Override
- public void onResult(Result result) {
- super.onResult(result);
+ public boolean onResultCallback(String result) {
if(isContinuousScan){//连续扫码时,直接弹出结果
- Toast.makeText(this,result.getText(),Toast.LENGTH_SHORT).show();
+ Toast.makeText(this,result,Toast.LENGTH_SHORT).show();
}
+
+ return super.onResultCallback(result);
}
- /**
- * 是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
- * @return 默认返回 false
- */
- @Override
- public boolean isContinuousScan() {
- return isContinuousScan;
- }
-
- /**
- * 是否自动重启扫码和解码器,当支持连扫时才起作用。
- * @return 默认返回 true
- */
- @Override
- public boolean isAutoRestartPreviewAndDecode() {
- return super.isAutoRestartPreviewAndDecode();
- }
private void clickFlash(View v){
if(v.isSelected()){
diff --git a/app/src/main/java/com/king/zxing/app/MainActivity.java b/app/src/main/java/com/king/zxing/app/MainActivity.java
index f98eb1b..6b13bd0 100644
--- a/app/src/main/java/com/king/zxing/app/MainActivity.java
+++ b/app/src/main/java/com/king/zxing/app/MainActivity.java
@@ -18,7 +18,6 @@ package com.king.zxing.app;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
-import android.graphics.BitmapFactory;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
@@ -30,8 +29,6 @@ import android.view.View;
import android.widget.Button;
import android.widget.Toast;
-import com.google.zxing.DecodeHintType;
-import com.google.zxing.common.StringUtils;
import com.king.zxing.CaptureActivity;
import com.king.zxing.Intents;
import com.king.zxing.app.util.UriUtils;
@@ -42,6 +39,20 @@ import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
+/**
+ * 扫码Demo示例说明
+ *
+ * 快速实现扫码有以下几种方式:
+ *
+ * 1、直接使用CaptureActivity或者CaptureFragment。(纯洁的扫码,无任何添加剂)
+ *
+ * 2、通过继承CaptureActivity或者CaptureFragment并自定义布局。(适用于大多场景,并无需关心扫码相关逻辑)
+ *
+ * 3、在你项目的Activity或者Fragment中创建创建一个CaptureHelper并在相应的生命周期中调用CaptureHelper的周期。(适用于想在扫码界面写交互逻辑,又因为项目架构或其它原因,无法直接或间接继承CaptureActivity或CaptureFragment时使用)
+ *
+ * 4、参照CaptureHelper写一个自定义的扫码帮助类,其它步骤同方式3。(扩展高级用法,谨慎使用)
+ *
+ */
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{
public static final String KEY_TITLE = "key_title";
@@ -195,18 +206,18 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
isContinuousScan = false;
switch (v.getId()){
case R.id.btn0:
+ this.cls = CaptureActivity.class;
+ this.title = ((Button)v).getText().toString();
+ checkCameraPermissions();
+ break;
+ case R.id.btn1:
this.cls = CustomCaptureActivity.class;
this.title = ((Button)v).getText().toString();
isContinuousScan = true;
checkCameraPermissions();
break;
- case R.id.btn1:
- this.cls = CaptureActivity.class;
- this.title = ((Button)v).getText().toString();
- checkCameraPermissions();
- break;
case R.id.btn2:
- this.cls = EasyCaptureActivity.class;
+ this.cls = CaptureFragmentActivity.class;
this.title = ((Button)v).getText().toString();
checkCameraPermissions();
break;
@@ -216,12 +227,17 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
checkCameraPermissions();
break;
case R.id.btn4:
- startCode(false);
+ this.cls = CustomActivity.class;
+ this.title = ((Button)v).getText().toString();
+ checkCameraPermissions();
break;
case R.id.btn5:
- startCode(true);
+ startCode(false);
break;
case R.id.btn6:
+ startCode(true);
+ break;
+ case R.id.btn7:
checkExternalStoragePermissions();
break;
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 0d14fb0..52b9a40 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -26,13 +26,6 @@
android:layout_gravity="center_horizontal"
android:text="@string/app_name"/>
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/custom_activity.xml b/app/src/main/res/layout/custom_activity.xml
new file mode 100644
index 0000000..1b5beea
--- /dev/null
+++ b/app/src/main/res/layout/custom_activity.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/custom_capture_activity.xml b/app/src/main/res/layout/custom_capture_activity.xml
index 5737de1..7ccd472 100644
--- a/app/src/main/res/layout/custom_capture_activity.xml
+++ b/app/src/main/res/layout/custom_capture_activity.xml
@@ -6,11 +6,11 @@
android:layout_height="match_parent">
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_activity.xml b/app/src/main/res/layout/fragment_activity.xml
new file mode 100644
index 0000000..33352cf
--- /dev/null
+++ b/app/src/main/res/layout/fragment_activity.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1e791cf..1499da2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,7 +2,7 @@
ZXingLite
App扫码需要用到拍摄权限
App需要用到读写权限
- 将二维码/条形码放入框内,即可自动扫码
+ 将二维码/条形码放入框内,即可自动扫描
二维码
条形码
diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml
index 885f413..bd901ed 100644
--- a/lib/src/main/AndroidManifest.xml
+++ b/lib/src/main/AndroidManifest.xml
@@ -5,14 +5,10 @@
-
-
+
-
-
+
diff --git a/lib/src/main/java/com/king/zxing/BeepManager.java b/lib/src/main/java/com/king/zxing/BeepManager.java
index afc1083..76d0fd9 100644
--- a/lib/src/main/java/com/king/zxing/BeepManager.java
+++ b/lib/src/main/java/com/king/zxing/BeepManager.java
@@ -32,7 +32,7 @@ import java.io.Closeable;
import java.io.IOException;
/**
- * Manages beeps and vibrations for {@link CaptureActivity}.
+ * Manages beeps and vibrations for {@link Activity}.
*/
public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
@@ -62,7 +62,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
synchronized void updatePrefs() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
- playBeep = shouldBeep(prefs, activity);
+ shouldBeep(prefs, activity);
// vibrate = prefs.getBoolean(Preferences.KEY_VIBRATE, false);
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
@@ -83,7 +83,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
}
private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
- boolean shouldPlayBeep = prefs.getBoolean(Preferences.KEY_PLAY_BEEP, true);
+ boolean shouldPlayBeep = prefs.getBoolean(Preferences.KEY_PLAY_BEEP, false);
if (shouldPlayBeep) {
// See if sound settings overrides this
AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
@@ -97,7 +97,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
@TargetApi(Build.VERSION_CODES.KITKAT)
private MediaPlayer buildMediaPlayer(Context activity) {
MediaPlayer mediaPlayer = new MediaPlayer();
- try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep)) {
+ try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.zxl_beep)) {
mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
diff --git a/lib/src/main/java/com/king/zxing/CaptureActivity.java b/lib/src/main/java/com/king/zxing/CaptureActivity.java
index 1a16672..6dc8c8a 100644
--- a/lib/src/main/java/com/king/zxing/CaptureActivity.java
+++ b/lib/src/main/java/com/king/zxing/CaptureActivity.java
@@ -1,7 +1,5 @@
-package com.king.zxing;
-
/*
- * Copyright (C) 2008 ZXing authors
+ * Copyright (C) 2018 Jenly Yu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,948 +13,129 @@ package com.king.zxing;
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+package com.king.zxing;
import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.Camera;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.KeyEvent;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.Nullable;
import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceHolder;
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;
-import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-/**
- * This activity opens the camera and does the actual scanning on a background thread. It draws a
- * viewfinder to help the user place the barcode correctly, shows feedback as the image processing
- * is happening, and then overlays the results when a scan is successful.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- * @author Sean Owen
- */
-public class CaptureActivity extends Activity implements SurfaceHolder.Callback {
+public class CaptureActivity extends Activity implements OnCaptureCallback{
public static final String KEY_RESULT = Intents.Scan.RESULT;
- private static final String TAG = CaptureActivity.class.getSimpleName();
-
-// private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
-// private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
-
- private static final int DEVIATION = 6;
-
- private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
-
-// private static final Collection DISPLAYABLE_METADATA_TYPES =
-// EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
-// ResultMetadataType.SUGGESTED_PRICE,
-// ResultMetadataType.ERROR_CORRECTION_LEVEL,
-// ResultMetadataType.POSSIBLE_COUNTRY);
-
- private CameraManager cameraManager;
- private CaptureActivityHandler handler;
- private Result savedResultToShow;
- private ViewfinderView viewfinderView;
private SurfaceView surfaceView;
- private SurfaceHolder surfaceHolder;
-// private TextView statusView;
-// private View resultView;
- private Result lastResult;
- private boolean hasSurface;
-// private boolean copyToClipboard;
-// private IntentSource source;
-// private String sourceUrl;
-// private ScanFromWebPageManager scanFromWebPageManager;
- private Collection decodeFormats;
- private Map decodeHints;
- private String characterSet;
-// private HistoryManager historyManager;
- private InactivityTimer inactivityTimer;
- private BeepManager beepManager;
- private AmbientLightManager ambientLightManager;
+ private ViewfinderView viewfinderView;
- /**
- * 是否支持缩放(变焦),默认支持
- */
- private boolean isZoom = true;
- private float oldDistance;
-
- public ViewfinderView getViewfinderView() {
- return viewfinderView;
- }
-
- public Handler getHandler() {
- return handler;
- }
-
- public CameraManager getCameraManager() {
- return cameraManager;
- }
-
- public BeepManager getBeepManager() {
- return beepManager;
- }
+ private CaptureHelper mCaptureHelper;
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- Window window = getWindow();
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- setContentView(getLayoutId());
-
- hasSurface = false;
- inactivityTimer = new InactivityTimer(this);
- beepManager = new BeepManager(this);
- ambientLightManager = new AmbientLightManager(this);
-
- viewfinderView = findViewById(getViewFinderViewId());
-
- surfaceView = findViewById(getPreviewViewId());
- surfaceHolder = surfaceView.getHolder();
-
-
- cameraManager = new CameraManager(getApplication());
-
-// PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ int layoutId = getLayoutId();
+ if(isContentView(layoutId)){
+ setContentView(layoutId);
+ }
+ initUI();
}
+ /**
+ * 初始化
+ */
+ public void initUI(){
+ surfaceView = findViewById(getSurfaceViewId());
+ viewfinderView = findViewById(getViewfinderViewId());
+ mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
+ mCaptureHelper.setOnCaptureCallback(this);
+ mCaptureHelper.onCreate();
+ }
+
+ /**
+ * 返回true时会自动初始化{@link #setContentView(int)},返回为false是需自己去初始化{@link #setContentView(int)}
+ * @param layoutId
+ * @return 默认返回true
+ */
+ public boolean isContentView(@LayoutRes int layoutId){
+ return true;
+ }
+
+ /**
+ * 布局id
+ * @return
+ */
public int getLayoutId(){
- return R.layout.capture;
- }
-
- public int getViewFinderViewId(){
- return R.id.viewfinder_view;
- }
-
- public int getPreviewViewId(){
- return R.id.preview_view;
+ return R.layout.zxl_capture;
}
/**
- * 扫码后声音与震动管理里入口
- * @return true表示播放和震动,是否播放与震动还得看{@link BeepManager}
+ * {@link ViewfinderView} 的 id
+ * @return
*/
- public boolean isBeepSoundAndVibrate(){
- return true;
+ public int getViewfinderViewId(){
+ return R.id.viewfinderView;
+ }
+
+
+ /**
+ * 预览界面{@link #surfaceView} 的id
+ * @return
+ */
+ public int getSurfaceViewId(){
+ return R.id.surfaceView;
+ }
+
+ /**
+ * Get {@link CaptureHelper}
+ * @return {@link #mCaptureHelper}
+ */
+ public CaptureHelper getCaptureHelper(){
+ return mCaptureHelper;
+ }
+
+ /**
+ * Get {@link CameraManager}
+ * @return {@link #mCaptureHelper#getCameraManager()}
+ */
+ public CameraManager getCameraManager(){
+ return mCaptureHelper.getCameraManager();
}
@Override
- protected void onResume() {
+ public void onResume() {
super.onResume();
-
- handler = null;
- lastResult = null;
-
- resetStatusView();
-
-
- beepManager.updatePrefs();
- ambientLightManager.start(cameraManager);
-
- inactivityTimer.onResume();
-
- Intent intent = getIntent();
-
- decodeFormats = null;
- characterSet = null;
-
- if (intent != null) {
-
- String action = intent.getAction();
- String dataString = intent.getDataString();
-
- if (Intents.Scan.ACTION.equals(action)) {
-
- // Scan the formats the intent requested, and return the result to the calling activity.
-// source = IntentSource.NATIVE_APP_INTENT;
- decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
- decodeHints = DecodeHintManager.parseDecodeHints(intent);
-
- if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
- int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
- int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
- if (width > 0 && height > 0) {
- cameraManager.setManualFramingRect(width, height);
- }
- }
-
- if (intent.hasExtra(Intents.Scan.CAMERA_ID)) {
- int cameraId = intent.getIntExtra(Intents.Scan.CAMERA_ID, -1);
- if (cameraId >= 0) {
- cameraManager.setManualCameraId(cameraId);
- }
- }
-
-// String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
-// if (customPromptMessage != null) {
-// statusView.setText(customPromptMessage);
-// }
-
- } else if (dataString != null &&
- dataString.contains("http://www.google") &&
- dataString.contains("/m/products/scan")) {
-
- // Scan only products and send the result to mobile Product Search.
-// source = IntentSource.PRODUCT_SEARCH_LINK;
-// sourceUrl = dataString;
- decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;
-
- } else if (isZXingURL(dataString)) {
-
- // Scan formats requested in query string (all formats if none specified).
- // If a return URL is specified, send the results there. Otherwise, handle it ourselves.
-// source = IntentSource.ZXING_LINK;
-// sourceUrl = dataString;
- Uri inputUri = Uri.parse(dataString);
-// scanFromWebPageManager = new ScanFromWebPageManager(inputUri);
- decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);
- // Allow a sub-set of the hints to be specified by the caller.
- decodeHints = DecodeHintManager.parseDecodeHints(inputUri);
-
- }
-
- characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);
-
- }
-
- if (hasSurface) {
- // The activity was paused but not stopped, so the surface still exists. Therefore
- // surfaceCreated() won't be called, so init the camera here.
- initCamera(surfaceHolder);
- } else {
- // Install the callback and wait for surfaceCreated() to init the camera.
- surfaceHolder.addCallback(this);
- }
- }
-
-// private int getCurrentOrientation() {
-// int rotation = getWindowManager().getDefaultDisplay().getRotation();
-// if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
-// switch (rotation) {
-// case Surface.ROTATION_0:
-// case Surface.ROTATION_90:
-// return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-// default:
-// return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-// }
-// } else {
-// switch (rotation) {
-// case Surface.ROTATION_0:
-// case Surface.ROTATION_270:
-// return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-// default:
-// return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
-// }
-// }
-// }
-
- private static boolean isZXingURL(String dataString) {
- if (dataString == null) {
- return false;
- }
- for (String url : ZXING_URLS) {
- if (dataString.startsWith(url)) {
- return true;
- }
- }
- return false;
+ mCaptureHelper.onResume();
}
@Override
- protected void onPause() {
- if (handler != null) {
- handler.quitSynchronously();
- handler = null;
- }
- inactivityTimer.onPause();
- ambientLightManager.stop();
- beepManager.close();
- cameraManager.closeDriver();
- //historyManager = null; // Keep for onActivityResult
- if (!hasSurface) {
- SurfaceView surfaceView = findViewById(R.id.preview_view);
- SurfaceHolder surfaceHolder = surfaceView.getHolder();
- surfaceHolder.removeCallback(this);
- }
+ public void onPause() {
super.onPause();
+ mCaptureHelper.onPause();
}
@Override
- protected void onDestroy() {
- inactivityTimer.shutdown();
+ public void onDestroy() {
super.onDestroy();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
-// if (source == IntentSource.NATIVE_APP_INTENT) {
-// setResult(RESULT_CANCELED);
-// finish();
-// return true;
-// }
-// if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {
-// restartPreviewAfterDelay(0L);
-// return true;
-// }
- break;
- case KeyEvent.KEYCODE_FOCUS:
- case KeyEvent.KEYCODE_CAMERA:
- // Handle these events so they don't launch the Camera app
- return true;
- // Use volume up/down to turn on light
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- cameraManager.setTorch(false);
- return true;
- case KeyEvent.KEYCODE_VOLUME_UP:
- cameraManager.setTorch(true);
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
-// @Override
-// public boolean onCreateOptionsMenu(Menu menu) {
-// MenuInflater menuInflater = getMenuInflater();
-// menuInflater.inflate(R.menu.capture, menu);
-// return super.onCreateOptionsMenu(menu);
-// }
-//
-// @Override
-// public boolean onOptionsItemSelected(MenuItem item) {
-// Intent intent = new Intent(Intent.ACTION_VIEW);
-// intent.addFlags(Intents.FLAG_NEW_DOC);
-// switch (item.getItemId()) {
-// case R.id.menu_share:
-// intent.setClassName(this, ShareActivity.class.getName());
-// startActivity(intent);
-// break;
-// case R.id.menu_history:
-// intent.setClassName(this, HistoryActivity.class.getName());
-// startActivityForResult(intent, HISTORY_REQUEST_CODE);
-// break;
-// case R.id.menu_settings:
-// intent.setClassName(this, PreferencesActivity.class.getName());
-// startActivity(intent);
-// break;
-// case R.id.menu_help:
-// intent.setClassName(this, HelpActivity.class.getName());
-// startActivity(intent);
-// break;
-// default:
-// return super.onOptionsItemSelected(item);
-// }
-// return true;
-// }
-
-// @Override
-// public void onActivityResult(int requestCode, int resultCode, Intent intent) {
-// if (resultCode == RESULT_OK && requestCode == HISTORY_REQUEST_CODE && historyManager != null) {
-// int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);
-// if (itemNumber >= 0) {
-// HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);
-// decodeOrStoreSavedBitmap(null, historyItem.getResult());
-// }
-// }
-// }
-
- private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
- // Bitmap isn't used yet -- will be used soon
- if (handler == null) {
- savedResultToShow = result;
- } else {
- if (result != null) {
- savedResultToShow = result;
- }
- if (savedResultToShow != null) {
- Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
- handler.sendMessage(message);
- }
- savedResultToShow = null;
- }
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- if (holder == null) {
- Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
- }
- if (!hasSurface) {
- hasSurface = true;
- initCamera(holder);
- }
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- hasSurface = false;
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // 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.
- *
- * @param rawResult The contents of the barcode.
- * @param scaleFactor amount by which thumbnail was scaled
- * @param barcode A greyscale bitmap of the camera data which was decoded.
- */
- public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
- inactivityTimer.onActivity();
- lastResult = rawResult;
- if(isBeepSoundAndVibrate()){
- beepManager.playBeepSoundAndVibrate();
- }
-
- onResult(rawResult);
-
-
-
-// ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
-
-// boolean fromLiveScan = barcode != null;
-// if (fromLiveScan) {
-//// historyManager.addHistoryItem(rawResult, resultHandler);
-// // Then not from history, so beep/vibrate and we have an image to draw on
-// beepManager.playBeepSoundAndVibrate();
-// drawResultPoints(barcode, scaleFactor, rawResult);
-// }
-
-
-
-// switch (source) {
-// case NATIVE_APP_INTENT:
-// case PRODUCT_SEARCH_LINK:
-// handleDecodeExternally(rawResult, resultHandler, barcode);
-// break;
-// case ZXING_LINK:
-// if (scanFromWebPageManager == null || !scanFromWebPageManager.isScanFromWebPage()) {
-// handleDecodeInternally(rawResult, resultHandler, barcode);
-// } else {
-// handleDecodeExternally(rawResult, resultHandler, barcode);
-// }
-// break;
-// case NONE:
-// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-// if (fromLiveScan && prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) {
-// Toast.makeText(getApplicationContext(),
-// getResources().getString(R.string.msg_bulk_mode_scanned) + " (" + rawResult.getText() + ')',
-// Toast.LENGTH_SHORT).show();
-// maybeSetClipboard(resultHandler);
-// // Wait a moment or else it will scan the same barcode continuously about 3 times
-// restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);
-// } else {
-// handleDecodeInternally(rawResult, resultHandler, barcode);
-// }
-// break;
-// }
- }
-
-// /**
-// * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
-// *
-// * @param barcode A bitmap of the captured image.
-// * @param scaleFactor amount by which thumbnail was scaled
-// * @param rawResult The decoded results which contains the points to draw.
-// */
-// private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) {
-// ResultPoint[] points = rawResult.getResultPoints();
-// if (points != null && points.length > 0) {
-// Canvas canvas = new Canvas(barcode);
-// Paint paint = new Paint();
-// paint.setColor(getResources().getColor(R.color.result_points));
-// if (points.length == 2) {
-// paint.setStrokeWidth(4.0f);
-// drawLine(canvas, paint, points[0], points[1], scaleFactor);
-// } else if (points.length == 4 &&
-// (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
-// rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
-// // Hacky special case -- draw two lines, for the barcode and metadata
-// drawLine(canvas, paint, points[0], points[1], scaleFactor);
-// drawLine(canvas, paint, points[2], points[3], scaleFactor);
-// } else {
-// paint.setStrokeWidth(10.0f);
-// for (ResultPoint point : points) {
-// if (point != null) {
-// canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint);
-// }
-// }
-// }
-// }
-// }
-//
-// private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) {
-// if (a != null && b != null) {
-// canvas.drawLine(scaleFactor * a.getX(),
-// scaleFactor * a.getY(),
-// scaleFactor * b.getX(),
-// scaleFactor * b.getY(),
-// paint);
-// }
-// }
-//
-// // Put up our own UI for how to handle the decoded contents.
-// private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
-//
-// maybeSetClipboard(resultHandler);
-//
-// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-//
-// if (resultHandler.getDefaultButtonID() != null && prefs.getBoolean(PreferencesActivity.KEY_AUTO_OPEN_WEB, false)) {
-// resultHandler.handleButtonPress(resultHandler.getDefaultButtonID());
-// return;
-// }
-//
-// statusView.setVisibility(View.GONE);
-// viewfinderView.setVisibility(View.GONE);
-// resultView.setVisibility(View.VISIBLE);
-//
-// ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view);
-// if (barcode == null) {
-// barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),
-// R.drawable.launcher_icon));
-// } else {
-// barcodeImageView.setImageBitmap(barcode);
-// }
-//
-// TextView formatTextView = (TextView) findViewById(R.id.format_text_view);
-// formatTextView.setText(rawResult.getBarcodeFormat().toString());
-//
-// TextView typeTextView = (TextView) findViewById(R.id.type_text_view);
-// typeTextView.setText(resultHandler.getType().toString());
-//
-// DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-// TextView timeTextView = (TextView) findViewById(R.id.time_text_view);
-// timeTextView.setText(formatter.format(rawResult.getTimestamp()));
-//
-//
-// TextView metaTextView = (TextView) findViewById(R.id.meta_text_view);
-// View metaTextViewLabel = findViewById(R.id.meta_text_view_label);
-// metaTextView.setVisibility(View.GONE);
-// metaTextViewLabel.setVisibility(View.GONE);
-// Map metadata = rawResult.getResultMetadata();
-// if (metadata != null) {
-// StringBuilder metadataText = new StringBuilder(20);
-// for (Map.Entry 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);
-// metaTextView.setText(metadataText);
-// metaTextView.setVisibility(View.VISIBLE);
-// metaTextViewLabel.setVisibility(View.VISIBLE);
-// }
-// }
-//
-// CharSequence displayContents = resultHandler.getDisplayContents();
-// TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view);
-// contentsTextView.setText(displayContents);
-// int scaledSize = Math.max(22, 32 - displayContents.length() / 4);
-// contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
-//
-// TextView supplementTextView = (TextView) findViewById(R.id.contents_supplement_text_view);
-// supplementTextView.setText("");
-// supplementTextView.setOnClickListener(null);
-// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
-// PreferencesActivity.KEY_SUPPLEMENTAL, true)) {
-// SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,
-// resultHandler.getResult(),
-// historyManager,
-// this);
-// }
-//
-// int buttonCount = resultHandler.getButtonCount();
-// ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view);
-// buttonView.requestFocus();
-// for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {
-// TextView button = (TextView) buttonView.getChildAt(x);
-// if (x < buttonCount) {
-// button.setVisibility(View.VISIBLE);
-// button.setText(resultHandler.getButtonText(x));
-// button.setOnClickListener(new ResultButtonListener(resultHandler, x));
-// } else {
-// button.setVisibility(View.GONE);
-// }
-// }
-//
-// }
-//
-// // Briefly show the contents of the barcode, then handle the result outside Barcode Scanner.
-// private void handleDecodeExternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
-//
-// if (barcode != null) {
-// viewfinderView.drawResultBitmap(barcode);
-// }
-//
-// long resultDurationMS;
-// if (getIntent() == null) {
-// resultDurationMS = DEFAULT_INTENT_RESULT_DURATION_MS;
-// } else {
-// resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,
-// DEFAULT_INTENT_RESULT_DURATION_MS);
-// }
-//
-// if (resultDurationMS > 0) {
-// String rawResultString = String.valueOf(rawResult);
-// if (rawResultString.length() > 32) {
-// rawResultString = rawResultString.substring(0, 32) + " ...";
-// }
-// statusView.setText(getString(resultHandler.getDisplayTitle()) + " : " + rawResultString);
-// }
-//
-// maybeSetClipboard(resultHandler);
-//
-// switch (source) {
-// case NATIVE_APP_INTENT:
-// // Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when
-// // the deprecated intent is retired.
-// Intent intent = new Intent(getIntent().getAction());
-// intent.addFlags(Intents.FLAG_NEW_DOC);
-// 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++;
-// }
-// }
-// }
-// sendReplyMessage(R.id.return_scan_result, intent, resultDurationMS);
-// break;
-//
-// case PRODUCT_SEARCH_LINK:
-// // Reformulate the URL which triggered us into a query, so that the request goes to the same
-// // TLD as the scan URL.
-// int end = sourceUrl.lastIndexOf("/scan");
-// String productReplyURL = sourceUrl.substring(0, end) + "?q=" +
-// resultHandler.getDisplayContents() + "&source=zxing";
-// sendReplyMessage(R.id.launch_product_query, productReplyURL, resultDurationMS);
-// break;
-//
-// case ZXING_LINK:
-// if (scanFromWebPageManager != null && scanFromWebPageManager.isScanFromWebPage()) {
-// String linkReplyURL = scanFromWebPageManager.buildReplyURL(rawResult, resultHandler);
-// scanFromWebPageManager = null;
-// sendReplyMessage(R.id.launch_product_query, linkReplyURL, resultDurationMS);
-// }
-// break;
-// }
-// }
-//
-// private void maybeSetClipboard(ResultHandler resultHandler) {
-// if (copyToClipboard && !resultHandler.areContentsSecure()) {
-// ClipboardInterface.setText(resultHandler.getDisplayContents(), this);
-// }
-// }
-//
-// private void sendReplyMessage(int id, Object arg, long delayMS) {
-// if (handler != null) {
-// Message message = Message.obtain(handler, id, arg);
-// if (delayMS > 0L) {
-// handler.sendMessageDelayed(message, delayMS);
-// } else {
-// handler.sendMessage(message);
-// }
-// }
-// }
-
- private void initCamera(SurfaceHolder surfaceHolder) {
- if (surfaceHolder == null) {
- throw new IllegalStateException("No SurfaceHolder provided");
- }
- if (cameraManager.isOpen()) {
- Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
- return;
- }
- try {
- cameraManager.openDriver(surfaceHolder);
- // Creating the handler starts the preview, which can also throw a RuntimeException.
- if (handler == null) {
- handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);
- }
- decodeOrStoreSavedBitmap(null, null);
- } catch (IOException ioe) {
- Log.w(TAG, 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
- Log.w(TAG, "Unexpected error initializing camera", e);
-// displayFrameworkBugMessageAndExit();
- }
- }
-
-// private void displayFrameworkBugMessageAndExit() {
-// AlertDialog.Builder builder = new AlertDialog.Builder(this);
-// builder.setTitle(getString(R.string.app_name));
-// builder.setMessage(getString(R.string.msg_camera_framework_bug));
-// builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
-// builder.setOnCancelListener(new FinishListener(this));
-// builder.show();
-// }
-
- public void restartPreviewAfterDelay(long delayMS) {
- if (handler != null) {
- handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
- }
- resetStatusView();
- }
-
- private void resetStatusView() {
-// resultView.setVisibility(View.GONE);
-// statusView.setText(R.string.msg_default_status);
-// statusView.setVisibility(View.VISIBLE);
- viewfinderView.setVisibility(View.VISIBLE);
- lastResult = null;
- }
-
- public void drawViewfinder() {
- viewfinderView.drawViewfinder();
+ mCaptureHelper.onDestroy();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- if(isZoom && cameraManager.isOpen()){
- Camera camera = cameraManager.getOpenCamera().getCamera();
- if(camera ==null){
- return super.onTouchEvent(event);
- }
- if (event.getPointerCount() == 1) {//单点触控,聚焦
-// focusOnTouch(event,camera);
- } else {
- switch (event.getAction() & MotionEvent.ACTION_MASK) {//多点触控
- case MotionEvent.ACTION_POINTER_DOWN:
- oldDistance = calcFingerSpacing(event);
- break;
- case MotionEvent.ACTION_MOVE:
- float newDistance = calcFingerSpacing(event);
-
- if (newDistance > oldDistance + DEVIATION) {//
- handleZoom(true, camera);
- } else if (newDistance < oldDistance - DEVIATION) {
- handleZoom(false, camera);
- }
- oldDistance = newDistance;
- break;
- }
- }
- }
+ mCaptureHelper.onTouchEvent(event);
return super.onTouchEvent(event);
}
- public boolean isZoom() {
- return isZoom;
- }
-
- public void setZoom(boolean zoom) {
- isZoom = zoom;
- }
-
/**
- * 处理变焦缩放
- * @param isZoomIn
- * @param camera
+ * 接收扫码结果回调
+ * @param result 扫码结果
+ * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截
*/
- private void handleZoom(boolean isZoomIn, Camera camera) {
- Camera.Parameters params = camera.getParameters();
- if (params.isZoomSupported()) {
- int maxZoom = params.getMaxZoom();
- int zoom = params.getZoom();
- if (isZoomIn && zoom < maxZoom) {
- zoom++;
- } else if (zoom > 0) {
- zoom--;
- }
- params.setZoom(zoom);
- camera.setParameters(params);
- } else {
- Log.i(TAG, "zoom not supported");
- }
+ @Override
+ public boolean onResultCallback(String result) {
+ return false;
}
-
- /**
- * 聚焦
- * @param event
- * @param camera
- */
- public void focusOnTouch(MotionEvent event,Camera camera) {
-
- Camera.Parameters params = camera.getParameters();
- Camera.Size previewSize = params.getPreviewSize();
-
- Rect focusRect = calcTapArea(event.getRawX(), event.getRawY(), 1f,previewSize);
- Rect meteringRect = calcTapArea(event.getRawX(), event.getRawY(), 1.5f,previewSize);
- Camera.Parameters parameters = camera.getParameters();
- if (parameters.getMaxNumFocusAreas() > 0) {
- List focusAreas = new ArrayList<>();
- focusAreas.add(new Camera.Area(focusRect, 600));
- parameters.setFocusAreas(focusAreas);
- }
-
- if (parameters.getMaxNumMeteringAreas() > 0) {
- List meteringAreas = new ArrayList<>();
- meteringAreas.add(new Camera.Area(meteringRect, 600));
- parameters.setMeteringAreas(meteringAreas);
- }
- final String currentFocusMode = params.getFocusMode();
- params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
- camera.setParameters(params);
-
- camera.autoFocus(new Camera.AutoFocusCallback() {
- @Override
- public void onAutoFocus(boolean success, Camera camera) {
- Camera.Parameters params = camera.getParameters();
- params.setFocusMode(currentFocusMode);
- camera.setParameters(params);
- }
- });
-
- }
-
- /**
- * 计算两指间距离
- * @param event
- * @return
- */
- private float calcFingerSpacing(MotionEvent event) {
- float x = event.getX(0) - event.getX(1);
- float y = event.getY(0) - event.getY(1);
- return (float) Math.sqrt(x * x + y * y);
- }
-
- /**
- * 计算对焦区域
- * @param x
- * @param y
- * @param coefficient
- * @param previewSize
- * @return
- */
- private Rect calcTapArea(float x, float y, float coefficient,Camera.Size previewSize) {
- float focusAreaSize = 200;
- int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
- int centerX = (int) ((x / previewSize.width) * 2000 - 1000);
- int centerY = (int) ((y / previewSize.height) * 2000 - 1000);
- int left = clamp(centerX - (areaSize / 2), -1000, 1000);
- int top = clamp(centerY - (areaSize / 2), -1000, 1000);
- RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
- return new Rect(Math.round(rectF.left), Math.round(rectF.top),
- Math.round(rectF.right), Math.round(rectF.bottom));
- }
-
- /**
- *
- * @param x
- * @param min
- * @param max
- * @return
- */
- private int clamp(int x, int min, int max) {
- if (x > max) {
- return max;
- }
- if (x < min) {
- return min;
- }
- return x;
- }
-
-
}
\ No newline at end of file
diff --git a/lib/src/main/java/com/king/zxing/CaptureFragment.java b/lib/src/main/java/com/king/zxing/CaptureFragment.java
new file mode 100644
index 0000000..87b5363
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/CaptureFragment.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2019 Jenly Yu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.king.zxing;
+
+import android.os.Bundle;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.king.zxing.camera.CameraManager;
+
+/**
+ * @author Jenly
+ */
+public class CaptureFragment extends Fragment implements OnCaptureCallback {
+
+ public static final String KEY_RESULT = Intents.Scan.RESULT;
+
+ private View mRootView;
+
+ private SurfaceView surfaceView;
+ private ViewfinderView viewfinderView;
+
+ private CaptureHelper mCaptureHelper;
+
+ public static CaptureFragment newInstance() {
+
+ Bundle args = new Bundle();
+
+ CaptureFragment fragment = new CaptureFragment();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ int layoutId = getLayoutId();
+ if(isContentView(layoutId)){
+ mRootView = inflater.inflate(getLayoutId(),container,false);
+ }
+ initUI();
+ return mRootView;
+ }
+
+ /**
+ * 初始化
+ */
+ public void initUI(){
+ surfaceView = mRootView.findViewById(getSurfaceViewId());
+ viewfinderView = mRootView.findViewById(getViewfinderViewId());
+ mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
+ mCaptureHelper.setOnCaptureCallback(this);
+ }
+
+ /**
+ * 返回true时会自动初始化{@link #mRootView},返回为false时需自己去通过{@link #setRootView(View)}初始化{@link #mRootView}
+ * @param layoutId
+ * @return 默认返回true
+ */
+ public boolean isContentView(@LayoutRes int layoutId){
+ return true;
+ }
+
+ /**
+ * 布局id
+ * @return
+ */
+ public int getLayoutId(){
+ return R.layout.zxl_capture;
+ }
+
+ /**
+ * {@link ViewfinderView} 的 id
+ * @return
+ */
+ public int getViewfinderViewId(){
+ return R.id.viewfinderView;
+ }
+
+
+ /**
+ * 预览界面{@link #surfaceView} 的id
+ * @return
+ */
+ public int getSurfaceViewId(){
+ return R.id.surfaceView;
+ }
+
+ /**
+ * Get {@link CaptureHelper}
+ * @return {@link #mCaptureHelper}
+ */
+ public CaptureHelper getCaptureHelper(){
+ return mCaptureHelper;
+ }
+
+ /**
+ * Get {@link CameraManager}
+ * @return {@link #mCaptureHelper#getCameraManager()}
+ */
+ public CameraManager getCameraManager(){
+ return mCaptureHelper.getCameraManager();
+ }
+
+ //--------------------------------------------
+
+ public View getRootView() {
+ return mRootView;
+ }
+
+ public void setRootView(View rootView) {
+ this.mRootView = rootView;
+ }
+
+
+ //--------------------------------------------
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mCaptureHelper.onCreate();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mCaptureHelper.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mCaptureHelper.onPause();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mCaptureHelper.onDestroy();
+ }
+
+ /**
+ * 接收扫码结果回调
+ * @param result 扫码结果
+ * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截
+ */
+ @Override
+ public boolean onResultCallback(String result) {
+ return false;
+ }
+
+}
diff --git a/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java b/lib/src/main/java/com/king/zxing/CaptureHandler.java
similarity index 74%
rename from lib/src/main/java/com/king/zxing/CaptureActivityHandler.java
rename to lib/src/main/java/com/king/zxing/CaptureHandler.java
index 1af3c59..652b1ee 100644
--- a/lib/src/main/java/com/king/zxing/CaptureActivityHandler.java
+++ b/lib/src/main/java/com/king/zxing/CaptureHandler.java
@@ -1,169 +1,154 @@
-package com.king.zxing;
-
-/*
- * Copyright (C) 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-import android.content.ActivityNotFoundException;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.BitmapFactory;
-import android.provider.Browser;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.DecodeHintType;
-import com.google.zxing.Result;
-import com.king.zxing.camera.CameraManager;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * This class handles all the messaging which comprises the state machine for capture.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-public final class CaptureActivityHandler extends Handler {
-
- private static final String TAG = CaptureActivityHandler.class.getSimpleName();
-
- private final CaptureActivity activity;
- private final DecodeThread decodeThread;
- private State state;
- private final CameraManager cameraManager;
-
- private enum State {
- PREVIEW,
- SUCCESS,
- DONE
- }
-
- CaptureActivityHandler(CaptureActivity activity,
- Collection decodeFormats,
- Map baseHints,
- String characterSet,
- CameraManager cameraManager) {
- this.activity = activity;
- decodeThread = new DecodeThread(activity, decodeFormats, baseHints, characterSet,
- new ViewfinderResultPointCallback(activity.getViewfinderView()));
- decodeThread.start();
- state = State.SUCCESS;
-
- // Start ourselves capturing previews and decoding.
- this.cameraManager = cameraManager;
- cameraManager.startPreview();
- restartPreviewAndDecode();
- }
-
- @Override
- public void handleMessage(Message message) {
- if (message.what == R.id.restart_preview) {
- restartPreviewAndDecode();
-
- } else if (message.what == R.id.decode_succeeded) {
- state = State.SUCCESS;
- Bundle bundle = message.getData();
- Bitmap barcode = null;
- float scaleFactor = 1.0f;
- if (bundle != null) {
- byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
- if (compressedBitmap != null) {
- barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
- // Mutable copy:
- barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
- }
- scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
- }
- activity.handleDecode((Result) message.obj, barcode, scaleFactor);
-
- } else if (message.what == R.id.decode_failed) {// We're decoding as fast as possible, so when one decode fails, start another.
- state = State.PREVIEW;
- cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
-
- } else if (message.what == R.id.return_scan_result) {
- activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
- activity.finish();
-
- } else if (message.what == R.id.launch_product_query) {
- String url = (String) message.obj;
-
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.addFlags(Intents.FLAG_NEW_DOC);
- intent.setData(Uri.parse(url));
-
- ResolveInfo resolveInfo =
- activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
- String browserPackageName = null;
- if (resolveInfo != null && resolveInfo.activityInfo != null) {
- browserPackageName = resolveInfo.activityInfo.packageName;
- Log.d(TAG, "Using browser in package " + browserPackageName);
- }
-
- // Needed for default Android browser / Chrome only apparently
- if (browserPackageName != null) {
- switch (browserPackageName) {
- case "com.android.browser":
- case "com.android.chrome":
- intent.setPackage(browserPackageName);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(Browser.EXTRA_APPLICATION_ID, browserPackageName);
- break;
- }
- }
-
- try {
- activity.startActivity(intent);
- } catch (ActivityNotFoundException ignored) {
- Log.w(TAG, "Can't find anything to handle VIEW of URI " + url);
- }
-
- }
- }
-
- public void quitSynchronously() {
- state = State.DONE;
- cameraManager.stopPreview();
- Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
- quit.sendToTarget();
- try {
- // Wait at most half a second; should be enough time, and onPause() will timeout quickly
- decodeThread.join(500L);
- } catch (InterruptedException e) {
- // continue
- }
-
- // Be absolutely sure we don't send any queued up messages
- removeMessages(R.id.decode_succeeded);
- removeMessages(R.id.decode_failed);
- }
-
- public void restartPreviewAndDecode() {
- if (state == State.SUCCESS) {
- state = State.PREVIEW;
- cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
- activity.drawViewfinder();
- }
- }
-
-}
\ No newline at end of file
+package com.king.zxing;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Browser;
+import android.util.Log;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.king.zxing.camera.CameraManager;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author Jenly
+ */
+public class CaptureHandler extends Handler {
+
+ private static final String TAG = CaptureHandler.class.getSimpleName();
+
+ private final OnCaptureListener onCaptureListener;
+ private final DecodeThread decodeThread;
+ private State state;
+ private final CameraManager cameraManager;
+ private final Activity activity;
+ private final ViewfinderView viewfinderView;
+
+
+ private enum State {
+ PREVIEW,
+ SUCCESS,
+ DONE
+ }
+
+ CaptureHandler(Activity activity,ViewfinderView viewfinderView,OnCaptureListener onCaptureListener,
+ Collection decodeFormats,
+ Map baseHints,
+ String characterSet,
+ CameraManager cameraManager) {
+ this.activity = activity;
+ this.viewfinderView = viewfinderView;
+ this.onCaptureListener = onCaptureListener;
+ decodeThread = new DecodeThread(activity,cameraManager,this, decodeFormats, baseHints, characterSet,
+ new ViewfinderResultPointCallback(viewfinderView));
+ decodeThread.start();
+ state = State.SUCCESS;
+
+ // Start ourselves capturing previews and decoding.
+ this.cameraManager = cameraManager;
+ cameraManager.startPreview();
+ restartPreviewAndDecode();
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == R.id.restart_preview) {
+ restartPreviewAndDecode();
+
+ } else if (message.what == R.id.decode_succeeded) {
+ state = State.SUCCESS;
+ Bundle bundle = message.getData();
+ Bitmap barcode = null;
+ float scaleFactor = 1.0f;
+ if (bundle != null) {
+ byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
+ if (compressedBitmap != null) {
+ barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
+ // Mutable copy:
+ barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
+ }
+ scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
+ }
+ onCaptureListener.onHandleDecode((Result) message.obj, barcode, scaleFactor);
+
+ } else if (message.what == R.id.decode_failed) {// We're decoding as fast as possible, so when one decode fails, start another.
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+
+ } else if (message.what == R.id.return_scan_result) {
+ activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
+ activity.finish();
+
+ } else if (message.what == R.id.launch_product_query) {
+ String url = (String) message.obj;
+
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intents.FLAG_NEW_DOC);
+ intent.setData(Uri.parse(url));
+
+ ResolveInfo resolveInfo =
+ activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ String browserPackageName = null;
+ if (resolveInfo != null && resolveInfo.activityInfo != null) {
+ browserPackageName = resolveInfo.activityInfo.packageName;
+ Log.d(TAG, "Using browser in package " + browserPackageName);
+ }
+
+ // Needed for default Android browser / Chrome only apparently
+ if (browserPackageName != null) {
+ switch (browserPackageName) {
+ case "com.android.browser":
+ case "com.android.chrome":
+ intent.setPackage(browserPackageName);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, browserPackageName);
+ break;
+ }
+ }
+
+ try {
+ activity.startActivity(intent);
+ } catch (ActivityNotFoundException ignored) {
+ Log.w(TAG, "Can't find anything to handle VIEW of URI " + url);
+ }
+
+ }
+ }
+
+ public void quitSynchronously() {
+ state = State.DONE;
+ cameraManager.stopPreview();
+ Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
+ quit.sendToTarget();
+ try {
+ // Wait at most half a second; should be enough time, and onPause() will timeout quickly
+ decodeThread.join(500L);
+ } catch (InterruptedException e) {
+ // continue
+ }
+
+ // Be absolutely sure we don't send any queued up messages
+ removeMessages(R.id.decode_succeeded);
+ removeMessages(R.id.decode_failed);
+ }
+
+ public void restartPreviewAndDecode() {
+ if (state == State.SUCCESS) {
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+ viewfinderView.drawViewfinder();
+ }
+ }
+}
diff --git a/lib/src/main/java/com/king/zxing/CaptureHelper.java b/lib/src/main/java/com/king/zxing/CaptureHelper.java
new file mode 100644
index 0000000..dc63b62
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/CaptureHelper.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2019 Jenly Yu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.king.zxing;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.hardware.Camera;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.Result;
+import com.king.zxing.camera.CameraManager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Jenly
+ */
+public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,CaptureManager {
+
+ public static final String TAG = CaptureHelper.class.getSimpleName();
+
+ private Activity activity;
+
+ private CaptureHandler captureHandler;
+ private OnCaptureListener onCaptureListener;
+
+ private CameraManager cameraManager;
+
+ private InactivityTimer inactivityTimer;
+ private BeepManager beepManager;
+ private AmbientLightManager ambientLightManager;
+
+
+ private ViewfinderView viewfinderView;
+ private SurfaceHolder surfaceHolder;
+ private SurfaceHolder.Callback callback;
+
+ private Collection decodeFormats;
+ private Map decodeHints;
+ private String characterSet;
+
+ private boolean hasSurface;
+ /**
+ * 默认触控误差值
+ */
+ private static final int DEVIATION = 6;
+ /**
+ * 是否支持缩放(变焦),默认支持
+ */
+ private boolean isSupportZoom = true;
+ private float oldDistance;
+ /**
+ * 是否支持连扫,默认不支持
+ */
+ private boolean isContinuousScan = false;
+ /**
+ * 连扫时,是否自动重置预览和解码器,默认自动重置
+ */
+ private boolean isAutoRestartPreviewAndDecode = true;
+ /**
+ * 是否播放音效
+ */
+ private boolean isPlayBeep;
+ /**
+ * 是否震动
+ */
+ private boolean isVibrate;
+
+ private OnCaptureCallback onCaptureCallback;
+
+
+ public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView){
+ this(fragment.getActivity(),surfaceView,viewfinderView);
+
+ }
+
+ public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView){
+ this.activity = activity;
+ this.viewfinderView = viewfinderView;
+ surfaceHolder = surfaceView.getHolder();
+ hasSurface = false;
+
+ }
+
+ @Override
+ public void onCreate(){
+ inactivityTimer = new InactivityTimer(activity);
+ beepManager = new BeepManager(activity);
+ ambientLightManager = new AmbientLightManager(activity);
+
+ cameraManager = new CameraManager(activity);
+
+ callback = new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (holder == null) {
+ Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+ }
+ 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;
+ }
+ };
+
+ onCaptureListener = new OnCaptureListener() {
+
+ @Override
+ public void onHandleDecode(Result result, Bitmap barcode, float scaleFactor) {
+ inactivityTimer.onActivity();
+ beepManager.playBeepSoundAndVibrate();
+
+ onResult(result);
+ }
+
+ };
+ //设置是否播放音效和震动
+ beepManager.setPlayBeep(isPlayBeep);
+ beepManager.setVibrate(isVibrate);
+ }
+
+
+ /**
+ * {@link Activity#onResume()}
+ */
+ @Override
+ public void onResume(){
+ beepManager.updatePrefs();
+ ambientLightManager.start(cameraManager);
+
+ inactivityTimer.onResume();
+
+ surfaceHolder.addCallback(callback);
+
+ if (hasSurface) {
+ initCamera(surfaceHolder);
+ } else {
+ surfaceHolder.addCallback(callback);
+ }
+ }
+
+ /**
+ * {@link Activity#onPause()}
+ */
+ @Override
+ public void onPause(){
+ if (captureHandler != null) {
+ captureHandler.quitSynchronously();
+ captureHandler = null;
+ }
+ inactivityTimer.onPause();
+ ambientLightManager.stop();
+ beepManager.close();
+ cameraManager.closeDriver();
+ if (!hasSurface) {
+ surfaceHolder.removeCallback(callback);
+ }
+ }
+
+ /**
+ * {@link Activity#onDestroy()}
+ */
+ @Override
+ public void onDestroy(){
+ inactivityTimer.shutdown();
+ }
+
+ /**
+ * 支持缩放时,须在{@link Activity#onTouchEvent(MotionEvent)}调用此方法
+ * @param event
+ */
+ @Override
+ public boolean onTouchEvent(MotionEvent event){
+ if(isSupportZoom && cameraManager.isOpen()){
+ Camera camera = cameraManager.getOpenCamera().getCamera();
+ if(camera ==null){
+ return false;
+ }
+ if(event.getPointerCount() > 1) {
+ switch (event.getAction() & MotionEvent.ACTION_MASK) {//多点触控
+ case MotionEvent.ACTION_POINTER_DOWN:
+ oldDistance = calcFingerSpacing(event);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ float newDistance = calcFingerSpacing(event);
+
+ if (newDistance > oldDistance + DEVIATION) {//
+ handleZoom(true, camera);
+ } else if (newDistance < oldDistance - DEVIATION) {
+ handleZoom(false, camera);
+ }
+ oldDistance = newDistance;
+ break;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void initCamera(SurfaceHolder surfaceHolder) {
+ if (surfaceHolder == null) {
+ throw new IllegalStateException("No SurfaceHolder provided");
+ }
+ if (cameraManager.isOpen()) {
+ Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
+ return;
+ }
+ try {
+ cameraManager.openDriver(surfaceHolder);
+ // Creating the handler starts the preview, which can also throw a RuntimeException.
+ if (captureHandler == null) {
+ captureHandler = new CaptureHandler(activity,viewfinderView,onCaptureListener, decodeFormats, decodeHints, characterSet, cameraManager);
+ }
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ } catch (RuntimeException e) {
+ // Barcode Scanner has seen crashes in the wild of this variety:
+ // java.?lang.?RuntimeException: Fail to connect to camera service
+ Log.w(TAG, "Unexpected error initializing camera", e);
+ }
+ }
+
+ /**
+ * 处理变焦缩放
+ * @param isZoomIn
+ * @param camera
+ */
+ private void handleZoom(boolean isZoomIn, Camera camera) {
+ Camera.Parameters params = camera.getParameters();
+ if (params.isZoomSupported()) {
+ int maxZoom = params.getMaxZoom();
+ int zoom = params.getZoom();
+ if (isZoomIn && zoom < maxZoom) {
+ zoom++;
+ } else if (zoom > 0) {
+ zoom--;
+ }
+ params.setZoom(zoom);
+ camera.setParameters(params);
+ } else {
+ Log.i(TAG, "zoom not supported");
+ }
+ }
+
+ /**
+ * 聚焦
+ * @param event
+ * @param camera
+ */
+ private void focusOnTouch(MotionEvent event,Camera camera) {
+
+ Camera.Parameters params = camera.getParameters();
+ Camera.Size previewSize = params.getPreviewSize();
+
+ Rect focusRect = calcTapArea(event.getRawX(), event.getRawY(), 1f,previewSize);
+ Rect meteringRect = calcTapArea(event.getRawX(), event.getRawY(), 1.5f,previewSize);
+ Camera.Parameters parameters = camera.getParameters();
+ if (parameters.getMaxNumFocusAreas() > 0) {
+ List focusAreas = new ArrayList<>();
+ focusAreas.add(new Camera.Area(focusRect, 600));
+ parameters.setFocusAreas(focusAreas);
+ }
+
+ if (parameters.getMaxNumMeteringAreas() > 0) {
+ List meteringAreas = new ArrayList<>();
+ meteringAreas.add(new Camera.Area(meteringRect, 600));
+ parameters.setMeteringAreas(meteringAreas);
+ }
+ final String currentFocusMode = params.getFocusMode();
+ params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
+ camera.setParameters(params);
+
+ camera.autoFocus(new Camera.AutoFocusCallback() {
+ @Override
+ public void onAutoFocus(boolean success, Camera camera) {
+ Camera.Parameters params = camera.getParameters();
+ params.setFocusMode(currentFocusMode);
+ camera.setParameters(params);
+ }
+ });
+
+ }
+
+
+ /**
+ * 计算两指间距离
+ * @param event
+ * @return
+ */
+ private float calcFingerSpacing(MotionEvent event) {
+ float x = event.getX(0) - event.getX(1);
+ float y = event.getY(0) - event.getY(1);
+ return (float) Math.sqrt(x * x + y * y);
+ }
+
+ /**
+ * 计算对焦区域
+ * @param x
+ * @param y
+ * @param coefficient
+ * @param previewSize
+ * @return
+ */
+ private Rect calcTapArea(float x, float y, float coefficient, Camera.Size previewSize) {
+ float focusAreaSize = 200;
+ int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
+ int centerX = (int) ((x / previewSize.width) * 2000 - 1000);
+ int centerY = (int) ((y / previewSize.height) * 2000 - 1000);
+ int left = clamp(centerX - (areaSize / 2), -1000, 1000);
+ int top = clamp(centerY - (areaSize / 2), -1000, 1000);
+ RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
+ return new Rect(Math.round(rectF.left), Math.round(rectF.top),
+ Math.round(rectF.right), Math.round(rectF.bottom));
+ }
+
+ /**
+ *
+ * @param x
+ * @param min
+ * @param max
+ * @return
+ */
+ private int clamp(int x, int min, int max) {
+ if (x > max) {
+ return max;
+ }
+ if (x < min) {
+ return min;
+ }
+ return x;
+ }
+
+
+ /**
+ * 重新启动扫码和解码器
+ */
+ public void restartPreviewAndDecode(){
+ if(captureHandler!=null){
+ captureHandler.restartPreviewAndDecode();
+ }
+ }
+
+ /**
+ * 接收扫码结果,想支持连扫时,可将{@link #continuousScan(boolean)}设置为{@code true}
+ * 如果{@link #isContinuousScan}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
+ * 请将{@link #autoRestartPreviewAndDecode(boolean)}设置为{@code false},并手动调用{@link #restartPreviewAndDecode()}
+ * @param result 扫码结果
+ */
+ public void onResult(Result result){
+ String text = result.getText();
+ if(isContinuousScan){
+ if(isAutoRestartPreviewAndDecode){
+ if(onCaptureCallback!=null){
+ onCaptureCallback.onResultCallback(text);
+ }
+ restartPreviewAndDecode();
+ }
+ }else{
+ //如果设置了回调,并且onCallback返回为true,则表示拦截
+ if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(text)){
+ return;
+ }
+ Intent intent = new Intent();
+ intent.putExtra(Intents.Scan.RESULT,text);
+ activity.setResult(Activity.RESULT_OK,intent);
+ activity.finish();
+ }
+ }
+
+ /**
+ * 设置是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
+ */
+ public CaptureHelper continuousScan(boolean isContinuousScan){
+ this.isContinuousScan = isContinuousScan;
+ return this;
+ }
+
+
+ /**
+ * 设置是否自动重启扫码和解码器,当支持连扫时才起作用。
+ * @return 默认返回 true
+ */
+ public CaptureHelper autoRestartPreviewAndDecode(boolean isAutoRestartPreviewAndDecode){
+ this.isAutoRestartPreviewAndDecode = isAutoRestartPreviewAndDecode;
+ return this;
+ }
+
+
+ /**
+ * 设置是否播放音效
+ * @return
+ */
+ public CaptureHelper playBeep(boolean playBeep){
+ this.isPlayBeep = playBeep;
+ if(beepManager!=null){
+ beepManager.setPlayBeep(playBeep);
+ }
+ return this;
+ }
+
+ /**
+ * 设置是否震动
+ * @return
+ */
+ public CaptureHelper vibrate(boolean vibrate){
+ this.isVibrate = vibrate;
+ if(beepManager!=null){
+ beepManager.setVibrate(vibrate);
+ }
+ return this;
+ }
+
+
+ /**
+ * 设置是否支持缩放
+ * @param supportZoom
+ * @return
+ */
+ public CaptureHelper supportZoom(boolean supportZoom) {
+ isSupportZoom = supportZoom;
+ return this;
+ }
+
+ /**
+ *
+ * @param decodeFormats
+ * @return
+ */
+ public CaptureHelper decodeFormats(Collection decodeFormats) {
+ this.decodeFormats = decodeFormats;
+ return this;
+ }
+
+ /**
+ *
+ * @param decodeHints
+ * @return
+ */
+ public CaptureHelper decodeHints(Map decodeHints) {
+ this.decodeHints = decodeHints;
+ return this;
+ }
+
+ /**
+ *
+ * @param characterSet
+ * @return
+ */
+ public CaptureHelper characterSet(String characterSet) {
+ this.characterSet = characterSet;
+ return this;
+ }
+
+ /**
+ * 设置扫码回调
+ * @param callback
+ * @return
+ */
+ public CaptureHelper setOnCaptureCallback(OnCaptureCallback callback) {
+ this.onCaptureCallback = callback;
+ return this;
+ }
+
+ @Override
+ public CameraManager getCameraManager() {
+ return cameraManager;
+ }
+
+ @Override
+ public BeepManager getBeepManager() {
+ return beepManager;
+ }
+
+ @Override
+ public AmbientLightManager getAmbientLightManager() {
+ return ambientLightManager;
+ }
+
+ @Override
+ public InactivityTimer getInactivityTimer() {
+ return inactivityTimer;
+ }
+}
diff --git a/lib/src/main/java/com/king/zxing/CaptureLifecycle.java b/lib/src/main/java/com/king/zxing/CaptureLifecycle.java
new file mode 100644
index 0000000..060b8cd
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/CaptureLifecycle.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 Jenly Yu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.king.zxing;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * @author Jenly
+ */
+public interface CaptureLifecycle {
+
+ /**
+ * {@link android.app.Activity#onCreate(Bundle)}
+ */
+ void onCreate();
+ /**
+ * {@link Activity#onResume()}
+ */
+ void onResume();
+
+ /**
+ * {@link Activity#onPause()}
+ */
+ void onPause();
+
+ /**
+ * {@link Activity#onDestroy()}
+ */
+ void onDestroy();
+
+}
diff --git a/lib/src/main/java/com/king/zxing/CaptureManager.java b/lib/src/main/java/com/king/zxing/CaptureManager.java
new file mode 100644
index 0000000..0d4e0c1
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/CaptureManager.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 Jenly Yu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.king.zxing;
+
+import com.king.zxing.camera.CameraManager;
+
+/**
+ * @author Jenly
+ */
+public interface CaptureManager {
+
+ /**
+ * Get {@link CameraManager}
+ * @return {@link CameraManager}
+ */
+ CameraManager getCameraManager();
+
+ /**
+ * Get {@link BeepManager}
+ * @return {@link BeepManager}
+ */
+ BeepManager getBeepManager();
+
+ /**
+ * Get {@link AmbientLightManager}
+ * @return {@link AmbientLightManager}
+ */
+ AmbientLightManager getAmbientLightManager();
+
+ /**
+ * Get {@link InactivityTimer}
+ * @return {@link InactivityTimer}
+ */
+ InactivityTimer getInactivityTimer();
+}
diff --git a/lib/src/main/java/com/king/zxing/CaptureTouchEvent.java b/lib/src/main/java/com/king/zxing/CaptureTouchEvent.java
new file mode 100644
index 0000000..884f1a5
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/CaptureTouchEvent.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 Jenly Yu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.king.zxing;
+
+import android.view.MotionEvent;
+
+/**
+ * @author Jenly
+ */
+public interface CaptureTouchEvent {
+
+ /**
+ * {@link android.app.Activity#onTouchEvent(MotionEvent)}
+ */
+ boolean onTouchEvent(MotionEvent event);
+}
diff --git a/lib/src/main/java/com/king/zxing/DecodeHandler.java b/lib/src/main/java/com/king/zxing/DecodeHandler.java
index c6c5860..8a45ca7 100644
--- a/lib/src/main/java/com/king/zxing/DecodeHandler.java
+++ b/lib/src/main/java/com/king/zxing/DecodeHandler.java
@@ -23,10 +23,10 @@ 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 com.king.zxing.camera.CameraManager;
import android.graphics.Point;
import android.os.Bundle;
@@ -44,14 +44,18 @@ final class DecodeHandler extends Handler {
private static final String TAG = DecodeHandler.class.getSimpleName();
- private final CaptureActivity activity;
+ private final Context context;
+ private final CameraManager cameraManager;
+ private final Handler handler;
private final MultiFormatReader multiFormatReader;
private boolean running = true;
- DecodeHandler(CaptureActivity activity, Map hints) {
+ DecodeHandler(Context context, CameraManager cameraManager,Handler handler, Map hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
- this.activity = activity;
+ this.context = context;
+ this.cameraManager = cameraManager;
+ this.handler = handler;
}
@Override
@@ -70,7 +74,7 @@ final class DecodeHandler extends Handler {
}
private boolean isScreenPortrait(){
- WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
+ WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point screenResolution = new Point();
display.getSize(screenResolution);
@@ -98,9 +102,9 @@ final class DecodeHandler extends Handler {
int tmp = width;
width = height;
height = tmp;
- source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
+ source = cameraManager.buildLuminanceSource(rotatedData, width, height);
}else{
- source = activity.getCameraManager().buildLuminanceSource(data, width, height);
+ source = cameraManager.buildLuminanceSource(data, width, height);
}
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
@@ -118,7 +122,6 @@ final class DecodeHandler extends Handler {
}
}
- Handler handler = activity.getHandler();
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
diff --git a/lib/src/main/java/com/king/zxing/DecodeThread.java b/lib/src/main/java/com/king/zxing/DecodeThread.java
index f4bf8f3..65eb6e9 100644
--- a/lib/src/main/java/com/king/zxing/DecodeThread.java
+++ b/lib/src/main/java/com/king/zxing/DecodeThread.java
@@ -20,7 +20,9 @@ package com.king.zxing;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.ResultPointCallback;
+import com.king.zxing.camera.CameraManager;
+import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
@@ -43,18 +45,23 @@ final class DecodeThread extends Thread {
public static final String BARCODE_BITMAP = "barcode_bitmap";
public static final String BARCODE_SCALED_FACTOR = "barcode_scaled_factor";
- private final CaptureActivity activity;
+ private final Context context;
+ private final CameraManager cameraManager;
private final Map hints;
private Handler handler;
+ private CaptureHandler captureHandler;
private final CountDownLatch handlerInitLatch;
- DecodeThread(CaptureActivity activity,
+ DecodeThread(Context context,CameraManager cameraManager,
+ CaptureHandler captureHandler,
Collection decodeFormats,
Map baseHints,
String characterSet,
ResultPointCallback resultPointCallback) {
- this.activity = activity;
+ this.context = context;
+ this.cameraManager = cameraManager;
+ this.captureHandler = captureHandler;
handlerInitLatch = new CountDownLatch(1);
hints = new EnumMap<>(DecodeHintType.class);
@@ -64,7 +71,7 @@ final class DecodeThread extends Thread {
// The prefs can't change while the thread is running, so pick them up once here.
if (decodeFormats == null || decodeFormats.isEmpty()) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
if (prefs.getBoolean(Preferences.KEY_DECODE_1D_PRODUCT, true)) {
decodeFormats.addAll(DecodeFormatManager.PRODUCT_FORMATS);
@@ -106,7 +113,7 @@ final class DecodeThread extends Thread {
@Override
public void run() {
Looper.prepare();
- handler = new DecodeHandler(activity, hints);
+ handler = new DecodeHandler(context,cameraManager,captureHandler, hints);
handlerInitLatch.countDown();
Looper.loop();
}
diff --git a/lib/src/main/java/com/king/zxing/OnCaptureCallback.java b/lib/src/main/java/com/king/zxing/OnCaptureCallback.java
new file mode 100644
index 0000000..a0004ad
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/OnCaptureCallback.java
@@ -0,0 +1,16 @@
+package com.king.zxing;
+
+
+
+/**
+ * @author Jenly
+ */
+public interface OnCaptureCallback {
+
+ /**
+ * 接收扫码结果回调
+ * @param result 扫码结果
+ * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截
+ */
+ boolean onResultCallback(String result);
+}
diff --git a/lib/src/main/java/com/king/zxing/OnCaptureListener.java b/lib/src/main/java/com/king/zxing/OnCaptureListener.java
new file mode 100644
index 0000000..05d098f
--- /dev/null
+++ b/lib/src/main/java/com/king/zxing/OnCaptureListener.java
@@ -0,0 +1,22 @@
+package com.king.zxing;
+
+import android.graphics.Bitmap;
+
+import com.google.zxing.Result;
+
+/**
+ * @author Jenly
+ */
+public interface OnCaptureListener {
+
+
+ /**
+ * 接收解码后的扫码结果
+ * @param result
+ * @param barcode
+ * @param scaleFactor
+ */
+ void onHandleDecode(Result result, Bitmap barcode, float scaleFactor);
+
+
+}
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraManager.java b/lib/src/main/java/com/king/zxing/camera/CameraManager.java
index ab89a50..2221b4f 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraManager.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraManager.java
@@ -66,7 +66,7 @@ public final class CameraManager {
private final PreviewCallback previewCallback;
public CameraManager(Context context) {
- this.context = context;
+ this.context = context.getApplicationContext();
this.configManager = new CameraConfigurationManager(context);
previewCallback = new PreviewCallback(configManager);
}
diff --git a/lib/src/main/res/layout/capture.xml b/lib/src/main/res/layout/zxl_capture.xml
similarity index 77%
rename from lib/src/main/res/layout/capture.xml
rename to lib/src/main/res/layout/zxl_capture.xml
index d2511d3..faab215 100644
--- a/lib/src/main/res/layout/capture.xml
+++ b/lib/src/main/res/layout/zxl_capture.xml
@@ -1,25 +1,27 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/src/main/res/raw/beep.mp3 b/lib/src/main/res/raw/zxl_beep.mp3
similarity index 100%
rename from lib/src/main/res/raw/beep.mp3
rename to lib/src/main/res/raw/zxl_beep.mp3
diff --git a/lib/src/main/res/values/colors.xml b/lib/src/main/res/values/colors.xml
index 03134c5..128abf9 100644
--- a/lib/src/main/res/values/colors.xml
+++ b/lib/src/main/res/values/colors.xml
@@ -4,7 +4,7 @@
#60000000
#7F1FB3E2
#FF1FB3E2
- #FF1FB3E2
+ #FF1FB3E2
#C0FFBD21
#FFC0C0C0
diff --git a/versions.gradle b/versions.gradle
index 89f045e..43184be 100644
--- a/versions.gradle
+++ b/versions.gradle
@@ -1,7 +1,7 @@
//App
def app_version = [:]
-app_version.versionCode = 8
-app_version.versionName = "1.0.7"
+app_version.versionCode = 9
+app_version.versionName = "1.1.0"
ext.app_version = app_version
//build version