+ * 快速实现扫描识别主要有以下几种方式: + *
+ * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。 + * (适用于大多数场景,自定义布局时需覆写getLayoutId方法) + *
+ * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目 + * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用) + *
+ * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用) + * * @author Jenly */ -public abstract class CameraScan implements ICamera,ICameraControl { +public abstract class CameraScan implements ICamera, ICameraControl { + /** + * 扫描返回结果的key;解析方式可参见:{@link #parseScanResult(Intent)} + */ public static String SCAN_RESULT = "SCAN_RESULT"; - /** A camera on the device facing the same direction as the device's screen. */ + /** + * A camera on the device facing the same direction as the device's screen. + */ public static int LENS_FACING_FRONT = CameraSelector.LENS_FACING_FRONT; - /** A camera on the device facing the opposite direction as the device's screen. */ + /** + * A camera on the device facing the opposite direction as the device's screen. + */ public static int LENS_FACING_BACK = CameraSelector.LENS_FACING_BACK; - /** * 是否需要支持自动缩放 */ @@ -40,15 +58,16 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 是否需要支持触摸缩放 + * * @return */ protected boolean isNeedTouchZoom() { return isNeedTouchZoom; } - /** * 设置是否需要支持触摸缩放 + * * @param needTouchZoom * @return */ @@ -59,6 +78,7 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 是否需要支持自动缩放 + * * @return */ protected boolean isNeedAutoZoom() { @@ -67,6 +87,7 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 设置是否需要支持自动缩放 + * * @param needAutoZoom * @return */ @@ -77,19 +98,21 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 设置相机配置,请在{@link #startCamera()}之前调用 + * * @param cameraConfig */ public abstract CameraScan setCameraConfig(CameraConfig cameraConfig); /** * 设置是否分析图像,通过此方法可以动态控制是否分析图像,常用于中断扫码识别。如:连扫时,扫到结果,然后停止分析图像 - * + *
* 1. 因为分析图像默认为true,如果想支持连扫,在{@link OnScanResultCallback#onScanResultCallback(Result)}返回true拦截即可。 * 当连扫的处理逻辑比较复杂时,请在处理逻辑前通过调用setAnalyzeImage(false)来停止分析图像, * 等逻辑处理完后再调用getCameraScan().setAnalyzeImage(true)来继续分析图像。 - * + *
* 2. 如果只是想拦截扫码结果回调自己处理逻辑,但并不想继续分析图像(即不想连扫),可通过 * 调用getCameraScan().setAnalyzeImage(false)来停止分析图像。 + * * @param analyze */ public abstract CameraScan setAnalyzeImage(boolean analyze); @@ -97,72 +120,77 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 设置分析器,如果内置的一些分析器不满足您的需求,你也可以自定义{@link Analyzer}, * 自定义时,切记需在{@link #startCamera()}之前调用才有效。 - * + *
* 内置了一些{@link Analyzer}的实现类如下: + * + * @param analyzer * @see {@link MultiFormatAnalyzer} * @see {@link AreaRectAnalyzer} * @see {@link ImageAnalyzer} - * * @see {@link BarcodeFormatAnalyzer} * @see {@link QRCodeReader} - * - * @param analyzer */ public abstract CameraScan setAnalyzer(Analyzer analyzer); /** * 设置是否震动 + * * @param vibrate */ public abstract CameraScan setVibrate(boolean vibrate); /** * 设置是否播放提示音 + * * @param playBeep */ public abstract CameraScan setPlayBeep(boolean playBeep); /** * 设置扫码结果回调 + * * @param callback */ public abstract CameraScan setOnScanResultCallback(OnScanResultCallback callback); /** * 绑定手电筒,绑定后可根据光线传感器,动态显示或隐藏手电筒 + * * @param v */ public abstract CameraScan bindFlashlightView(@Nullable View v); /** * 设置光线足够暗的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效 + * * @param lightLux */ public abstract CameraScan setDarkLightLux(float lightLux); /** * 设置光线足够明亮的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效 + * * @param lightLux */ public abstract CameraScan setBrightLightLux(float lightLux); - public interface OnScanResultCallback{ + public interface OnScanResultCallback { /** * 扫码结果回调 + * * @param result * @return 返回false表示不拦截,将关闭扫码界面并将结果返回给调用界面; - * 返回true表示拦截,需自己处理逻辑。当isAnalyze为true时,默认会继续分析图像(也就是连扫)。 - * 如果只是想拦截扫码结果回调,并不想继续分析图像(不想连扫),请在拦截扫码逻辑处通过调 - * 用{@link CameraScan#setAnalyzeImage(boolean)}, - * 因为{@link CameraScan#setAnalyzeImage(boolean)}方法能动态控制是否继续分析图像。 - * + * 返回true表示拦截,需自己处理逻辑。当isAnalyze为true时,默认会继续分析图像(也就是连扫)。 + * 如果只是想拦截扫码结果回调,并不想继续分析图像(不想连扫),请在拦截扫码逻辑处通过调 + * 用{@link CameraScan#setAnalyzeImage(boolean)}, + * 因为{@link CameraScan#setAnalyzeImage(boolean)}方法能动态控制是否继续分析图像。 */ boolean onScanResultCallback(Result result); /** * 扫码结果识别失败时触发此回调方法 */ - default void onScanResultFailure(){ + default void onScanResultFailure() { } @@ -170,12 +198,13 @@ public abstract class CameraScan implements ICamera,ICameraControl { /** * 解析扫码结果 + * * @param data * @return */ @Nullable - public static String parseScanResult(Intent data){ - if(data != null){ + public static String parseScanResult(Intent data) { + if (data != null) { return data.getStringExtra(SCAN_RESULT); } return null; diff --git a/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java b/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java index 9c413d1..99bb782 100644 --- a/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java +++ b/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java @@ -29,9 +29,21 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.camera.view.PreviewView; /** + * 相机扫描基类;{@link CaptureActivity} 内部持有{@link CameraScan},便于快速实现扫描识别。 + *
+ * 快速实现扫描识别主要有以下几种方式: + *
+ * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。 + * (适用于大多数场景,自定义布局时需覆写getLayoutId方法) + *
+ * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目 + * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用) + *
+ * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用) + * * @author Jenly */ -public class CaptureActivity extends AppCompatActivity implements CameraScan.OnScanResultCallback{ +public class CaptureActivity extends AppCompatActivity implements CameraScan.OnScanResultCallback { private static final int CAMERA_PERMISSION_REQUEST_CODE = 0X86; @@ -44,7 +56,7 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if(isContentView()){ + if (isContentView()) { setContentView(getLayoutId()); } initUI(); @@ -53,16 +65,16 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS /** * 初始化 */ - public void initUI(){ + public void initUI() { previewView = findViewById(getPreviewViewId()); int viewfinderViewId = getViewfinderViewId(); - if(viewfinderViewId != 0){ + if (viewfinderViewId != 0) { viewfinderView = findViewById(viewfinderViewId); } int ivFlashlightId = getFlashlightId(); - if(ivFlashlightId != 0){ + if (ivFlashlightId != 0) { ivFlashlight = findViewById(ivFlashlightId); - if(ivFlashlight != null){ + if (ivFlashlight != null) { ivFlashlight.setOnClickListener(v -> onClickFlashlight()); } } @@ -73,39 +85,37 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS /** * 点击手电筒 */ - protected void onClickFlashlight(){ + protected void onClickFlashlight() { toggleTorchState(); } /** * 初始化CameraScan */ - public void initCameraScan(){ - mCameraScan = new DefaultCameraScan(this,previewView); + public void initCameraScan() { + mCameraScan = new DefaultCameraScan(this, previewView); mCameraScan.setOnScanResultCallback(this); } - /** * 启动相机预览 */ - public void startCamera(){ - if(mCameraScan != null){ - if(PermissionUtils.checkPermission(this,Manifest.permission.CAMERA)){ + public void startCamera() { + if (mCameraScan != null) { + if (PermissionUtils.checkPermission(this, Manifest.permission.CAMERA)) { mCameraScan.startCamera(); - }else{ + } else { LogUtils.d("checkPermissionResult != PERMISSION_GRANTED"); - PermissionUtils.requestPermission(this,Manifest.permission.CAMERA,CAMERA_PERMISSION_REQUEST_CODE); + PermissionUtils.requestPermission(this, Manifest.permission.CAMERA, CAMERA_PERMISSION_REQUEST_CODE); } } } - /** * 释放相机 */ - private void releaseCamera(){ - if(mCameraScan != null){ + private void releaseCamera() { + if (mCameraScan != null) { mCameraScan.release(); } } @@ -113,11 +123,11 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS /** * 切换闪光灯状态(开启/关闭) */ - protected void toggleTorchState(){ - if(mCameraScan != null){ + protected void toggleTorchState() { + if (mCameraScan != null) { boolean isTorch = mCameraScan.isTorchEnabled(); mCameraScan.enableTorch(!isTorch); - if(ivFlashlight != null){ + if (ivFlashlight != null) { ivFlashlight.setSelected(!isTorch); } } @@ -126,20 +136,21 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if(requestCode == CAMERA_PERMISSION_REQUEST_CODE){ - requestCameraPermissionResult(permissions,grantResults); + if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) { + requestCameraPermissionResult(permissions, grantResults); } } /** * 请求Camera权限回调结果 + * * @param permissions * @param grantResults */ - public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults){ - if(PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA,permissions,grantResults)){ + public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { + if (PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA, permissions, grantResults)) { startCamera(); - }else{ + } else { finish(); } } @@ -152,55 +163,62 @@ public class CaptureActivity extends AppCompatActivity implements CameraScan.OnS /** * 返回true时会自动初始化{@link #setContentView(int)},返回为false是需自己去初始化{@link #setContentView(int)} + * * @return 默认返回true */ - public boolean isContentView(){ + public boolean isContentView() { return true; } /** - * 布局id + * 布局ID;通过覆写此方法可以自定义布局 + * * @return */ - public int getLayoutId(){ + public int getLayoutId() { return R.layout.zxl_capture; } /** * {@link #viewfinderView} 的 ID + * * @return 默认返回{@code R.id.viewfinderView}, 如果不需要扫码框可以返回0 */ - public int getViewfinderViewId(){ + public int getViewfinderViewId() { return R.id.viewfinderView; } /** * 预览界面{@link #previewView} 的ID + * * @return */ - public int getPreviewViewId(){ + public int getPreviewViewId() { return R.id.previewView; } /** * 获取 {@link #ivFlashlight} 的ID - * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0 + * + * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0 */ - public int getFlashlightId(){ + public int getFlashlightId() { return R.id.ivFlashlight; } /** * Get {@link CameraScan} + * * @return {@link #mCameraScan} */ - public CameraScan getCameraScan(){ + public CameraScan getCameraScan() { return mCameraScan; } /** * 接收扫码结果回调 + * * @param result 扫码结果 * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截 */ diff --git a/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java b/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java index 5eaa9c9..462fb97 100644 --- a/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java +++ b/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java @@ -30,6 +30,18 @@ import androidx.camera.view.PreviewView; import androidx.fragment.app.Fragment; /** + * 相机扫描基类;{@link CaptureFragment} 内部持有{@link CameraScan},便于快速实现扫描识别。 + *
+ * 快速实现扫描识别主要有以下几种方式: + *
+ * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。 + * (适用于大多数场景,自定义布局时需覆写getLayoutId方法) + *
+ * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目 + * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用) + *
+ * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用) + * * @author Jenly */ public class CaptureFragment extends Fragment implements CameraScan.OnScanResultCallback { @@ -53,11 +65,10 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult return fragment; } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - if(isContentView()){ - mRootView = createRootView(inflater,container); + if (isContentView()) { + mRootView = createRootView(inflater, container); } initUI(); return mRootView; @@ -66,16 +77,16 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult /** * 初始化 */ - public void initUI(){ + public void initUI() { previewView = mRootView.findViewById(getPreviewViewId()); int viewfinderViewId = getViewfinderViewId(); - if(viewfinderViewId != 0){ + if (viewfinderViewId != 0) { viewfinderView = mRootView.findViewById(viewfinderViewId); } int ivFlashlightId = getFlashlightId(); - if(ivFlashlightId != 0){ + if (ivFlashlightId != 0) { ivFlashlight = mRootView.findViewById(ivFlashlightId); - if(ivFlashlight != null){ + if (ivFlashlight != null) { ivFlashlight.setOnClickListener(v -> onClickFlashlight()); } } @@ -86,28 +97,28 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult /** * 点击手电筒 */ - protected void onClickFlashlight(){ + protected void onClickFlashlight() { toggleTorchState(); } /** * 初始化CameraScan */ - public void initCameraScan(){ - mCameraScan = new DefaultCameraScan(this,previewView); + public void initCameraScan() { + mCameraScan = new DefaultCameraScan(this, previewView); mCameraScan.setOnScanResultCallback(this); } /** * 启动相机预览 */ - public void startCamera(){ - if(mCameraScan != null){ - if(PermissionUtils.checkPermission(getContext(), Manifest.permission.CAMERA)){ + public void startCamera() { + if (mCameraScan != null) { + if (PermissionUtils.checkPermission(getContext(), Manifest.permission.CAMERA)) { mCameraScan.startCamera(); - }else{ + } else { LogUtils.d("checkPermissionResult != PERMISSION_GRANTED"); - PermissionUtils.requestPermission(this,Manifest.permission.CAMERA,CAMERA_PERMISSION_REQUEST_CODE); + PermissionUtils.requestPermission(this, Manifest.permission.CAMERA, CAMERA_PERMISSION_REQUEST_CODE); } } } @@ -115,8 +126,8 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult /** * 释放相机 */ - private void releaseCamera(){ - if(mCameraScan != null){ + private void releaseCamera() { + if (mCameraScan != null) { mCameraScan.release(); } } @@ -124,11 +135,11 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult /** * 切换闪光灯状态(开启/关闭) */ - protected void toggleTorchState(){ - if(mCameraScan != null){ + protected void toggleTorchState() { + if (mCameraScan != null) { boolean isTorch = mCameraScan.isTorchEnabled(); mCameraScan.enableTorch(!isTorch); - if(ivFlashlight != null){ + if (ivFlashlight != null) { ivFlashlight.setSelected(!isTorch); } } @@ -137,20 +148,21 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if(requestCode == CAMERA_PERMISSION_REQUEST_CODE){ - requestCameraPermissionResult(permissions,grantResults); + if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) { + requestCameraPermissionResult(permissions, grantResults); } } /** * 请求Camera权限回调结果 + * * @param permissions * @param grantResults */ - public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults){ - if(PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA,permissions,grantResults)){ + public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { + if (PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA, permissions, grantResults)) { startCamera(); - }else{ + } else { getActivity().finish(); } } @@ -163,66 +175,73 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult /** * 返回true时会自动初始化{@link #createRootView(LayoutInflater, ViewGroup)},返回为false是需自己去初始化{@link #createRootView(LayoutInflater, ViewGroup)} + * * @return 默认返回true */ - public boolean isContentView(){ + public boolean isContentView() { return true; } /** * 创建{@link #mRootView} + * * @param inflater * @param container * @return */ @NonNull - public View createRootView(LayoutInflater inflater, ViewGroup container){ - return inflater.inflate(getLayoutId(),container,false); + public View createRootView(LayoutInflater inflater, ViewGroup container) { + return inflater.inflate(getLayoutId(), container, false); } /** - * 布局id + * 布局ID;通过覆写此方法可以自定义布局 + * * @return */ - public int getLayoutId(){ + public int getLayoutId() { return R.layout.zxl_capture; } /** * {@link #viewfinderView} 的 ID + * * @return 默认返回{@code R.id.viewfinderView}, 如果不需要扫码框可以返回0 */ - public int getViewfinderViewId(){ + public int getViewfinderViewId() { return R.id.viewfinderView; } - /** * 预览界面{@link #previewView} 的ID + * * @return */ - public int getPreviewViewId(){ + public int getPreviewViewId() { return R.id.previewView; } /** * 获取 {@link #ivFlashlight} 的ID - * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0 + * + * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0 */ - public int getFlashlightId(){ + public int getFlashlightId() { return R.id.ivFlashlight; } /** * Get {@link CameraScan} + * * @return {@link #mCameraScan} */ - public CameraScan getCameraScan(){ + public CameraScan getCameraScan() { return mCameraScan; } /** * 接收扫码结果回调 + * * @param result 扫码结果 * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截 */ @@ -237,5 +256,4 @@ public class CaptureFragment extends Fragment implements CameraScan.OnScanResult return mRootView; } - } diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java index 0cdc18b..308d89f 100644 --- a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java +++ b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java @@ -12,11 +12,12 @@ import java.util.Map; import androidx.annotation.FloatRange; - /** * 解码配置:主要用于在扫码识别时,提供一些配置,便于扩展。通过配置可决定内置分析器的能力,从而间接的控制并简化扫码识别的流程 *
> * 设置解码 {@link #setHints(Map)}内置的一些解码可参见如下: + * + * @author Jenly * @see {@link DecodeFormatManager#DEFAULT_HINTS} * @see {@link DecodeFormatManager#ALL_HINTS} * @see {@link DecodeFormatManager#CODE_128_HINTS} @@ -24,7 +25,7 @@ import androidx.annotation.FloatRange; * @see {@link DecodeFormatManager#ONE_DIMENSIONAL_HINTS} * @see {@link DecodeFormatManager#TWO_DIMENSIONAL_HINTS} * @see {@link DecodeFormatManager#DEFAULT_HINTS} - * + *
* 如果不满足您也可以通过{@link DecodeFormatManager#createDecodeHints(BarcodeFormat...)}自己配置支持的格式 * *
> @@ -32,18 +33,16 @@ import androidx.annotation.FloatRange; * {@link #setFullAreaScan(boolean)} 设置是否支持全区域扫码识别,优先级比识别区域高 * {@link #setAnalyzeAreaRect(Rect)} 设置需要分析识别区域,优先级比识别区域比例高,当设置了指定的分析区域时,识别区域比例和识别区域偏移量相关参数都将无效 * {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低 - * + *
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域, * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息 - * + *
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)} *
>
- *
- * @author Jenly
*/
public class DecodeConfig {
- private Map
+ * 内置的一些解码可参见如下:
+ * @return
* @see {@link DecodeFormatManager#DEFAULT_HINTS}
* @see {@link DecodeFormatManager#ALL_HINTS}
* @see {@link DecodeFormatManager#CODE_128_HINTS}
@@ -112,10 +113,8 @@ public class DecodeConfig {
* @see {@link DecodeFormatManager#ONE_DIMENSIONAL_HINTS}
* @see {@link DecodeFormatManager#TWO_DIMENSIONAL_HINTS}
* @see {@link DecodeFormatManager#DEFAULT_HINTS}
- *
+ *
* 如果不满足您也可以通过{@link DecodeFormatManager#createDecodeHints(BarcodeFormat...)}自己配置支持的格式
- *
- * @return
*/
public DecodeConfig setHints(Map
+ * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
+ * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
+ *
+ * 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return
*/
public DecodeConfig setAnalyzeAreaRect(Rect analyzeAreaRect) {
@@ -246,6 +253,7 @@ public class DecodeConfig {
/**
* 是否支持全区域扫码识别
+ *
* @return
*/
public boolean isFullAreaScan() {
@@ -254,17 +262,18 @@ public class DecodeConfig {
/**
* 设置是否支持全区域扫码识别,优先级比识别区域高
+ *
* @param fullAreaScan 默认为{@code true}
- *
- * 识别区域可设置的方式有如下几种:
- * {@link #setFullAreaScan(boolean)} 设置是否支持全区域扫码识别,优先级比识别区域高
- * {@link #setAnalyzeAreaRect(Rect)} 设置需要分析识别区域,优先级比识别区域比例高,当设置了指定的分析区域时,识别区域比例和识别区域偏移量相关参数都将无效
- * {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
- *
- * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
- *
- * 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
+ *
+ * 识别区域可设置的方式有如下几种:
+ * {@link #setFullAreaScan(boolean)} 设置是否支持全区域扫码识别,优先级比识别区域高
+ * {@link #setAnalyzeAreaRect(Rect)} 设置需要分析识别区域,优先级比识别区域比例高,当设置了指定的分析区域时,识别区域比例和识别区域偏移量相关参数都将无效
+ * {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
+ *
+ * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
+ * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
+ *
+ * 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return
*/
public DecodeConfig setFullAreaScan(boolean fullAreaScan) {
@@ -274,6 +283,7 @@ public class DecodeConfig {
/**
* 识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别
+ *
* @return
*/
public float getAreaRectRatio() {
@@ -282,27 +292,26 @@ public class DecodeConfig {
/**
* 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
- * @param areaRectRatio
- *
- * 识别区域可设置的方式有如下几种:
- * {@link #setFullAreaScan(boolean)} 设置是否支持全区域扫码识别,优先级比识别区域高
- * {@link #setAnalyzeAreaRect(Rect)} 设置需要分析识别区域,优先级比识别区域比例高,当设置了指定的分析区域时,识别区域比例和识别区域偏移量相关参数都将无效
- * {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
- *
- * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
- *
- * 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
*
+ * @param areaRectRatio 识别区域可设置的方式有如下几种:
+ * {@link #setFullAreaScan(boolean)} 设置是否支持全区域扫码识别,优先级比识别区域高
+ * {@link #setAnalyzeAreaRect(Rect)} 设置需要分析识别区域,优先级比识别区域比例高,当设置了指定的分析区域时,识别区域比例和识别区域偏移量相关参数都将无效
+ * {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
+ *
+ * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
+ * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
+ *
+ * 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return
*/
- public DecodeConfig setAreaRectRatio(@FloatRange(from = 0.5,to = 1.0) float areaRectRatio) {
+ public DecodeConfig setAreaRectRatio(@FloatRange(from = 0.5, to = 1.0) float areaRectRatio) {
this.areaRectRatio = areaRectRatio;
return this;
}
/**
* 识别区域垂直方向偏移量,支持负数,大于0时,居中心向下偏移,小于0时,居中心向上偏移
+ *
* @return
*/
public int getAreaRectVerticalOffset() {
@@ -311,6 +320,7 @@ public class DecodeConfig {
/**
* 设置识别区域垂直方向偏移量,支持负数,大于0时,居中心向下偏移,小于0时,居中心向上偏移
+ *
* @param areaRectVerticalOffset
* @return
*/
@@ -321,6 +331,7 @@ public class DecodeConfig {
/**
* 识别区域水平方向偏移量,支持负数,大于0时,居中心向右偏移,小于0时,居中心向左偏移
+ *
* @return
*/
public int getAreaRectHorizontalOffset() {
@@ -329,6 +340,7 @@ public class DecodeConfig {
/**
* 设置识别区域水平方向偏移量,支持负数,大于0时,居中心向右偏移,小于0时,居中心向左偏移
+ *
* @param areaRectHorizontalOffset
* @return
*/
diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
index a0eef3b..0a08c42 100644
--- a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
+++ b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
@@ -13,6 +13,10 @@ import java.util.Map;
import androidx.annotation.NonNull;
/**
+ * 解码格式管理器
+ *
+ * 将常见的一些解码配置已根据条形码类型进行了几大划分,可根据需要找到符合的划分配置类型直接使用。
+ *
* @author Jenly
*/
public final class DecodeFormatManager {
@@ -20,45 +24,46 @@ public final class DecodeFormatManager {
/**
* 所有的
*/
- public static final Map
+ * 快速实现扫描识别主要有以下几种方式:
+ *
+ * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。
+ * (适用于大多数场景,自定义布局时需覆写getLayoutId方法)
+ *
+ * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目
+ * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用)
+ *
+ * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用)
+ *
* @author Jenly
*/
public class DefaultCameraScan extends CameraScan {
@@ -61,6 +75,11 @@ public class DefaultCameraScan extends CameraScan {
*/
private static final int HOVER_TAP_SLOP = 20;
+ /**
+ * 每次缩放改变的步长
+ */
+ private static final float ZOOM_STEP_SIZE = 0.1F;
+
private FragmentActivity mFragmentActivity;
private Context mContext;
private LifecycleOwner mLifecycleOwner;
@@ -92,15 +111,15 @@ public class DefaultCameraScan extends CameraScan {
private AmbientLightManager mAmbientLightManager;
private int mOrientation;
- private int mScreenWidth;
- private int mScreenHeight;
+ private int mImageWidth;
+ private int mImageHeight;
private long mLastAutoZoomTime;
private long mLastHoveTapTime;
private boolean isClickTap;
private float mDownX;
private float mDownY;
- public DefaultCameraScan(@NonNull FragmentActivity activity,@NonNull PreviewView previewView){
+ public DefaultCameraScan(@NonNull FragmentActivity activity, @NonNull PreviewView previewView) {
this.mFragmentActivity = activity;
this.mLifecycleOwner = activity;
this.mContext = activity;
@@ -108,7 +127,7 @@ public class DefaultCameraScan extends CameraScan {
initData();
}
- public DefaultCameraScan(@NonNull Fragment fragment,@NonNull PreviewView previewView){
+ public DefaultCameraScan(@NonNull Fragment fragment, @NonNull PreviewView previewView) {
this.mFragmentActivity = fragment.getActivity();
this.mLifecycleOwner = fragment;
this.mContext = fragment.getContext();
@@ -116,25 +135,34 @@ public class DefaultCameraScan extends CameraScan {
initData();
}
- private ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener = new ScaleGestureDetector.SimpleOnScaleGestureListener(){
+ /**
+ * 缩放手势检测
+ */
+ private ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = detector.getScaleFactor();
- if(mCamera != null){
+ if (mCamera != null) {
float ratio = mCamera.getCameraInfo().getZoomState().getValue().getZoomRatio();
+ // 根据缩放的手势和当前比例进行缩放
zoomTo(ratio * scale);
+ return true;
}
- return true;
+ return false;
}
};
- private void initData(){
+ /**
+ * 初始化
+ */
+ @SuppressLint("ClickableViewAccessibility")
+ private void initData() {
mResultLiveData = new MutableLiveData<>();
mResultLiveData.observe(mLifecycleOwner, result -> {
- if(result != null){
+ if (result != null) {
handleAnalyzeResult(result);
- }else if(mOnScanResultCallback != null){
+ } else if (mOnScanResultCallback != null) {
mOnScanResultCallback.onScanResultFailure();
}
});
@@ -144,42 +172,38 @@ public class DefaultCameraScan extends CameraScan {
ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener);
mPreviewView.setOnTouchListener((v, event) -> {
handlePreviewViewClickTap(event);
- if(isNeedTouchZoom()){
+ if (isNeedTouchZoom()) {
return scaleGestureDetector.onTouchEvent(event);
}
return false;
});
- DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- mScreenWidth = displayMetrics.widthPixels;
- mScreenHeight = displayMetrics.heightPixels;
-
- LogUtils.d(String.format("displayMetrics:%dx%d",mScreenWidth,mScreenHeight));
-
mBeepManager = new BeepManager(mContext);
mAmbientLightManager = new AmbientLightManager(mContext);
- if(mAmbientLightManager != null){
- mAmbientLightManager.register();
- mAmbientLightManager.setOnLightSensorEventListener((dark, lightLux) -> {
- if(flashlightView != null){
- if(dark){
- if(flashlightView.getVisibility() != View.VISIBLE){
- flashlightView.setVisibility(View.VISIBLE);
- flashlightView.setSelected(isTorchEnabled());
- }
- }else if(flashlightView.getVisibility() == View.VISIBLE && !isTorchEnabled()){
- flashlightView.setVisibility(View.INVISIBLE);
- flashlightView.setSelected(false);
+ mAmbientLightManager.register();
+ mAmbientLightManager.setOnLightSensorEventListener((dark, lightLux) -> {
+ if (flashlightView != null) {
+ if (dark) {
+ if (flashlightView.getVisibility() != View.VISIBLE) {
+ flashlightView.setVisibility(View.VISIBLE);
+ flashlightView.setSelected(isTorchEnabled());
}
-
+ } else if (flashlightView.getVisibility() == View.VISIBLE && !isTorchEnabled()) {
+ flashlightView.setVisibility(View.INVISIBLE);
+ flashlightView.setSelected(false);
}
- });
- }
+ }
+ });
}
- private void handlePreviewViewClickTap(MotionEvent event){
- if(event.getPointerCount() == 1){
- switch (event.getAction()){
+ /**
+ * 处理预览视图点击事件;如果触发的点击事件被判定对焦操作,则开始自动对焦
+ *
+ * @param event
+ */
+ private void handlePreviewViewClickTap(MotionEvent event) {
+ if (event.getPointerCount() == 1) {
+ switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isClickTap = true;
mDownX = event.getX();
@@ -187,35 +211,43 @@ public class DefaultCameraScan extends CameraScan {
mLastHoveTapTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
- isClickTap = MathUtils.distance(mDownX,mDownY,event.getX(),event.getY()) < HOVER_TAP_SLOP;
+ isClickTap = MathUtils.distance(mDownX, mDownY, event.getX(), event.getY()) < HOVER_TAP_SLOP;
break;
case MotionEvent.ACTION_UP:
- if(isClickTap && mLastHoveTapTime + HOVER_TAP_TIMEOUT > System.currentTimeMillis()){
- startFocusAndMetering(event.getX(),event.getY());
+ if (isClickTap && mLastHoveTapTime + HOVER_TAP_TIMEOUT > System.currentTimeMillis()) {
+ // 开始对焦和测光
+ startFocusAndMetering(event.getX(), event.getY());
}
break;
}
}
}
- private void startFocusAndMetering(float x, float y){
- if(mCamera != null){
- MeteringPoint point = mPreviewView.getMeteringPointFactory().createPoint(x,y);
+ /**
+ * 开始对焦和测光
+ *
+ * @param x
+ * @param y
+ */
+ private void startFocusAndMetering(float x, float y) {
+ if (mCamera != null) {
+ MeteringPoint point = mPreviewView.getMeteringPointFactory().createPoint(x, y);
FocusMeteringAction focusMeteringAction = new FocusMeteringAction.Builder(point).build();
- if(mCamera.getCameraInfo().isFocusMeteringSupported(focusMeteringAction)){
+ if (mCamera.getCameraInfo().isFocusMeteringSupported(focusMeteringAction)) {
mCamera.getCameraControl().startFocusAndMetering(focusMeteringAction);
LogUtils.d("startFocusAndMetering:" + x + "," + y);
}
}
}
-
-
- private void initConfig(){
- if(mCameraConfig == null){
+ /**
+ * 初始化配置
+ */
+ private void initConfig() {
+ if (mCameraConfig == null) {
mCameraConfig = new CameraConfig();
}
- if(mAnalyzer == null){
+ if (mAnalyzer == null) {
mAnalyzer = new MultiFormatAnalyzer();
}
}
@@ -223,19 +255,19 @@ public class DefaultCameraScan extends CameraScan {
@Override
public CameraScan setCameraConfig(CameraConfig cameraConfig) {
- if(cameraConfig != null){
+ if (cameraConfig != null) {
this.mCameraConfig = cameraConfig;
}
return this;
}
@Override
- public void startCamera(){
+ public void startCamera() {
initConfig();
mCameraProviderFuture = ProcessCameraProvider.getInstance(mContext);
mCameraProviderFuture.addListener(() -> {
- try{
+ try {
Preview preview = mCameraConfig.options(new Preview.Builder());
//相机选择器
@@ -248,49 +280,52 @@ public class DefaultCameraScan extends CameraScan {
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST));
imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), image -> {
- if(isAnalyze && !isAnalyzeResult && mAnalyzer != null){
- Result result = mAnalyzer.analyze(image,mOrientation);
+ mImageWidth = image.getWidth();
+ mImageHeight = image.getHeight();
+ if (isAnalyze && !isAnalyzeResult && mAnalyzer != null) {
+ Result result = mAnalyzer.analyze(image, mOrientation);
mResultLiveData.postValue(result);
}
image.close();
});
- if(mCamera != null){
+ if (mCamera != null) {
mCameraProviderFuture.get().unbindAll();
}
- //绑定到生命周期
+ // 绑定到生命周期
mCamera = mCameraProviderFuture.get().bindToLifecycle(mLifecycleOwner, cameraSelector, preview, imageAnalysis);
- }catch (Exception e){
+ } catch (Exception e) {
LogUtils.e(e);
}
- },ContextCompat.getMainExecutor(mContext));
+ }, ContextCompat.getMainExecutor(mContext));
}
/**
* 处理分析结果
+ *
* @param result
*/
- private synchronized void handleAnalyzeResult(Result result){
+ private synchronized void handleAnalyzeResult(Result result) {
- if(isAnalyzeResult || !isAnalyze){
+ if (isAnalyzeResult || !isAnalyze) {
return;
}
isAnalyzeResult = true;
- if(mBeepManager != null){
+ if (mBeepManager != null) {
mBeepManager.playBeepSoundAndVibrate();
}
- if(result.getBarcodeFormat() == BarcodeFormat.QR_CODE && isNeedAutoZoom() && mLastAutoZoomTime + 100 < System.currentTimeMillis()){
+ 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]);
+ 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 (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)){
+ if (handleAutoZoom((int) maxDistance, result)) {
return;
}
}
@@ -299,9 +334,15 @@ public class DefaultCameraScan extends CameraScan {
scanResultCallback(result);
}
- private boolean handleAutoZoom(int distance,Result result){
- int size = Math.min(mScreenWidth,mScreenHeight);
- if(distance * 4 < size){
+ /**
+ * 处理自动缩放
+ * @param distance
+ * @param result
+ * @return
+ */
+ private boolean handleAutoZoom(int distance, Result result) {
+ int size = Math.min(mImageWidth, mImageHeight);
+ if (distance * 4 < size) {
mLastAutoZoomTime = System.currentTimeMillis();
zoomIn();
scanResultCallback(result);
@@ -310,8 +351,12 @@ public class DefaultCameraScan extends CameraScan {
return false;
}
- private void scanResultCallback(Result result){
- if(mOnScanResultCallback != null && mOnScanResultCallback.onScanResultCallback(result)){
+ /**
+ * 扫描结果回调
+ * @param result
+ */
+ private void scanResultCallback(Result result) {
+ if (mOnScanResultCallback != null && mOnScanResultCallback.onScanResultCallback(result)) {
/*
* 如果拦截了结果,则重置分析结果状态,并当isAnalyze为true时,默认会继续分析图像(也就是连扫)。
* 如果只是想拦截扫码结果回调,并不想继续分析图像(不想连扫),请在拦截扫码逻辑处通过调用
@@ -321,21 +366,20 @@ public class DefaultCameraScan extends CameraScan {
return;
}
- if(mFragmentActivity != null){
+ if (mFragmentActivity != null) {
Intent intent = new Intent();
- intent.putExtra(SCAN_RESULT,result.getText());
- mFragmentActivity.setResult(Activity.RESULT_OK,intent);
+ intent.putExtra(SCAN_RESULT, result.getText());
+ mFragmentActivity.setResult(Activity.RESULT_OK, intent);
mFragmentActivity.finish();
}
}
-
@Override
- public void stopCamera(){
- if(mCameraProviderFuture != null){
+ public void stopCamera() {
+ if (mCameraProviderFuture != null) {
try {
mCameraProviderFuture.get().unbindAll();
- }catch (Exception e){
+ } catch (Exception e) {
LogUtils.e(e);
}
}
@@ -353,45 +397,45 @@ public class DefaultCameraScan extends CameraScan {
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){
+ public void zoomIn() {
+ if (mCamera != null) {
+ float ratio = getCameraInfo().getZoomState().getValue().getZoomRatio() + ZOOM_STEP_SIZE;
+ float maxRatio = 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){
+ public void zoomOut() {
+ if (mCamera != null) {
+ float ratio = getCameraInfo().getZoomState().getValue().getZoomRatio() - ZOOM_STEP_SIZE;
+ float minRatio = getCameraInfo().getZoomState().getValue().getMinZoomRatio();
+ if (ratio >= minRatio) {
mCamera.getCameraControl().setZoomRatio(ratio);
}
}
}
-
@Override
public void zoomTo(float ratio) {
- if(mCamera != null){
- ZoomState zoomState = mCamera.getCameraInfo().getZoomState().getValue();
+ if (mCamera != null) {
+ ZoomState zoomState = getCameraInfo().getZoomState().getValue();
float maxRatio = zoomState.getMaxZoomRatio();
float minRatio = zoomState.getMinZoomRatio();
- float zoom = Math.max(Math.min(ratio,maxRatio),minRatio);
+ float zoom = Math.max(Math.min(ratio, maxRatio), minRatio);
mCamera.getCameraControl().setZoomRatio(zoom);
}
}
@Override
public void lineZoomIn() {
- if(mCamera != null){
- float zoom = mCamera.getCameraInfo().getZoomState().getValue().getLinearZoom() + 0.1f;
- if(zoom <= 1f){
+ if (mCamera != null) {
+ float zoom = getCameraInfo().getZoomState().getValue().getLinearZoom() + ZOOM_STEP_SIZE;
+ if (zoom <= 1f) {
mCamera.getCameraControl().setLinearZoom(zoom);
}
}
@@ -399,31 +443,31 @@ public class DefaultCameraScan extends CameraScan {
@Override
public void lineZoomOut() {
- if(mCamera != null){
- float zoom = mCamera.getCameraInfo().getZoomState().getValue().getLinearZoom() - 0.1f;
- if(zoom >= 0f){
+ if (mCamera != null) {
+ float zoom = getCameraInfo().getZoomState().getValue().getLinearZoom() - ZOOM_STEP_SIZE;
+ if (zoom >= 0f) {
mCamera.getCameraControl().setLinearZoom(zoom);
}
}
}
@Override
- public void lineZoomTo(@FloatRange(from = 0.0,to = 1.0) float linearZoom) {
- if(mCamera != null){
+ public void lineZoomTo(@FloatRange(from = 0.0, to = 1.0) float linearZoom) {
+ if (mCamera != null) {
mCamera.getCameraControl().setLinearZoom(linearZoom);
}
}
@Override
public void enableTorch(boolean torch) {
- if(mCamera != null && hasFlashUnit()){
+ if (mCamera != null && hasFlashUnit()) {
mCamera.getCameraControl().enableTorch(torch);
}
}
@Override
public boolean isTorchEnabled() {
- if(mCamera != null){
+ if (mCamera != null) {
return mCamera.getCameraInfo().getTorchState().getValue() == TorchState.ON;
}
return false;
@@ -431,11 +475,12 @@ public class DefaultCameraScan extends CameraScan {
/**
* 是否支持闪光灯
+ *
* @return
*/
@Override
- public boolean hasFlashUnit(){
- if(mCamera != null){
+ public boolean hasFlashUnit() {
+ if (mCamera != null) {
return mCamera.getCameraInfo().hasFlashUnit();
}
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
@@ -443,7 +488,7 @@ public class DefaultCameraScan extends CameraScan {
@Override
public CameraScan setVibrate(boolean vibrate) {
- if(mBeepManager != null){
+ if (mBeepManager != null) {
mBeepManager.setVibrate(vibrate);
}
return this;
@@ -451,7 +496,7 @@ public class DefaultCameraScan extends CameraScan {
@Override
public CameraScan setPlayBeep(boolean playBeep) {
- if(mBeepManager != null){
+ if (mBeepManager != null) {
mBeepManager.setPlayBeep(playBeep);
}
return this;
@@ -465,19 +510,27 @@ public class DefaultCameraScan extends CameraScan {
@Nullable
@Override
- public Camera getCamera(){
+ public Camera getCamera() {
return mCamera;
}
+ /**
+ * CameraInfo
+ *
+ * @return {@link CameraInfo}
+ */
+ private CameraInfo getCameraInfo() {
+ return mCamera.getCameraInfo();
+ }
@Override
public void release() {
isAnalyze = false;
flashlightView = null;
- if(mAmbientLightManager != null){
+ if (mAmbientLightManager != null) {
mAmbientLightManager.unregister();
}
- if(mBeepManager != null){
+ if (mBeepManager != null) {
mBeepManager.close();
}
stopCamera();
@@ -486,23 +539,23 @@ public class DefaultCameraScan extends CameraScan {
@Override
public CameraScan bindFlashlightView(@Nullable View v) {
flashlightView = v;
- if(mAmbientLightManager != null){
+ if (mAmbientLightManager != null) {
mAmbientLightManager.setLightSensorEnabled(v != null);
}
return this;
}
@Override
- public CameraScan setDarkLightLux(float lightLux){
- if(mAmbientLightManager != null){
+ public CameraScan setDarkLightLux(float lightLux) {
+ if (mAmbientLightManager != null) {
mAmbientLightManager.setDarkLightLux(lightLux);
}
return this;
}
@Override
- public CameraScan setBrightLightLux(float lightLux){
- if(mAmbientLightManager != null){
+ public CameraScan setBrightLightLux(float lightLux) {
+ if (mAmbientLightManager != null) {
mAmbientLightManager.setBrightLightLux(lightLux);
}
return this;
diff --git a/zxing-lite/src/main/java/com/king/zxing/ICamera.java b/zxing-lite/src/main/java/com/king/zxing/ICamera.java
index df4ddf1..b8543c2 100644
--- a/zxing-lite/src/main/java/com/king/zxing/ICamera.java
+++ b/zxing-lite/src/main/java/com/king/zxing/ICamera.java
@@ -1,10 +1,11 @@
package com.king.zxing;
-
import androidx.annotation.Nullable;
import androidx.camera.core.Camera;
/**
+ * 相机定义
+ *
* @author Jenly
*/
public interface ICamera {
@@ -21,9 +22,11 @@ public interface ICamera {
/**
* 获取{@link Camera}
+ *
* @return
*/
- @Nullable Camera getCamera();
+ @Nullable
+ Camera getCamera();
/**
* 释放
diff --git a/zxing-lite/src/main/java/com/king/zxing/ICameraControl.java b/zxing-lite/src/main/java/com/king/zxing/ICameraControl.java
index 5bdbf96..2dfa9c8 100644
--- a/zxing-lite/src/main/java/com/king/zxing/ICameraControl.java
+++ b/zxing-lite/src/main/java/com/king/zxing/ICameraControl.java
@@ -3,6 +3,8 @@ package com.king.zxing;
import androidx.annotation.FloatRange;
/**
+ * 相机控制:主要包括调节焦距和闪光灯控制
+ *
* @author Jenly
*/
public interface ICameraControl {
@@ -19,6 +21,7 @@ public interface ICameraControl {
/**
* 缩放到指定比例
+ *
* @param ratio
*/
void zoomTo(float ratio);
@@ -35,24 +38,28 @@ public interface ICameraControl {
/**
* 线性缩放到指定比例
+ *
* @param linearZoom
*/
- void lineZoomTo(@FloatRange(from = 0.0,to = 1.0) float linearZoom);
+ void lineZoomTo(@FloatRange(from = 0.0, to = 1.0) float linearZoom);
/**
* 设置闪光灯(手电筒)是否开启
+ *
* @param torch
*/
void enableTorch(boolean torch);
/**
* 闪光灯(手电筒)是否开启
+ *
* @return
*/
boolean isTorchEnabled();
/**
* 是否支持闪光灯
+ *
* @return
*/
boolean hasFlashUnit();
diff --git a/zxing-lite/src/main/java/com/king/zxing/ViewfinderView.java b/zxing-lite/src/main/java/com/king/zxing/ViewfinderView.java
index f43fb2e..4e3af5b 100644
--- a/zxing-lite/src/main/java/com/king/zxing/ViewfinderView.java
+++ b/zxing-lite/src/main/java/com/king/zxing/ViewfinderView.java
@@ -1,30 +1,20 @@
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.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
+import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
@@ -32,28 +22,37 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
import android.view.View;
import com.king.zxing.util.LogUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
-import static com.king.zxing.ViewfinderView.FrameGravity.*;
-
/**
- * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
- * transparency outside it, as well as the laser scanner animation and result points.
+ * 取景视图:主要用于渲染扫描效果
*
- * @author dswitkin@google.com (Daniel Switkin)
+ * @author Jenly
*/
public class ViewfinderView extends View {
- private static final int CURRENT_POINT_OPACITY = 0xA0;
- private static final int MAX_RESULT_POINTS = 20;
- private static final int POINT_SIZE = 30;
+ /**
+ * 默认范围比例,之所以默认为 1.2 是因为内切圆半径和外切圆半径之和的二分之一(即:(1 + √2) / 2 ≈ 1.2)
+ */
+ private final float DEFAULT_RANGE_RATIO = 1.2F;
+
+ private final float MAX_ZOOM_RATIO = 1.2F;
/**
* 画笔
@@ -186,25 +185,78 @@ public class ViewfinderView extends View {
*/
private FrameGravity frameGravity;
-
- private Point point;
private int pointColor;
private int pointStrokeColor;
+ private Bitmap pointBitmap;
+ private boolean isShowPointAnim = true;
private float pointRadius;
- private float pointStrokeRatio = 1.2f;
+ private float pointStrokeRatio;
+ private float pointStrokeRadius;
+ /**
+ * 当前缩放比例
+ */
+ private float currentZoomRatio = 1.0f;
+ /**
+ * 最后一次缩放比例(即上一次缩放比例)
+ */
+ private float lastZoomRatio;
+ /**
+ * 缩放速度
+ */
+ private float zoomSpeed = 0.02f;
- public enum LaserStyle{
- NONE(0),LINE(1),GRID(2);
+ private int zoomCount;
+
+ /**
+ * 结果点有效点击范围半径
+ */
+ private float pointRangeRadius;
+
+ private Bitmap laserBitmap;
+
+ private int viewfinderStyle = ViewfinderStyle.CLASSIC;
+
+ private List
+ * 库中内置实现{@link CameraConfig}的有{@link AspectRatioCameraConfig}和{@link ResolutionCameraConfig};
+ *
+ * 这里简单说下各自的特点:
+ *
+ * {@link CameraConfig} - 默认的相机配置
+ *
+ * {@link AspectRatioCameraConfig} - 根据纵横比配置相机,使输出分析的图像尽可能的接近屏幕的比例
+ *
+ * {@link ResolutionCameraConfig} - 根据尺寸配置相机的目标图像大小,使输出分析的图像的分辨率尽可能的接近屏幕尺寸
+ *
+ * 当使用默认的 {@link CameraConfig}在某些机型上体验欠佳时,你可以尝试使用{@link AspectRatioCameraConfig}或
+ * {@link ResolutionCameraConfig}会有意想不到奇效。
+ *
+ * 你也可以自定义或覆写 {@link CameraConfig} 中的 {@link #options} 方法,根据需要定制配置。
+ *
* @author Jenly
*/
public class CameraConfig {
- public CameraConfig(){
+ public CameraConfig() {
}
+ /**
+ * 配置 {@link Preview.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
+ *
+ * 如配置目标旋转角度为90度:{@code builder.setTargetRotation(Surface.ROTATION_90)}
+ *
+ * 切记,外部请勿直接调用 {@link #options(Preview.Builder)}
+ *
+ * @param builder
+ * @return
+ */
@NonNull
- public Preview options(@NonNull Preview.Builder builder){
+ public Preview options(@NonNull Preview.Builder builder) {
return builder.build();
}
+ /**
+ * 配置 {@link CameraSelector.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
+ *
+ * 如配置前置摄像头:{@code builder.requireLensFacing(CameraSelector.LENS_FACING_FRONT)}
+ *
+ * 切记,外部请勿直接调用 {@link #options(CameraSelector.Builder)}
+ *
+ * @param builder
+ * @return
+ */
@NonNull
- public CameraSelector options(@NonNull CameraSelector.Builder builder){
+ public CameraSelector options(@NonNull CameraSelector.Builder builder) {
return builder.build();
}
+ /**
+ * 配置 {@link ImageAnalysis.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
+ *
+ * 如配置目标旋转角度为90度:{@code builder.setTargetRotation(Surface.ROTATION_90)}
+ *
+ * 切记,外部请勿直接调用 {@link #options(ImageAnalysis.Builder)}
+ *
+ * @param builder
+ * @return
+ */
@NonNull
- public ImageAnalysis options(@NonNull ImageAnalysis.Builder builder){
+ public ImageAnalysis options(@NonNull ImageAnalysis.Builder builder) {
return builder.build();
}
}
+
diff --git a/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java b/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java
index b783641..5239679 100644
--- a/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java
+++ b/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java
@@ -4,53 +4,89 @@ import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Size;
-
import com.king.zxing.util.LogUtils;
+import java.util.Locale;
+
import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
/**
- * 相机配置:根据尺寸配置相机的目标图像,使输出分析的图像尽可能的接近屏幕尺寸
+ * 相机配置:根据尺寸配置相机的目标图像大小,使输出分析的图像的分辨率尽可能的接近屏幕尺寸
+ *
* @author Jenly
*/
public class ResolutionCameraConfig extends CameraConfig {
- private Size mTargetSize;
-
- public ResolutionCameraConfig(Context context) {
- super();
+ /**
+ * 1080P
+ */
+ public static final int IMAGE_QUALITY_1080P = 1080;
+ /**
+ * 720P
+ */
+ public static final int IMAGE_QUALITY_720P = 720;
+
+ private Size mTargetSize;
+
+ /**
+ * 构造
+ *
+ * @param context 上下文
+ */
+ public ResolutionCameraConfig(Context context) {
+ this(context, IMAGE_QUALITY_1080P);
+ }
+
+ /**
+ * 构造
+ *
+ * @param context 上下文
+ * @param imageQuality 图像质量;此参数只是期望的图像质量,最终以实际计算结果为准
+ */
+ public ResolutionCameraConfig(Context context, int imageQuality) {
+ super();
+ initTargetResolutionSize(context, imageQuality);
+ }
+
+ /**
+ * 初始化 {@link #mTargetSize}
+ *
+ * @param context 上下文
+ * @param imageQuality 图像质量;此参数只是期望的图像质量,最终以实际计算结果为准
+ */
+ private void initTargetResolutionSize(Context context, int imageQuality) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
- LogUtils.d(String.format("displayMetrics:%d x %d",width,height));
- //因为为了保持流畅性和性能,限制在1080p,在此前提下尽可能的找到屏幕接近的分辨率
- if(width < height){
- int size = Math.min(width, 1080);
- float ratio = width / (float)height;
- if(ratio > 0.7){//一般应用于平板
- mTargetSize = new Size(size, (int)(size / 3.0f * 4.0f));
- }else{
- mTargetSize = new Size(size, (int)(size / 9.0f * 16.0f));
+ LogUtils.d(String.format(Locale.getDefault(), "displayMetrics:%d x %d", width, height));
+ // 因为为了保持流畅性和性能,尽可能的限制在imageQuality(默认:1080p),在此前提下尽可能的找到屏幕接近的分辨率
+ if (width < height) {
+ int size = Math.min(width, imageQuality);
+ float ratio = width / (float) height;
+ if (ratio > 0.7F) {
+ // 一般应用于平板
+ mTargetSize = new Size(size, (int) (size / 3.0F * 4.0F));
+ } else {
+ mTargetSize = new Size(size, (int) (size / 9.0F * 16.0F));
}
- }else{
- int size = Math.min(height, 1080);
- float ratio = height / (float)width;
- if(ratio > 0.7){//一般应用于平板
- mTargetSize = new Size((int)(size / 3.0f * 4.0f), size);
- }else{
- mTargetSize = new Size((int)(size / 9.0f * 16.0), size);
+ } else {
+ int size = Math.min(height, imageQuality);
+ float ratio = height / (float) width;
+ if (ratio > 0.7F) {
+ // 一般应用于平板
+ mTargetSize = new Size((int) (size / 3.0F * 4.0F), size);
+ } else {
+ mTargetSize = new Size((int) (size / 9.0F * 16.0F), size);
}
}
LogUtils.d("targetSize:" + mTargetSize);
}
-
-
@NonNull
@Override
public Preview options(@NonNull Preview.Builder builder) {
diff --git a/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java b/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java
index 919a6e8..8db276c 100644
--- a/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java
+++ b/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java
@@ -1,22 +1,5 @@
package com.king.zxing.manager;
-/*
- * Copyright (C) 2012 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.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
@@ -30,8 +13,8 @@ public class AmbientLightManager implements SensorEventListener {
private static final int INTERVAL_TIME = 200;
- protected static final float DARK_LUX = 45.0f;
- protected static final float BRIGHT_LUX = 100.0f;
+ protected static final float DARK_LUX = 45.0F;
+ protected static final float BRIGHT_LUX = 100.0F;
/**
* 光线太暗时,默认:照度45 lux
@@ -72,9 +55,10 @@ public class AmbientLightManager implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
- if(isLightSensorEnabled){
+ if (isLightSensorEnabled) {
long currentTime = System.currentTimeMillis();
- if(currentTime - lastTime < INTERVAL_TIME){//降低频率
+ if (currentTime - lastTime < INTERVAL_TIME) {
+ // 降低频率
return;
}
lastTime = currentTime;
@@ -83,9 +67,9 @@ public class AmbientLightManager implements SensorEventListener {
float lightLux = sensorEvent.values[0];
mOnLightSensorEventListener.onSensorChanged(lightLux);
if (lightLux <= darkLightLux) {
- mOnLightSensorEventListener.onSensorChanged(true,lightLux);
+ mOnLightSensorEventListener.onSensorChanged(true, lightLux);
} else if (lightLux >= brightLightLux) {
- mOnLightSensorEventListener.onSensorChanged(false,lightLux);
+ mOnLightSensorEventListener.onSensorChanged(false, lightLux);
}
}
}
@@ -93,17 +77,19 @@ public class AmbientLightManager implements SensorEventListener {
/**
* 设置光线足够暗的阈值(单位:lux)
+ *
* @param lightLux
*/
- public void setDarkLightLux(float lightLux){
+ public void setDarkLightLux(float lightLux) {
this.darkLightLux = lightLux;
}
/**
* 设置光线足够明亮的阈值(单位:lux)
+ *
* @param lightLux
*/
- public void setBrightLightLux(float lightLux){
+ public void setBrightLightLux(float lightLux) {
this.brightLightLux = lightLux;
}
@@ -118,6 +104,7 @@ public class AmbientLightManager implements SensorEventListener {
/**
* 设置是否启用光线亮度传感器
+ *
* @param lightSensorEnabled
*/
public void setLightSensorEnabled(boolean lightSensorEnabled) {
@@ -126,26 +113,27 @@ public class AmbientLightManager implements SensorEventListener {
/**
* 设置光线亮度传感器监听器,只有在 {@link #isLightSensorEnabled} 为{@code true} 才有效
+ *
* @param listener
*/
- public void setOnLightSensorEventListener(OnLightSensorEventListener listener){
+ public void setOnLightSensorEventListener(OnLightSensorEventListener listener) {
mOnLightSensorEventListener = listener;
}
- public interface OnLightSensorEventListener{
+ public interface OnLightSensorEventListener {
/**
- *
* @param lightLux 当前检测到的光线照度值
*/
- default void onSensorChanged(float lightLux){
+ default void onSensorChanged(float lightLux) {
}
/**
* 传感器改变事件
- * @param dark 是否太暗了,当检测到的光线照度值小于{@link #darkLightLux}时,为{@code true}
+ *
+ * @param dark 是否太暗了,当检测到的光线照度值小于{@link #darkLightLux}时,为{@code true}
* @param lightLux 当前检测到的光线照度值
*/
- void onSensorChanged(boolean dark,float lightLux);
+ void onSensorChanged(boolean dark, float lightLux);
}
-}
+}
\ No newline at end of file
diff --git a/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java b/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java
index dc2b892..b9dd88c 100644
--- a/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java
+++ b/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java
@@ -1,24 +1,7 @@
package com.king.zxing.manager;
-/*
- * Copyright (C) 2010 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.Context;
import android.content.res.AssetFileDescriptor;
-import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.VibrationEffect;
@@ -28,7 +11,6 @@ import com.king.zxing.R;
import com.king.zxing.util.LogUtils;
import java.io.Closeable;
-import java.lang.annotation.ElementType;
/**
* @author Jenly
@@ -49,11 +31,11 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
updatePrefs();
}
- public void setVibrate(boolean vibrate){
+ public void setVibrate(boolean vibrate) {
this.vibrate = vibrate;
}
- public void setPlayBeep(boolean playBeep){
+ public void setPlayBeep(boolean playBeep) {
this.playBeep = playBeep;
}
@@ -61,8 +43,8 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
if (mediaPlayer == null) {
mediaPlayer = buildMediaPlayer(context);
}
- if(vibrator == null){
- vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
+ if (vibrator == null) {
+ vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
}
}
@@ -85,7 +67,6 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
AssetFileDescriptor file = context.getResources().openRawResourceFd(R.raw.zxl_beep);
mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
mediaPlayer.setOnErrorListener(this);
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.prepare();
return mediaPlayer;
@@ -105,12 +86,12 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
@Override
public synchronized void close() {
- try{
+ try {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
- }catch (Exception e){
+ } catch (Exception e) {
LogUtils.e(e);
}
}
diff --git a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
index 513b21a..7d9be52 100644
--- a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
+++ b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
@@ -48,8 +48,9 @@ import com.king.zxing.DecodeFormatManager;
import java.util.HashMap;
import java.util.Map;
-
/**
+ * 二维码/条形码工具类:主要包括二维码/条形码的解析与生成
+ *
* @author Jenly Jenly
*/
public final class CodeUtils {
@@ -57,108 +58,115 @@ public final class CodeUtils {
public static final int DEFAULT_REQ_WIDTH = 480;
public static final int DEFAULT_REQ_HEIGHT = 640;
- private CodeUtils(){
+ private CodeUtils() {
throw new AssertionError();
}
/**
* 生成二维码
- * @param content 二维码的内容
+ *
+ * @param content 二维码的内容
* @param heightPix 二维码的高
* @return
*/
public static Bitmap createQRCode(String content, int heightPix) {
- return createQRCode(content,heightPix,null);
+ return createQRCode(content, heightPix, null);
}
/**
* 生成二维码
- * @param content 二维码的内容
+ *
+ * @param content 二维码的内容
* @param heightPix 二维码的高
* @param codeColor 二维码的颜色
* @return
*/
- public static Bitmap createQRCode(String content, int heightPix,int codeColor) {
- return createQRCode(content,heightPix,null,codeColor);
+ public static Bitmap createQRCode(String content, int heightPix, int codeColor) {
+ return createQRCode(content, heightPix, null, codeColor);
}
/**
* 生成我二维码
- * @param content 二维码的内容
+ *
+ * @param content 二维码的内容
* @param heightPix 二维码的高
- * @param logo logo大小默认占二维码的20%
+ * @param logo logo大小默认占二维码的20%
* @return
*/
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo) {
- return createQRCode(content,heightPix,logo,Color.BLACK);
+ return createQRCode(content, heightPix, logo, Color.BLACK);
}
/**
* 生成我二维码
- * @param content 二维码的内容
+ *
+ * @param content 二维码的内容
* @param heightPix 二维码的高
- * @param logo logo大小默认占二维码的20%
+ * @param logo logo大小默认占二维码的20%
* @param codeColor 二维码的颜色
* @return
*/
- public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,int codeColor) {
- return createQRCode(content,heightPix,logo,0.2f,codeColor);
+ public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, int codeColor) {
+ return createQRCode(content, heightPix, logo, 0.2f, codeColor);
}
/**
* 生成二维码
- * @param content 二维码的内容
+ *
+ * @param content 二维码的内容
* @param heightPix 二维码的高
- * @param logo 二维码中间的logo
- * @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
+ * @param logo 二维码中间的logo
+ * @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
* @return
*/
- public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f)float ratio) {
+ public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio) {
//配置参数
Map