重构v2.0

This commit is contained in:
Jenly
2020-12-23 19:03:44 +08:00
parent 7c87efa216
commit 5eb7511ed9
61 changed files with 2032 additions and 4150 deletions

View File

@@ -0,0 +1,404 @@
package com.king.zxing;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.king.zxing.analyze.Analyzer;
import com.king.zxing.analyze.MultiFormatAnalyzer;
import com.king.zxing.util.LogUtils;
import java.util.concurrent.Executors;
import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
import androidx.camera.core.TorchState;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
/**
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
*/
public class DefaultCameraScan extends CameraScan {
private FragmentActivity mFragmentActivity;
private Context mContext;
private LifecycleOwner mLifecycleOwner;
private PreviewView mPreviewView;
private ListenableFuture<ProcessCameraProvider> mCameraProviderFuture;
private Camera mCamera;
private CameraConfig mCameraConfig;
private Analyzer mAnalyzer;
/**
* 是否分析
*/
private volatile boolean isAnalyze = true;
/**
* 是否已经分析出结果
*/
private volatile boolean isAnalyzeResult;
private View flashlightView;
private MutableLiveData<Result> mResultLiveData;
private OnScanResultCallback mOnScanResultCallback;
private BeepManager mBeepManager;
private AmbientLightManager mAmbientLightManager;
private int mScreenWidth;
private int mScreenHeight;
private long mLastAutoZoomTime;
public DefaultCameraScan(FragmentActivity activity, PreviewView previewView){
this.mFragmentActivity = activity;
this.mLifecycleOwner = activity;
this.mContext = activity;
this.mPreviewView = previewView;
initData();
}
public DefaultCameraScan(Fragment fragment, PreviewView previewView){
this.mFragmentActivity = fragment.getActivity();
this.mLifecycleOwner = fragment;
this.mContext = fragment.getContext();
this.mPreviewView = previewView;
initData();
}
private void initData(){
mResultLiveData = new MutableLiveData<>();
mResultLiveData.observe(mLifecycleOwner, result -> {
handleAnalyzeResult(result);
});
mPreviewView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LogUtils.d("click");
}
});
mPreviewView.setOnTouchListener((v, event) -> onTouchEvent(event));
DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
mScreenWidth = displayMetrics.widthPixels;
mScreenHeight = displayMetrics.heightPixels;
mBeepManager = new BeepManager(mContext);
mAmbientLightManager = new AmbientLightManager(mContext);
if(mAmbientLightManager != null){
mAmbientLightManager.register();
mAmbientLightManager.setOnLightSensorEventListener((dark, lightLux) -> {
if(flashlightView != null){
flashlightView.setSelected(!dark);
if(dark){
if(flashlightView.getVisibility() != View.VISIBLE){
flashlightView.setVisibility(View.VISIBLE);
}
}else if(flashlightView.getVisibility() == View.VISIBLE){
flashlightView.setVisibility(View.INVISIBLE);
}
}
});
}
}
private void initConfig(){
if(mCameraConfig == null){
mCameraConfig = new CameraConfig();
}
if(mAnalyzer == null){
mAnalyzer = new MultiFormatAnalyzer();
}
}
@Override
public CameraScan setCameraConfig(CameraConfig cameraConfig) {
if(cameraConfig != null){
this.mCameraConfig = cameraConfig;
}
return this;
}
@Override
public void startCamera(){
initConfig();
mCameraProviderFuture = ProcessCameraProvider.getInstance(mContext);
mCameraProviderFuture.addListener(() -> {
try{
Preview preview = mCameraConfig.options(new Preview.Builder());
//相机选择器
CameraSelector cameraSelector = mCameraConfig.options(new CameraSelector.Builder()
.requireLensFacing(LENS_FACING_BACK));
//设置SurfaceProvider
preview.setSurfaceProvider(mPreviewView.getSurfaceProvider());
//图像分析
ImageAnalysis imageAnalysis = mCameraConfig.options(new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST));
imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), image -> {
if(isAnalyze && !isAnalyzeResult && mAnalyzer != null){
Result result = mAnalyzer.analyze(image);
if(result != null){
mResultLiveData.postValue(result);
}
}
image.close();
});
if(mCamera != null){
mCameraProviderFuture.get().unbindAll();
}
//绑定到生命周期
mCamera = mCameraProviderFuture.get().bindToLifecycle(mLifecycleOwner, cameraSelector, preview, imageAnalysis);
}catch (Exception e){
LogUtils.e(e);
}
},ContextCompat.getMainExecutor(mContext));
}
/**
* 处理分析结果
* @param result
*/
private synchronized void handleAnalyzeResult(Result result){
if(isAnalyzeResult || !isAnalyze){
return;
}
isAnalyzeResult = true;
if(mBeepManager != null){
mBeepManager.playBeepSoundAndVibrate();
}
if(result.getBarcodeFormat() == BarcodeFormat.QR_CODE && isNeedAutoZoom() && mLastAutoZoomTime + 100 < System.currentTimeMillis()){
ResultPoint[] points = result.getResultPoints();
if(points != null && points.length >= 2){
float distance1 = ResultPoint.distance(points[0],points[1]);
float maxDistance = distance1;
if(points.length >= 3){
float distance2 = ResultPoint.distance(points[1],points[2]);
float distance3 = ResultPoint.distance(points[0],points[2]);
maxDistance = Math.max(Math.max(distance1,distance2),distance3);
}
if(handleAutoZoom((int)maxDistance,result)){
return;
}
}
}
scanResultCallback(result);
}
private boolean handleAutoZoom(int distance,Result result){
int size = Math.min(mScreenWidth,mScreenHeight);
if(distance * 4 < size){
mLastAutoZoomTime = System.currentTimeMillis();
zoomIn();
scanResultCallback(result);
return true;
}
return false;
}
private void scanResultCallback(Result result){
if(mOnScanResultCallback != null && mOnScanResultCallback.onScanResultCallback(result)){
//如果拦截了结果,则重置分析结果状态,直接可以连扫
isAnalyzeResult = false;
return;
}
if(mFragmentActivity != null){
Intent intent = new Intent();
intent.putExtra(SCAN_RESULT,result.getText());
mFragmentActivity.setResult(Activity.RESULT_OK,intent);
mFragmentActivity.finish();
}
}
@Override
public void stopCamera(){
if(mCameraProviderFuture != null){
try {
mCameraProviderFuture.get().unbindAll();
}catch (Exception e){
LogUtils.e(e);
}
}
}
@Override
public CameraScan setAnalyzeImage(boolean analyze) {
isAnalyze = analyze;
return this;
}
/**
* 设置分析器,如果内置的一些分析器不满足您的需求,你也可以自定义{@link Analyzer}
* 自定义时,切记需在{@link #startCamera()}之前调用才有效
* @param analyzer
*/
@Override
public CameraScan setAnalyzer(Analyzer analyzer) {
mAnalyzer = analyzer;
return this;
}
@Override
public void zoomIn(){
if(mCamera != null){
float ratio = mCamera.getCameraInfo().getZoomState().getValue().getZoomRatio() + 0.1f;
float maxRatio = mCamera.getCameraInfo().getZoomState().getValue().getMaxZoomRatio();
if(ratio <= maxRatio){
mCamera.getCameraControl().setZoomRatio(ratio);
}
}
}
@Override
public void zoomOut(){
if(mCamera != null){
float ratio = mCamera.getCameraInfo().getZoomState().getValue().getZoomRatio() - 0.1f;
float minRatio = mCamera.getCameraInfo().getZoomState().getValue().getMinZoomRatio();
if(ratio >= minRatio){
mCamera.getCameraControl().setZoomRatio(ratio);
}
}
}
@Override
public void zoomTo(float ratio) {
if(mCamera != null){
mCamera.getCameraControl().setZoomRatio(ratio);
}
}
@Override
public void lineZoomIn() {
if(mCamera != null){
float zoom = mCamera.getCameraInfo().getZoomState().getValue().getLinearZoom() + 0.1f;
if(zoom <= 1f){
mCamera.getCameraControl().setLinearZoom(zoom);
}
}
}
@Override
public void lineZoomOut() {
if(mCamera != null){
float zoom = mCamera.getCameraInfo().getZoomState().getValue().getLinearZoom() - 0.1f;
if(zoom >= 0f){
mCamera.getCameraControl().setLinearZoom(zoom);
}
}
}
@Override
public void lineZoomTo(@FloatRange(from = 0.0,to = 1.0) float linearZoom) {
if(mCamera != null){
mCamera.getCameraControl().setLinearZoom(linearZoom);
}
}
@Override
public CameraScan enableTorch(boolean torch) {
if(mCamera != null && hasFlashUnit()){
mCamera.getCameraControl().enableTorch(torch);
}
return this;
}
@Override
public boolean isTorchEnabled() {
if(mCamera != null){
return mCamera.getCameraInfo().getTorchState().getValue() == TorchState.ON;
}
return false;
}
/**
* 是否支持闪光灯
* @return
*/
@Override
public boolean hasFlashUnit(){
if(mCamera != null){
return mCamera.getCameraInfo().hasFlashUnit();
}
return false;
}
@Override
public CameraScan setVibrate(boolean vibrate) {
if(mBeepManager != null){
mBeepManager.setVibrate(vibrate);
}
return this;
}
@Override
public CameraScan setPlayBeep(boolean playBeep) {
if(mBeepManager != null){
mBeepManager.setPlayBeep(playBeep);
}
return this;
}
@Override
public CameraScan setOnScanResultCallback(OnScanResultCallback callback) {
this.mOnScanResultCallback = callback;
return this;
}
@Nullable
@Override
public Camera getCamera(){
return mCamera;
}
@Override
public void release() {
isAnalyze = false;
flashlightView = null;
if(mAmbientLightManager != null){
mAmbientLightManager.unregister();
}
if(mBeepManager != null){
mBeepManager.close();
}
stopCamera();
}
@Override
public CameraScan bindFlashlightView(@Nullable View v) {
flashlightView = v;
if(mAmbientLightManager != null){
mAmbientLightManager.setLightSensorEnabled(v != null);
}
return this;
}
}