39
README.md
39
README.md
@@ -14,6 +14,7 @@
|
|||||||
ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成二维码/条形码功能,扫码界面完全支持自定义,也可一行代码使用默认实现的扫码功能。总之你想要的都在这里。
|
ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成二维码/条形码功能,扫码界面完全支持自定义,也可一行代码使用默认实现的扫码功能。总之你想要的都在这里。
|
||||||
>简单如斯,你不试试? Come on~
|
>简单如斯,你不试试? Come on~
|
||||||
|
|
||||||
|
|
||||||
### [AndroidX version](https://github.com/jenly1314/ZXingLite/tree/androidx)
|
### [AndroidX version](https://github.com/jenly1314/ZXingLite/tree/androidx)
|
||||||
|
|
||||||
## Gif 展示
|
## Gif 展示
|
||||||
@@ -55,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.3</version>
|
<version>1.1.4</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
### Gradle:
|
### Gradle:
|
||||||
```gradle
|
```gradle
|
||||||
//AndroidX 版本
|
//AndroidX 版本
|
||||||
implementation 'com.king.zxing:zxing-lite:1.1.3-androidx'
|
implementation 'com.king.zxing:zxing-lite:1.1.4-androidx'
|
||||||
|
|
||||||
//Android 版本
|
//Android 版本
|
||||||
implementation 'com.king.zxing:zxing-lite:1.1.3'
|
implementation 'com.king.zxing:zxing-lite:1.1.4'
|
||||||
```
|
```
|
||||||
### Lvy:
|
### Lvy:
|
||||||
```lvy
|
```lvy
|
||||||
<dependency org='com.king.zxing' name='zxing-lite' rev='1.1.3'>
|
<dependency org='com.king.zxing' name='zxing-lite' rev='1.1.4'>
|
||||||
<artifact name='$AID' ext='pom'></artifact>
|
<artifact name='$AID' ext='pom'></artifact>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
@@ -86,17 +87,20 @@ allprojects {
|
|||||||
## 引入的库:
|
## 引入的库:
|
||||||
```gradle
|
```gradle
|
||||||
//AndroidX
|
//AndroidX
|
||||||
compileOnly 'androidx.appcompat:appcompat:1.0.0+'
|
api 'androidx.appcompat:appcompat:1.0.0+'
|
||||||
api 'com.google.zxing:core:3.3.3'
|
api 'com.google.zxing:core:3.3.3'
|
||||||
|
|
||||||
//Android
|
//Android
|
||||||
compileOnly 'com.android.support:appcompat-v7:28.0.0'
|
api 'com.android.support:appcompat-v7:28.0.0'
|
||||||
api 'com.google.zxing:core:3.3.3'
|
api 'com.google.zxing:core:3.3.3'
|
||||||
```
|
```
|
||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
布局示例 (可自定义布局,布局内至少要保证有SurfaceView和ViewfinderView,控件id可根据重写CaptureActivity 的 getPreviewViewId 和 getViewFinderViewId方法自定义)
|
布局示例
|
||||||
|
> 可自定义布局,布局内至少要保证有SurfaceView和ViewfinderView,控件id可根据重写CaptureActivity 的 getSurfaceViewId 和 getViewfinderViewId方法自定义
|
||||||
|
> ivTorch为 v1.1.4版本新增的手电筒按钮,如果想改ID可通过CaptureActivity中的getIvTorchId自定义ID
|
||||||
|
|
||||||
```Xml
|
```Xml
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -110,10 +114,22 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
android:id="@+id/viewfinderView"
|
android:id="@+id/viewfinderView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivTorch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/zxl_torch_selector"
|
||||||
|
android:layout_marginTop="@dimen/torchMarginTop" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
或在你的布局中添加
|
||||||
|
|
||||||
|
```Xml
|
||||||
|
<include layout="@layout/zxl_capture"/>
|
||||||
|
```
|
||||||
|
|
||||||
代码示例 (二维码/条形码)
|
代码示例 (二维码/条形码)
|
||||||
```Java
|
```Java
|
||||||
//跳转的默认扫码界面
|
//跳转的默认扫码界面
|
||||||
@@ -129,7 +145,8 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
```Xml
|
```Xml
|
||||||
<activity
|
<activity
|
||||||
android:name="com.king.zxing.CaptureActivity"
|
android:name="com.king.zxing.CaptureActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 快速实现扫码有以下几种方式:
|
### 快速实现扫码有以下几种方式:
|
||||||
@@ -147,6 +164,10 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
|
|
||||||
## 版本记录
|
## 版本记录
|
||||||
|
|
||||||
|
#### v1.1.4:2019-11-15
|
||||||
|
* 内置手电筒按钮,当光线太暗时,自动显示手电筒 fix(#58)
|
||||||
|
* 生成二维码时Logo支持自定义大小 fix(#62)
|
||||||
|
|
||||||
#### v1.1.3:2019-9-24
|
#### v1.1.3:2019-9-24
|
||||||
* 支持真实识别区域比例和识别区域偏移量可配置
|
* 支持真实识别区域比例和识别区域偏移量可配置
|
||||||
* 对外暴露更多可配置参数
|
* 对外暴露更多可配置参数
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":13,"versionName":"1.1.3","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
[{"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":{}}]
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".MainActivity"
|
<activity android:name=".MainActivity"
|
||||||
android:screenOrientation="portrait">
|
android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
@@ -23,21 +23,26 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.king.zxing.CaptureActivity"
|
android:name="com.king.zxing.CaptureActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".EasyCaptureActivity"
|
android:name=".EasyCaptureActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".CustomCaptureActivity"/>
|
android:name=".CustomCaptureActivity"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".CaptureFragmentActivity"
|
android:name=".CaptureFragmentActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".CustomActivity"
|
android:name=".CustomActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/CaptureTheme"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".CodeActivity"
|
android:name=".CodeActivity"
|
||||||
|
|||||||
@@ -56,11 +56,16 @@ public class CodeActivity extends AppCompatActivity {
|
|||||||
* @param content
|
* @param content
|
||||||
*/
|
*/
|
||||||
private void createQRCode(String content){
|
private void createQRCode(String content){
|
||||||
//生成二维码最好放子线程生成防止阻塞UI,这里只是演示
|
new Thread(() -> {
|
||||||
Bitmap logo = BitmapFactory.decodeResource(getResources(),R.drawable.logo);
|
//生成二维码相关放在子线程里面
|
||||||
Bitmap bitmap = CodeUtils.createQRCode(content,600,logo);
|
Bitmap logo = BitmapFactory.decodeResource(getResources(),R.drawable.logo);
|
||||||
//显示二维码
|
Bitmap bitmap = CodeUtils.createQRCode(content,600,logo);
|
||||||
ivCode.setImageBitmap(bitmap);
|
runOnUiThread(()->{
|
||||||
|
//显示二维码
|
||||||
|
ivCode.setImageBitmap(bitmap);
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,13 +73,18 @@ public class CodeActivity extends AppCompatActivity {
|
|||||||
* @param content
|
* @param content
|
||||||
*/
|
*/
|
||||||
private void createBarCode(String content){
|
private void createBarCode(String content){
|
||||||
//生成条形码最好放子线程生成防止阻塞UI,这里只是演示
|
new Thread(() -> {
|
||||||
Bitmap bitmap = CodeUtils.createBarCode(content, BarcodeFormat.CODE_128,800,200,null,true);
|
//生成条形码相关放在子线程里面
|
||||||
//显示条形码
|
Bitmap bitmap = CodeUtils.createBarCode(content, BarcodeFormat.CODE_128,800,200,null,true);
|
||||||
ivCode.setImageBitmap(bitmap);
|
runOnUiThread(()->{
|
||||||
|
//显示条形码
|
||||||
|
ivCode.setImageBitmap(bitmap);
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void onClick(View v){
|
public void onClick(View v){
|
||||||
switch (v.getId()){
|
switch (v.getId()){
|
||||||
case R.id.ivLeft:
|
case R.id.ivLeft:
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
|
|||||||
|
|
||||||
private ViewfinderView viewfinderView;
|
private ViewfinderView viewfinderView;
|
||||||
|
|
||||||
|
private View ivTorch;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
@@ -51,10 +53,12 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
|
|||||||
|
|
||||||
surfaceView = findViewById(R.id.surfaceView);
|
surfaceView = findViewById(R.id.surfaceView);
|
||||||
viewfinderView = findViewById(R.id.viewfinderView);
|
viewfinderView = findViewById(R.id.viewfinderView);
|
||||||
|
ivTorch = findViewById(R.id.ivFlash);
|
||||||
|
ivTorch.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
|
isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
|
||||||
|
|
||||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
|
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView,ivTorch);
|
||||||
mCaptureHelper.setOnCaptureCallback(this);
|
mCaptureHelper.setOnCaptureCallback(this);
|
||||||
mCaptureHelper.onCreate();
|
mCaptureHelper.onCreate();
|
||||||
mCaptureHelper.vibrate(true)
|
mCaptureHelper.vibrate(true)
|
||||||
@@ -88,26 +92,6 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
|
|||||||
return super.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码结果回调
|
* 扫码结果回调
|
||||||
@@ -123,25 +107,12 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void clickFlash(View v){
|
|
||||||
if(v.isSelected()){
|
|
||||||
offFlash();
|
|
||||||
v.setSelected(false);
|
|
||||||
}else{
|
|
||||||
openFlash();
|
|
||||||
v.setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View v){
|
public void onClick(View v){
|
||||||
switch (v.getId()){
|
switch (v.getId()){
|
||||||
case R.id.ivLeft:
|
case R.id.ivLeft:
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
break;
|
break;
|
||||||
case R.id.ivFlash:
|
|
||||||
clickFlash(v);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ 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.CameraConfigurationUtils;
|
||||||
|
import com.king.zxing.camera.FrontLightMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义继承CaptureActivity
|
* 自定义继承CaptureActivity
|
||||||
@@ -34,8 +35,6 @@ import com.king.zxing.camera.CameraConfigurationUtils;
|
|||||||
*/
|
*/
|
||||||
public class CustomCaptureActivity extends CaptureActivity {
|
public class CustomCaptureActivity extends CaptureActivity {
|
||||||
|
|
||||||
private ImageView ivFlash;
|
|
||||||
|
|
||||||
private boolean isContinuousScan;
|
private boolean isContinuousScan;
|
||||||
@Override
|
@Override
|
||||||
public int getLayoutId() {
|
public int getLayoutId() {
|
||||||
@@ -51,12 +50,6 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
TextView tvTitle = findViewById(R.id.tvTitle);
|
TextView tvTitle = findViewById(R.id.tvTitle);
|
||||||
tvTitle.setText(getIntent().getStringExtra(MainActivity.KEY_TITLE));
|
tvTitle.setText(getIntent().getStringExtra(MainActivity.KEY_TITLE));
|
||||||
|
|
||||||
ivFlash = findViewById(R.id.ivFlash);
|
|
||||||
|
|
||||||
if(!hasTorch()){
|
|
||||||
ivFlash.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
|
isContinuousScan = getIntent().getBooleanExtra(MainActivity.KEY_IS_CONTINUOUS,false);
|
||||||
//获取CaptureHelper,里面有扫码相关的配置设置
|
//获取CaptureHelper,里面有扫码相关的配置设置
|
||||||
getCaptureHelper().playBeep(false)//播放音效
|
getCaptureHelper().playBeep(false)//播放音效
|
||||||
@@ -66,28 +59,12 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
// .framingRectRatio(0.9f)//设置识别区域比例,范围建议在0.625 ~ 1.0之间。非全屏识别时才有效
|
// .framingRectRatio(0.9f)//设置识别区域比例,范围建议在0.625 ~ 1.0之间。非全屏识别时才有效
|
||||||
// .framingRectVerticalOffset(0)//设置识别区域垂直方向偏移量,非全屏识别时才有效
|
// .framingRectVerticalOffset(0)//设置识别区域垂直方向偏移量,非全屏识别时才有效
|
||||||
// .framingRectHorizontalOffset(0)//设置识别区域水平方向偏移量,非全屏识别时才有效
|
// .framingRectHorizontalOffset(0)//设置识别区域水平方向偏移量,非全屏识别时才有效
|
||||||
|
.frontLightMode(FrontLightMode.AUTO)//设置闪光灯模式
|
||||||
|
.tooDarkLux(45f)//设置光线太暗时,自动触发开启闪光灯的照度值
|
||||||
|
.brightEnoughLux(450f)//设置光线足够明亮时,自动触发关闭闪光灯的照度值
|
||||||
.continuousScan(isContinuousScan);//是否连扫
|
.continuousScan(isContinuousScan);//是否连扫
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 开启或关闭闪光灯(手电筒)
|
|
||||||
* @param on {@code true}表示开启,{@code false}表示关闭
|
|
||||||
*/
|
|
||||||
public void setTorch(boolean on){
|
|
||||||
Camera camera = getCameraManager().getOpenCamera().getCamera();
|
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
|
||||||
CameraConfigurationUtils.setTorch(parameters,on);
|
|
||||||
camera.setParameters(parameters);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测是否支持闪光灯(手电筒)
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean hasTorch(){
|
|
||||||
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码结果回调
|
* 扫码结果回调
|
||||||
@@ -103,21 +80,11 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
return super.onResultCallback(result);
|
return super.onResultCallback(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void clickFlash(View v){
|
|
||||||
boolean isSelected = v.isSelected();
|
|
||||||
setTorch(!isSelected);
|
|
||||||
v.setSelected(!isSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View v){
|
public void onClick(View v){
|
||||||
switch (v.getId()){
|
switch (v.getId()){
|
||||||
case R.id.ivLeft:
|
case R.id.ivLeft:
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
break;
|
break;
|
||||||
case R.id.ivFlash:
|
|
||||||
clickFlash(v);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void parsePhoto(Intent data){
|
private void parsePhoto(Intent data){
|
||||||
final String path = UriUtils.INSTANCE.getImagePath(this,data);
|
final String path = UriUtils.getImagePath(this,data);
|
||||||
Log.d("Jenly","path:" + path);
|
Log.d("Jenly","path:" + path);
|
||||||
if(TextUtils.isEmpty(path)){
|
if(TextUtils.isEmpty(path)){
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -32,9 +32,13 @@ import com.king.zxing.app.R;
|
|||||||
/**
|
/**
|
||||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||||
*/
|
*/
|
||||||
public class StatusBarUtils {
|
public final class StatusBarUtils {
|
||||||
|
|
||||||
public static void immersiveStatusBar(Activity activity,Toolbar toolbar) {
|
private StatusBarUtils(){
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void immersiveStatusBar(Activity activity, Toolbar toolbar) {
|
||||||
immersiveStatusBar(activity,toolbar,0.0f);
|
immersiveStatusBar(activity,toolbar,0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +82,7 @@ public class StatusBarUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 获取状态栏高度 */
|
/** 获取状态栏高度 */
|
||||||
private static int getStatusBarHeight(Context context) {
|
public static int getStatusBarHeight(Context context) {
|
||||||
return context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
|
return context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.king.zxing.app.util;
|
package com.king.zxing.app.util;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -14,13 +13,16 @@ import android.util.Log;
|
|||||||
/**
|
/**
|
||||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||||
*/
|
*/
|
||||||
public enum UriUtils {
|
public final class UriUtils {
|
||||||
INSTANCE;
|
|
||||||
|
private UriUtils(){
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取图片
|
* 获取图片
|
||||||
*/
|
*/
|
||||||
public String getImagePath(Context context,Intent data) {
|
public static String getImagePath(Context context,Intent data) {
|
||||||
String imagePath = null;
|
String imagePath = null;
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
//获取系統版本
|
//获取系統版本
|
||||||
@@ -54,7 +56,7 @@ public enum UriUtils {
|
|||||||
/**
|
/**
|
||||||
* 通过uri和selection来获取真实的图片路径,从相册获取图片时要用
|
* 通过uri和selection来获取真实的图片路径,从相册获取图片时要用
|
||||||
*/
|
*/
|
||||||
private String getImagePath(Context context,Uri uri, String selection) {
|
private static String getImagePath(Context context,Uri uri, String selection) {
|
||||||
String path = null;
|
String path = null;
|
||||||
Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
|
Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 809 B After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 1.5 KiB |
@@ -31,7 +31,6 @@
|
|||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_marginTop="160dp"
|
android:layout_marginTop="160dp" />
|
||||||
style="@style/OnClick"/>
|
|
||||||
<include layout="@layout/toolbar_capture"/>
|
<include layout="@layout/toolbar_capture"/>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
app:labelTextLocation="bottom"
|
app:labelTextLocation="bottom"
|
||||||
app:laserStyle="grid"/>
|
app:laserStyle="grid"/>
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivFlash"
|
android:id="@+id/ivTorch"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:src="@drawable/flash_selected_selector"
|
android:src="@drawable/flash_selected_selector"
|
||||||
@@ -30,7 +30,6 @@
|
|||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_marginTop="160dp"
|
android:layout_marginTop="160dp" />
|
||||||
style="@style/OnClick"/>
|
|
||||||
<include layout="@layout/toolbar_capture"/>
|
<include layout="@layout/toolbar_capture"/>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
@@ -42,6 +42,6 @@ dependencies {
|
|||||||
androidTestImplementation deps.test.runner
|
androidTestImplementation deps.test.runner
|
||||||
androidTestImplementation deps.test.espresso
|
androidTestImplementation deps.test.espresso
|
||||||
|
|
||||||
compileOnly deps.support.appcompat
|
api deps.support.appcompat
|
||||||
api deps.zxing
|
api deps.zxing
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,17 @@ import com.king.zxing.camera.FrontLightMode;
|
|||||||
*/
|
*/
|
||||||
final class AmbientLightManager implements SensorEventListener {
|
final class AmbientLightManager implements SensorEventListener {
|
||||||
|
|
||||||
private static final float TOO_DARK_LUX = 45.0f;
|
protected static final float TOO_DARK_LUX = 45.0f;
|
||||||
private static final float BRIGHT_ENOUGH_LUX = 450.0f;
|
protected static final float BRIGHT_ENOUGH_LUX = 100.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 光线太暗时,默认:照度45 lux
|
||||||
|
*/
|
||||||
|
private float tooDarkLux = TOO_DARK_LUX;
|
||||||
|
/**
|
||||||
|
* 光线足够亮时,默认:照度450 lux
|
||||||
|
*/
|
||||||
|
private float brightEnoughLux = BRIGHT_ENOUGH_LUX;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private CameraManager cameraManager;
|
private CameraManager cameraManager;
|
||||||
@@ -72,14 +81,22 @@ final class AmbientLightManager implements SensorEventListener {
|
|||||||
public void onSensorChanged(SensorEvent sensorEvent) {
|
public void onSensorChanged(SensorEvent sensorEvent) {
|
||||||
float ambientLightLux = sensorEvent.values[0];
|
float ambientLightLux = sensorEvent.values[0];
|
||||||
if (cameraManager != null) {
|
if (cameraManager != null) {
|
||||||
if (ambientLightLux <= TOO_DARK_LUX) {
|
if (ambientLightLux <= tooDarkLux) {
|
||||||
cameraManager.setTorch(true);
|
cameraManager.sensorChanged(true,ambientLightLux);
|
||||||
} else if (ambientLightLux >= BRIGHT_ENOUGH_LUX) {
|
} else if (ambientLightLux >= brightEnoughLux) {
|
||||||
cameraManager.setTorch(false);
|
cameraManager.sensorChanged(false,ambientLightLux);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTooDarkLux(float tooDarkLux){
|
||||||
|
this.tooDarkLux = tooDarkLux;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrightEnoughLux(float brightEnoughLux){
|
||||||
|
this.brightEnoughLux = brightEnoughLux;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.support.annotation.LayoutRes;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.king.zxing.camera.CameraManager;
|
import com.king.zxing.camera.CameraManager;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
|||||||
|
|
||||||
private SurfaceView surfaceView;
|
private SurfaceView surfaceView;
|
||||||
private ViewfinderView viewfinderView;
|
private ViewfinderView viewfinderView;
|
||||||
|
private View ivTorch;
|
||||||
|
|
||||||
private CaptureHelper mCaptureHelper;
|
private CaptureHelper mCaptureHelper;
|
||||||
|
|
||||||
@@ -50,7 +52,12 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
|||||||
public void initUI(){
|
public void initUI(){
|
||||||
surfaceView = findViewById(getSurfaceViewId());
|
surfaceView = findViewById(getSurfaceViewId());
|
||||||
viewfinderView = findViewById(getViewfinderViewId());
|
viewfinderView = findViewById(getViewfinderViewId());
|
||||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
|
int ivTorchId = getIvTorchId();
|
||||||
|
if(ivTorchId != 0){
|
||||||
|
ivTorch = findViewById(ivTorchId);
|
||||||
|
ivTorch.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView,ivTorch);
|
||||||
mCaptureHelper.setOnCaptureCallback(this);
|
mCaptureHelper.setOnCaptureCallback(this);
|
||||||
mCaptureHelper.onCreate();
|
mCaptureHelper.onCreate();
|
||||||
}
|
}
|
||||||
@@ -73,7 +80,7 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ViewfinderView} 的 id
|
* {@link #viewfinderView} 的 ID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getViewfinderViewId(){
|
public int getViewfinderViewId(){
|
||||||
@@ -82,13 +89,21 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览界面{@link #surfaceView} 的id
|
* 预览界面{@link #surfaceView} 的ID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getSurfaceViewId(){
|
public int getSurfaceViewId(){
|
||||||
return R.id.surfaceView;
|
return R.id.surfaceView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 {@link #ivTorch} 的ID
|
||||||
|
* @return 默认返回{@code R.id.ivTorch}, 如果不需要手电筒按钮可以返回0
|
||||||
|
*/
|
||||||
|
public int getIvTorchId(){
|
||||||
|
return R.id.ivTorch;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get {@link CaptureHelper}
|
* Get {@link CaptureHelper}
|
||||||
* @return {@link #mCaptureHelper}
|
* @return {@link #mCaptureHelper}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
|||||||
|
|
||||||
private SurfaceView surfaceView;
|
private SurfaceView surfaceView;
|
||||||
private ViewfinderView viewfinderView;
|
private ViewfinderView viewfinderView;
|
||||||
|
private View ivTorch;
|
||||||
|
|
||||||
private CaptureHelper mCaptureHelper;
|
private CaptureHelper mCaptureHelper;
|
||||||
|
|
||||||
@@ -66,7 +67,12 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
|||||||
public void initUI(){
|
public void initUI(){
|
||||||
surfaceView = mRootView.findViewById(getSurfaceViewId());
|
surfaceView = mRootView.findViewById(getSurfaceViewId());
|
||||||
viewfinderView = mRootView.findViewById(getViewfinderViewId());
|
viewfinderView = mRootView.findViewById(getViewfinderViewId());
|
||||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
|
int ivTorchId = getIvTorchId();
|
||||||
|
if(ivTorchId != 0){
|
||||||
|
ivTorch = mRootView.findViewById(ivTorchId);
|
||||||
|
ivTorch.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView,ivTorch);
|
||||||
mCaptureHelper.setOnCaptureCallback(this);
|
mCaptureHelper.setOnCaptureCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +101,6 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
|||||||
return R.id.viewfinderView;
|
return R.id.viewfinderView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览界面{@link #surfaceView} 的id
|
* 预览界面{@link #surfaceView} 的id
|
||||||
* @return
|
* @return
|
||||||
@@ -104,6 +109,14 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
|||||||
return R.id.surfaceView;
|
return R.id.surfaceView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 {@link #ivTorch} 的ID
|
||||||
|
* @return 默认返回{@code R.id.ivTorch}, 如果不需要手电筒按钮可以返回0
|
||||||
|
*/
|
||||||
|
public int getIvTorchId(){
|
||||||
|
return R.id.ivTorch;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get {@link CaptureHelper}
|
* Get {@link CaptureHelper}
|
||||||
* @return {@link #mCaptureHelper}
|
* @return {@link #mCaptureHelper}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package com.king.zxing;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
@@ -26,11 +27,13 @@ import android.util.Log;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.DecodeHintType;
|
import com.google.zxing.DecodeHintType;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
import com.king.zxing.camera.CameraManager;
|
import com.king.zxing.camera.CameraManager;
|
||||||
|
import com.king.zxing.camera.FrontLightMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -61,6 +64,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
private ViewfinderView viewfinderView;
|
private ViewfinderView viewfinderView;
|
||||||
private SurfaceHolder surfaceHolder;
|
private SurfaceHolder surfaceHolder;
|
||||||
private SurfaceHolder.Callback callback;
|
private SurfaceHolder.Callback callback;
|
||||||
|
private View ivTorch;
|
||||||
|
|
||||||
private Collection<BarcodeFormat> decodeFormats;
|
private Collection<BarcodeFormat> decodeFormats;
|
||||||
private Map<DecodeHintType,Object> decodeHints;
|
private Map<DecodeHintType,Object> decodeHints;
|
||||||
@@ -126,21 +130,58 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
* 识别区域水平方向偏移量
|
* 识别区域水平方向偏移量
|
||||||
*/
|
*/
|
||||||
private int framingRectHorizontalOffset;
|
private int framingRectHorizontalOffset;
|
||||||
|
/**
|
||||||
|
* 光线太暗,当光线亮度太暗,亮度低于此值时,显示手电筒按钮
|
||||||
|
*/
|
||||||
|
private float tooDarkLux = AmbientLightManager.TOO_DARK_LUX;
|
||||||
|
/**
|
||||||
|
* 光线足够明亮,当光线亮度足够明亮,亮度高于此值时,隐藏手电筒按钮
|
||||||
|
*/
|
||||||
|
private float brightEnoughLux = AmbientLightManager.BRIGHT_ENOUGH_LUX;
|
||||||
|
/**
|
||||||
|
* 扫码回调
|
||||||
|
*/
|
||||||
private OnCaptureCallback onCaptureCallback;
|
private OnCaptureCallback onCaptureCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
|
||||||
|
* @param fragment
|
||||||
|
* @param surfaceView
|
||||||
|
* @param viewfinderView
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView){
|
public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView){
|
||||||
this(fragment.getActivity(),surfaceView,viewfinderView);
|
this(fragment,surfaceView,viewfinderView,null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView,View ivTorch){
|
||||||
|
this(fragment.getActivity(),surfaceView,viewfinderView,ivTorch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use {@link #CaptureHelper(Activity, SurfaceView, ViewfinderView, View)}
|
||||||
|
* @param activity
|
||||||
|
* @param surfaceView
|
||||||
|
* @param viewfinderView
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView){
|
public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView){
|
||||||
|
this(activity,surfaceView,viewfinderView,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param activity
|
||||||
|
* @param surfaceView
|
||||||
|
* @param viewfinderView
|
||||||
|
* @param ivTorch
|
||||||
|
*/
|
||||||
|
public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView,View ivTorch){
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
this.viewfinderView = viewfinderView;
|
this.viewfinderView = viewfinderView;
|
||||||
|
this.ivTorch = ivTorch;
|
||||||
surfaceHolder = surfaceView.getHolder();
|
surfaceHolder = surfaceView.getHolder();
|
||||||
hasSurface = false;
|
hasSurface = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,6 +196,22 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
cameraManager.setFramingRectRatio(framingRectRatio);
|
cameraManager.setFramingRectRatio(framingRectRatio);
|
||||||
cameraManager.setFramingRectVerticalOffset(framingRectVerticalOffset);
|
cameraManager.setFramingRectVerticalOffset(framingRectVerticalOffset);
|
||||||
cameraManager.setFramingRectHorizontalOffset(framingRectHorizontalOffset);
|
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() {
|
callback = new SurfaceHolder.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
@@ -186,6 +243,11 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
//设置是否播放音效和震动
|
//设置是否播放音效和震动
|
||||||
beepManager.setPlayBeep(isPlayBeep);
|
beepManager.setPlayBeep(isPlayBeep);
|
||||||
beepManager.setVibrate(isVibrate);
|
beepManager.setVibrate(isVibrate);
|
||||||
|
|
||||||
|
//设置闪光灯的太暗时和足够亮时的照度值
|
||||||
|
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||||
|
ambientLightManager.setBrightEnoughLux(brightEnoughLux);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -565,6 +627,49 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置闪光灯模式。当设置模式为:{@link FrontLightMode#AUTO}时,如果满意默认的照度值范围,
|
||||||
|
* 可通过{@link #tooDarkLux(float)}和{@link #brightEnoughLux(float)}来自定义照度范围,
|
||||||
|
* 控制自动触发开启和关闭闪光灯。
|
||||||
|
* 当设置模式非{@link FrontLightMode#AUTO}时,传感器不会检测,则不使用手电筒
|
||||||
|
*
|
||||||
|
* @param mode 默认:{@link FrontLightMode#AUTO}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CaptureHelper frontLightMode(FrontLightMode mode) {
|
||||||
|
FrontLightMode.put(activity,mode);
|
||||||
|
if(ivTorch!=null && mode != FrontLightMode.AUTO){
|
||||||
|
ivTorch.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置光线太暗时,自动显示手电筒按钮
|
||||||
|
* @param tooDarkLux 默认:{@link AmbientLightManager#TOO_DARK_LUX}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CaptureHelper tooDarkLux(float tooDarkLux) {
|
||||||
|
this.tooDarkLux = tooDarkLux;
|
||||||
|
if(ambientLightManager != null){
|
||||||
|
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置光线足够明亮时,自动隐藏手电筒按钮
|
||||||
|
* @param brightEnoughLux 默认:{@link AmbientLightManager#BRIGHT_ENOUGH_LUX}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CaptureHelper brightEnoughLux(float brightEnoughLux) {
|
||||||
|
this.brightEnoughLux = brightEnoughLux;
|
||||||
|
if(ambientLightManager != null){
|
||||||
|
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置返回扫码原图
|
* 设置返回扫码原图
|
||||||
* @param returnBitmap 默认为false,当返回true表示扫码就结果会返回扫码原图,相应的会增加性能消耗。
|
* @param returnBitmap 默认为false,当返回true表示扫码就结果会返回扫码原图,相应的会增加性能消耗。
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ public final class CameraManager {
|
|||||||
*/
|
*/
|
||||||
private final PreviewCallback previewCallback;
|
private final PreviewCallback previewCallback;
|
||||||
|
|
||||||
|
private OnTorchListener onTorchListener;
|
||||||
|
private OnSensorListener onSensorListener;
|
||||||
|
|
||||||
|
private boolean isTorch;
|
||||||
|
|
||||||
public CameraManager(Context context) {
|
public CameraManager(Context context) {
|
||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
this.configManager = new CameraConfigurationManager(context);
|
this.configManager = new CameraConfigurationManager(context);
|
||||||
@@ -192,14 +197,22 @@ public final class CameraManager {
|
|||||||
autoFocusManager.stop();
|
autoFocusManager.stop();
|
||||||
autoFocusManager = null;
|
autoFocusManager = null;
|
||||||
}
|
}
|
||||||
|
this.isTorch = newSetting;
|
||||||
configManager.setTorch(theCamera.getCamera(), newSetting);
|
configManager.setTorch(theCamera.getCamera(), newSetting);
|
||||||
if (wasAutoFocusManager) {
|
if (wasAutoFocusManager) {
|
||||||
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
|
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
|
||||||
autoFocusManager.start();
|
autoFocusManager.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(onTorchListener!=null){
|
||||||
|
onTorchListener.onTorchChanged(newSetting);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
|
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
|
||||||
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
|
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
|
||||||
@@ -376,4 +389,49 @@ public final class CameraManager {
|
|||||||
size, size, false);
|
size, size, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供闪光灯监听
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void setOnTorchListener(OnTorchListener listener){
|
||||||
|
this.onTorchListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 传感器光线照度监听
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void setOnSensorListener(OnSensorListener listener){
|
||||||
|
this.onSensorListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sensorChanged(boolean tooDark,float ambientLightLux){
|
||||||
|
if(onSensorListener!=null){
|
||||||
|
onSensorListener.onSensorChanged(isTorch,tooDark,ambientLightLux);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnTorchListener{
|
||||||
|
/**
|
||||||
|
* 当闪光灯状态改变时触发
|
||||||
|
* @param torch true表示开启、false表示关闭
|
||||||
|
*/
|
||||||
|
void onTorchChanged(boolean torch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 传感器灯光亮度监听
|
||||||
|
*/
|
||||||
|
public interface OnSensorListener{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param torch 闪光灯是否开启
|
||||||
|
* @param tooDark 传感器检测到的光线亮度,是否太暗
|
||||||
|
* @param ambientLightLux 光线照度
|
||||||
|
*/
|
||||||
|
void onSensorChanged(boolean torch,boolean tooDark,float ambientLightLux);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,9 @@ package com.king.zxing.camera;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import com.king.zxing.Preferences;
|
import com.king.zxing.Preferences;
|
||||||
|
|
||||||
@@ -33,11 +35,16 @@ public enum FrontLightMode {
|
|||||||
OFF;
|
OFF;
|
||||||
|
|
||||||
private static FrontLightMode parse(String modeString) {
|
private static FrontLightMode parse(String modeString) {
|
||||||
return modeString == null ? OFF : valueOf(modeString);
|
return modeString == null ? AUTO : valueOf(modeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FrontLightMode readPref(SharedPreferences sharedPrefs) {
|
public static FrontLightMode readPref(SharedPreferences sharedPrefs) {
|
||||||
return parse(sharedPrefs.getString(Preferences.KEY_FRONT_LIGHT_MODE, OFF.toString()));
|
return parse(sharedPrefs.getString(Preferences.KEY_FRONT_LIGHT_MODE, AUTO.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void put(Context context, FrontLightMode mode) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
prefs.edit().putString(Preferences.KEY_FRONT_LIGHT_MODE, mode.toString()).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
|
import android.support.annotation.FloatRange;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -51,7 +52,7 @@ import java.util.Vector;
|
|||||||
/**
|
/**
|
||||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||||
*/
|
*/
|
||||||
public class CodeUtils {
|
public final class CodeUtils {
|
||||||
|
|
||||||
private CodeUtils(){
|
private CodeUtils(){
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
@@ -59,8 +60,8 @@ public class CodeUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成二维码
|
* 生成二维码
|
||||||
* @param content
|
* @param content 二维码的内容
|
||||||
* @param heightPix
|
* @param heightPix 二维码的高
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Bitmap createQRCode(String content, int heightPix) {
|
public static Bitmap createQRCode(String content, int heightPix) {
|
||||||
@@ -68,13 +69,25 @@ public class CodeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成二维码
|
* 生成我二维码
|
||||||
* @param content
|
* @param content 二维码的内容
|
||||||
* @param heightPix
|
* @param heightPix 二维码的高
|
||||||
* @param logo
|
* @param logo logo大小默认占二维码的20%
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo) {
|
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo) {
|
||||||
|
return createQRCode(content,heightPix,logo,0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成二维码
|
||||||
|
* @param content 二维码的内容
|
||||||
|
* @param heightPix 二维码的高
|
||||||
|
* @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) {
|
||||||
//配置参数
|
//配置参数
|
||||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||||
hints.put( EncodeHintType.CHARACTER_SET, "utf-8");
|
hints.put( EncodeHintType.CHARACTER_SET, "utf-8");
|
||||||
@@ -82,18 +95,19 @@ public class CodeUtils {
|
|||||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||||
//设置空白边距的宽度
|
//设置空白边距的宽度
|
||||||
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
||||||
return createQRCode(content,heightPix,logo,hints);
|
return createQRCode(content,heightPix,logo,ratio,hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成二维码
|
* 生成二维码
|
||||||
* @param content
|
* @param content 二维码的内容
|
||||||
* @param heightPix
|
* @param heightPix 二维码的高
|
||||||
* @param logo
|
* @param logo 二维码中间的logo
|
||||||
|
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||||
* @param hints
|
* @param hints
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,Map<EncodeHintType,?> hints) {
|
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f)float ratio,Map<EncodeHintType,?> hints) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// 图像数据转换,使用了矩阵转换
|
// 图像数据转换,使用了矩阵转换
|
||||||
@@ -116,7 +130,7 @@ public class CodeUtils {
|
|||||||
bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);
|
bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);
|
||||||
|
|
||||||
if (logo != null) {
|
if (logo != null) {
|
||||||
bitmap = addLogo(bitmap, logo);
|
bitmap = addLogo(bitmap, logo,ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bitmap;
|
return bitmap;
|
||||||
@@ -129,8 +143,12 @@ public class CodeUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 在二维码中间添加Logo图案
|
* 在二维码中间添加Logo图案
|
||||||
|
* @param src
|
||||||
|
* @param logo
|
||||||
|
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
private static Bitmap addLogo(Bitmap src, Bitmap logo) {
|
private static Bitmap addLogo(Bitmap src, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f) float ratio) {
|
||||||
if (src == null) {
|
if (src == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -153,8 +171,8 @@ public class CodeUtils {
|
|||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
//logo大小为二维码整体大小的1/6
|
//logo大小为二维码整体大小
|
||||||
float scaleFactor = srcWidth * 1.0f / 6 / logoWidth;
|
float scaleFactor = srcWidth * ratio / logoWidth;
|
||||||
Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
|
Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
|
||||||
try {
|
try {
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
@@ -255,7 +273,7 @@ public class CodeUtils {
|
|||||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
try {
|
try {
|
||||||
result = reader.decodeWithState(bitmap);
|
result = reader.decodeWithState(bitmap);
|
||||||
} catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
|
} catch (Exception e) {//解析失败时则通过GlobalHistogramBinarizer 再试一次
|
||||||
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||||
try {
|
try {
|
||||||
result = reader.decodeWithState(bitmap1);
|
result = reader.decodeWithState(bitmap1);
|
||||||
@@ -290,7 +308,7 @@ public class CodeUtils {
|
|||||||
int h = newOpts.outHeight;
|
int h = newOpts.outHeight;
|
||||||
float width = 800f;
|
float width = 800f;
|
||||||
float height = 480f;
|
float height = 480f;
|
||||||
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||||
int be = 1;// be=1表示不缩放
|
int be = 1;// be=1表示不缩放
|
||||||
if (w > h && w > width) {// 如果宽度大的话根据宽度固定大小缩放
|
if (w > h && w > width) {// 如果宽度大的话根据宽度固定大小缩放
|
||||||
be = (int) (newOpts.outWidth / width);
|
be = (int) (newOpts.outWidth / width);
|
||||||
|
|||||||
BIN
lib/src/main/res/drawable-xxhdpi/zxl_torch_off.png
Normal file
BIN
lib/src/main/res/drawable-xxhdpi/zxl_torch_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
lib/src/main/res/drawable-xxhdpi/zxl_torch_on.png
Normal file
BIN
lib/src/main/res/drawable-xxhdpi/zxl_torch_on.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
5
lib/src/main/res/drawable/zxl_torch_selector.xml
Normal file
5
lib/src/main/res/drawable/zxl_torch_selector.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_selected="true" android:drawable="@drawable/zxl_torch_on"/>
|
||||||
|
<item android:drawable="@drawable/zxl_torch_off"/>
|
||||||
|
</selector>
|
||||||
@@ -23,5 +23,11 @@
|
|||||||
android:id="@+id/viewfinderView"
|
android:id="@+id/viewfinderView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivTorch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/zxl_torch_selector"
|
||||||
|
android:layout_marginTop="@dimen/torchMarginTop" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
13
lib/src/main/res/values-v19/styles.xml
Normal file
13
lib/src/main/res/values-v19/styles.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="CaptureTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="colorPrimary">@android:color/black</item>
|
||||||
|
<item name="colorPrimaryDark">@android:color/black</item>
|
||||||
|
<item name="android:windowTranslucentStatus">true</item>
|
||||||
|
<item name="android:windowTranslucentNavigation">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
15
lib/src/main/res/values-v21/styles.xml
Normal file
15
lib/src/main/res/values-v21/styles.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="CaptureTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="colorPrimary">@android:color/black</item>
|
||||||
|
<item name="colorPrimaryDark">@android:color/black</item>
|
||||||
|
<item name="android:windowTranslucentStatus">true</item>
|
||||||
|
<item name="android:windowTranslucentNavigation">true</item>
|
||||||
|
<item name="android:statusBarColor">@color/capture_status_bar_color</item>
|
||||||
|
<item name="android:navigationBarColor">@color/capture_navigation_bar_color</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -8,4 +8,7 @@
|
|||||||
<color name="viewfinder_result_point_color">#C0FFBD21</color>
|
<color name="viewfinder_result_point_color">#C0FFBD21</color>
|
||||||
<color name="viewfinder_text_color">#FFC0C0C0</color>
|
<color name="viewfinder_text_color">#FFC0C0C0</color>
|
||||||
|
|
||||||
|
<color name="capture_status_bar_color">#00000000</color>
|
||||||
|
<color name="capture_navigation_bar_color">#00000000</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
4
lib/src/main/res/values/dimens.xml
Normal file
4
lib/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="torchMarginTop">80dp</dimen>
|
||||||
|
</resources>
|
||||||
10
lib/src/main/res/values/styles.xml
Normal file
10
lib/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="CaptureTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="colorPrimary">@android:color/black</item>
|
||||||
|
<item name="colorPrimaryDark">@android:color/black</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//App
|
//App
|
||||||
def app_version = [:]
|
def app_version = [:]
|
||||||
app_version.versionCode = 13 //androidx 14
|
app_version.versionCode = 15 //androidx 16
|
||||||
app_version.versionName = "1.1.3"
|
app_version.versionName = "1.1.4"
|
||||||
ext.app_version = app_version
|
ext.app_version = app_version
|
||||||
|
|
||||||
//build version
|
//build version
|
||||||
|
|||||||
Reference in New Issue
Block a user