优化Camera初始化相关策略,减少出现卡顿的可能性(#64,#65)
This commit is contained in:
15
README.md
15
README.md
@@ -56,21 +56,21 @@ ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.king.zxing</groupId>
|
<groupId>com.king.zxing</groupId>
|
||||||
<artifactId>zxing-lite</artifactId>
|
<artifactId>zxing-lite</artifactId>
|
||||||
<version>1.1.4</version>
|
<version>1.1.5</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
### Gradle:
|
### Gradle:
|
||||||
```gradle
|
```gradle
|
||||||
//AndroidX 版本
|
//AndroidX 版本
|
||||||
implementation 'com.king.zxing:zxing-lite:1.1.4-androidx'
|
implementation 'com.king.zxing:zxing-lite:1.1.5-androidx'
|
||||||
|
|
||||||
//Android 版本
|
//Android 版本
|
||||||
implementation 'com.king.zxing:zxing-lite:1.1.4'
|
implementation 'com.king.zxing:zxing-lite:1.1.5'
|
||||||
```
|
```
|
||||||
### Lvy:
|
### Lvy:
|
||||||
```lvy
|
```lvy
|
||||||
<dependency org='com.king.zxing' name='zxing-lite' rev='1.1.4'>
|
<dependency org='com.king.zxing' name='zxing-lite' rev='1.1.5'>
|
||||||
<artifact name='$AID' ext='pom'></artifact>
|
<artifact name='$AID' ext='pom'></artifact>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
@@ -100,9 +100,9 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
布局示例
|
布局示例
|
||||||
> 可自定义布局(覆写getLayoutId方法),布局内至少要保证有SurfaceView和ViewfinderView,控件id可根据覆写CaptureActivity 的 getSurfaceViewId 和 getViewfinderViewId方法自定义
|
> 可自定义布局(覆写getLayoutId方法),布局内至少要保证有SurfaceView和ViewfinderView,控件id可根据覆写CaptureActivity 的 getSurfaceViewId 和 getViewfinderViewId方法自定义
|
||||||
|
|
||||||
> ivTorch为 v1.1.4版本新增的手电筒按钮,如果想改ID可通过CaptureActivity中的getIvTorchId自定义ID
|
> ivTorch为 v1.1.5版本新增的手电筒按钮,如果想改ID可通过CaptureActivity中的getIvTorchId自定义ID
|
||||||
|
|
||||||
> 如果是从v1.1.4以前版本升级至v1.1.4以上版本,请参考如下布局示例(新增ivTorch),也可忽略内置手电筒功能可直接将CaptureActivity中的getIvTorchId方法返回0
|
> 如果是从v1.1.5以前版本升级至v1.1.5以上版本,请参考如下布局示例(新增ivTorch),也可忽略内置手电筒功能可直接将CaptureActivity中的getIvTorchId方法返回0
|
||||||
|
|
||||||
```Xml
|
```Xml
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
@@ -167,6 +167,9 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
|
|
||||||
## 版本记录
|
## 版本记录
|
||||||
|
|
||||||
|
#### v1.1.5:2019-12-16
|
||||||
|
* 优化Camera初始化相关策略,减少出现卡顿的可能性
|
||||||
|
|
||||||
#### v1.1.4:2019-11-18
|
#### v1.1.4:2019-11-18
|
||||||
* 内置手电筒按钮,当光线太暗时,自动显示手电筒 (fix#58)
|
* 内置手电筒按钮,当光线太暗时,自动显示手电筒 (fix#58)
|
||||||
* 生成二维码时Logo支持自定义大小 (fix#62)
|
* 生成二维码时Logo支持自定义大小 (fix#62)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":15,"versionName":"1.1.4","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":17,"versionName":"1.1.5","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -15,18 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.king.zxing.app;
|
package com.king.zxing.app;
|
||||||
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.king.zxing.CaptureActivity;
|
import com.king.zxing.CaptureActivity;
|
||||||
import com.king.zxing.app.util.StatusBarUtils;
|
import com.king.zxing.app.util.StatusBarUtils;
|
||||||
import com.king.zxing.camera.CameraConfigurationUtils;
|
|
||||||
import com.king.zxing.camera.FrontLightMode;
|
import com.king.zxing.camera.FrontLightMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +57,7 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
// .framingRectHorizontalOffset(0)//设置识别区域水平方向偏移量,非全屏识别时才有效
|
// .framingRectHorizontalOffset(0)//设置识别区域水平方向偏移量,非全屏识别时才有效
|
||||||
.frontLightMode(FrontLightMode.AUTO)//设置闪光灯模式
|
.frontLightMode(FrontLightMode.AUTO)//设置闪光灯模式
|
||||||
.tooDarkLux(45f)//设置光线太暗时,自动触发开启闪光灯的照度值
|
.tooDarkLux(45f)//设置光线太暗时,自动触发开启闪光灯的照度值
|
||||||
.brightEnoughLux(450f)//设置光线足够明亮时,自动触发关闭闪光灯的照度值
|
.brightEnoughLux(100f)//设置光线足够明亮时,自动触发关闭闪光灯的照度值
|
||||||
.continuousScan(isContinuousScan);//是否连扫
|
.continuousScan(isContinuousScan);//是否连扫
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class CaptureHandler extends Handler implements ResultPointCallback {
|
|||||||
quit.sendToTarget();
|
quit.sendToTarget();
|
||||||
try {
|
try {
|
||||||
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
|
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
|
||||||
decodeThread.join(500L);
|
decodeThread.join(100L);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||||
*/
|
*/
|
||||||
public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,CaptureManager {
|
public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,CaptureManager, SurfaceHolder.Callback {
|
||||||
|
|
||||||
public static final String TAG = CaptureHelper.class.getSimpleName();
|
public static final String TAG = CaptureHelper.class.getSimpleName();
|
||||||
|
|
||||||
@@ -64,7 +64,6 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
|
|
||||||
private ViewfinderView viewfinderView;
|
private ViewfinderView viewfinderView;
|
||||||
private SurfaceHolder surfaceHolder;
|
private SurfaceHolder surfaceHolder;
|
||||||
private SurfaceHolder.Callback callback;
|
|
||||||
private View ivTorch;
|
private View ivTorch;
|
||||||
|
|
||||||
private Collection<BarcodeFormat> decodeFormats;
|
private Collection<BarcodeFormat> decodeFormats;
|
||||||
@@ -144,6 +143,8 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
*/
|
*/
|
||||||
private OnCaptureCallback onCaptureCallback;
|
private OnCaptureCallback onCaptureCallback;
|
||||||
|
|
||||||
|
private boolean hasCameraFlash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
|
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
|
||||||
* @param fragment
|
* @param fragment
|
||||||
@@ -192,49 +193,8 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
beepManager = new BeepManager(activity);
|
beepManager = new BeepManager(activity);
|
||||||
ambientLightManager = new AmbientLightManager(activity);
|
ambientLightManager = new AmbientLightManager(activity);
|
||||||
|
|
||||||
cameraManager = new CameraManager(activity);
|
hasCameraFlash = activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
|
||||||
cameraManager.setFullScreenScan(isFullScreenScan);
|
initCameraManager();
|
||||||
cameraManager.setFramingRectRatio(framingRectRatio);
|
|
||||||
cameraManager.setFramingRectVerticalOffset(framingRectVerticalOffset);
|
|
||||||
cameraManager.setFramingRectHorizontalOffset(framingRectHorizontalOffset);
|
|
||||||
if(ivTorch !=null && activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
|
|
||||||
ivTorch.setOnClickListener(v -> cameraManager.setTorch(!ivTorch.isSelected()));
|
|
||||||
cameraManager.setOnSensorListener((torch, tooDark, ambientLightLux) -> {
|
|
||||||
if(tooDark){
|
|
||||||
if(ivTorch.getVisibility() != View.VISIBLE){
|
|
||||||
ivTorch.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}else if(!torch){
|
|
||||||
if(ivTorch.getVisibility() == View.VISIBLE){
|
|
||||||
ivTorch.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cameraManager.setOnTorchListener(torch -> ivTorch.setSelected(torch));
|
|
||||||
|
|
||||||
}
|
|
||||||
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 = (result, barcode, scaleFactor) -> {
|
onCaptureListener = (result, barcode, scaleFactor) -> {
|
||||||
inactivityTimer.onActivity();
|
inactivityTimer.onActivity();
|
||||||
@@ -256,17 +216,15 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
@Override
|
@Override
|
||||||
public void onResume(){
|
public void onResume(){
|
||||||
beepManager.updatePrefs();
|
beepManager.updatePrefs();
|
||||||
ambientLightManager.start(cameraManager);
|
|
||||||
|
|
||||||
inactivityTimer.onResume();
|
inactivityTimer.onResume();
|
||||||
|
|
||||||
surfaceHolder.addCallback(callback);
|
|
||||||
|
|
||||||
if (hasSurface) {
|
if (hasSurface) {
|
||||||
initCamera(surfaceHolder);
|
initCamera(surfaceHolder);
|
||||||
} else {
|
} else {
|
||||||
surfaceHolder.addCallback(callback);
|
surfaceHolder.addCallback(this);
|
||||||
}
|
}
|
||||||
|
ambientLightManager.start(cameraManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -281,7 +239,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
beepManager.close();
|
beepManager.close();
|
||||||
cameraManager.closeDriver();
|
cameraManager.closeDriver();
|
||||||
if (!hasSurface) {
|
if (!hasSurface) {
|
||||||
surfaceHolder.removeCallback(callback);
|
surfaceHolder.removeCallback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,6 +284,35 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initCameraManager(){
|
||||||
|
cameraManager = new CameraManager(activity);
|
||||||
|
cameraManager.setFullScreenScan(isFullScreenScan);
|
||||||
|
cameraManager.setFramingRectRatio(framingRectRatio);
|
||||||
|
cameraManager.setFramingRectVerticalOffset(framingRectVerticalOffset);
|
||||||
|
cameraManager.setFramingRectHorizontalOffset(framingRectHorizontalOffset);
|
||||||
|
if(ivTorch !=null && hasCameraFlash){
|
||||||
|
ivTorch.setOnClickListener(v -> {
|
||||||
|
if(cameraManager!=null){
|
||||||
|
cameraManager.setTorch(!ivTorch.isSelected());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cameraManager.setOnSensorListener((torch, tooDark, ambientLightLux) -> {
|
||||||
|
if(tooDark){
|
||||||
|
if(ivTorch.getVisibility() != View.VISIBLE){
|
||||||
|
ivTorch.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}else if(!torch){
|
||||||
|
if(ivTorch.getVisibility() == View.VISIBLE){
|
||||||
|
ivTorch.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cameraManager.setOnTorchListener(torch -> ivTorch.setSelected(torch));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化Camera
|
* 初始化Camera
|
||||||
* @param surfaceHolder
|
* @param surfaceHolder
|
||||||
@@ -356,6 +343,27 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理变焦缩放
|
* 处理变焦缩放
|
||||||
* @param isZoomIn
|
* @param isZoomIn
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ final class InactivityTimer {
|
|||||||
onActivity();
|
onActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void onActivity() {
|
void onActivity() {
|
||||||
cancel();
|
cancel();
|
||||||
inactivityTask = new InactivityAsyncTask(activity);
|
inactivityTask = new InactivityAsyncTask(activity);
|
||||||
try {
|
try {
|
||||||
@@ -60,7 +60,7 @@ final class InactivityTimer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void onPause() {
|
void onPause() {
|
||||||
cancel();
|
cancel();
|
||||||
if (registered) {
|
if (registered) {
|
||||||
activity.unregisterReceiver(powerStatusReceiver);
|
activity.unregisterReceiver(powerStatusReceiver);
|
||||||
@@ -70,7 +70,7 @@ final class InactivityTimer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void onResume() {
|
void onResume() {
|
||||||
if (registered) {
|
if (registered) {
|
||||||
Log.w(TAG, "PowerStatusReceiver was already registered?");
|
Log.w(TAG, "PowerStatusReceiver was already registered?");
|
||||||
} else {
|
} else {
|
||||||
@@ -80,7 +80,7 @@ final class InactivityTimer {
|
|||||||
onActivity();
|
onActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void cancel() {
|
private void cancel() {
|
||||||
AsyncTask<?,?,?> task = inactivityTask;
|
AsyncTask<?,?,?> task = inactivityTask;
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
task.cancel(true);
|
task.cancel(true);
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public final class CameraManager {
|
|||||||
* @param holder The surface object which the camera will draw preview frames into.
|
* @param holder The surface object which the camera will draw preview frames into.
|
||||||
* @throws IOException Indicates the camera driver failed to open.
|
* @throws IOException Indicates the camera driver failed to open.
|
||||||
*/
|
*/
|
||||||
public synchronized void openDriver(SurfaceHolder holder) throws IOException {
|
public void openDriver(SurfaceHolder holder) throws IOException {
|
||||||
OpenCamera theCamera = camera;
|
OpenCamera theCamera = camera;
|
||||||
if (theCamera == null) {
|
if (theCamera == null) {
|
||||||
theCamera = OpenCameraInterface.open(requestedCameraId);
|
theCamera = OpenCameraInterface.open(requestedCameraId);
|
||||||
@@ -146,7 +146,7 @@ public final class CameraManager {
|
|||||||
/**
|
/**
|
||||||
* Closes the camera driver if still in use.
|
* Closes the camera driver if still in use.
|
||||||
*/
|
*/
|
||||||
public synchronized void closeDriver() {
|
public void closeDriver() {
|
||||||
if (camera != null) {
|
if (camera != null) {
|
||||||
camera.getCamera().release();
|
camera.getCamera().release();
|
||||||
camera = null;
|
camera = null;
|
||||||
@@ -160,7 +160,7 @@ public final class CameraManager {
|
|||||||
/**
|
/**
|
||||||
* Asks the camera hardware to begin drawing preview frames to the screen.
|
* Asks the camera hardware to begin drawing preview frames to the screen.
|
||||||
*/
|
*/
|
||||||
public synchronized void startPreview() {
|
public void startPreview() {
|
||||||
OpenCamera theCamera = camera;
|
OpenCamera theCamera = camera;
|
||||||
if (theCamera != null && !previewing) {
|
if (theCamera != null && !previewing) {
|
||||||
theCamera.getCamera().startPreview();
|
theCamera.getCamera().startPreview();
|
||||||
@@ -172,7 +172,7 @@ public final class CameraManager {
|
|||||||
/**
|
/**
|
||||||
* Tells the camera to stop drawing preview frames.
|
* Tells the camera to stop drawing preview frames.
|
||||||
*/
|
*/
|
||||||
public synchronized void stopPreview() {
|
public void stopPreview() {
|
||||||
if (autoFocusManager != null) {
|
if (autoFocusManager != null) {
|
||||||
autoFocusManager.stop();
|
autoFocusManager.stop();
|
||||||
autoFocusManager = null;
|
autoFocusManager = null;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//App
|
//App
|
||||||
def app_version = [:]
|
def app_version = [:]
|
||||||
app_version.versionCode = 15 //androidx 16
|
app_version.versionCode = 17 //androidx 18
|
||||||
app_version.versionName = "1.1.4"
|
app_version.versionName = "1.1.5"
|
||||||
ext.app_version = app_version
|
ext.app_version = app_version
|
||||||
|
|
||||||
//build version
|
//build version
|
||||||
|
|||||||
Reference in New Issue
Block a user