优化细节

This commit is contained in:
Jenly
2020-12-17 00:34:26 +08:00
parent 4d607cf849
commit 7c87efa216
21 changed files with 243 additions and 256 deletions

View File

@@ -7,7 +7,7 @@
[![JitPack](https://jitpack.io/v/jenly1314/ZXingLite.svg)](https://jitpack.io/#jenly1314/ZXingLite) [![JitPack](https://jitpack.io/v/jenly1314/ZXingLite.svg)](https://jitpack.io/#jenly1314/ZXingLite)
[![CI](https://travis-ci.org/jenly1314/ZXingLite.svg?branch=master)](https://travis-ci.org/jenly1314/ZXingLite) [![CI](https://travis-ci.org/jenly1314/ZXingLite.svg?branch=master)](https://travis-ci.org/jenly1314/ZXingLite)
[![CircleCI](https://circleci.com/gh/jenly1314/ZXingLite.svg?style=svg)](https://circleci.com/gh/jenly1314/ZXingLite) [![CircleCI](https://circleci.com/gh/jenly1314/ZXingLite.svg?style=svg)](https://circleci.com/gh/jenly1314/ZXingLite)
[![API](https://img.shields.io/badge/API-16%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=16) [![API](https://img.shields.io/badge/API-21%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=21)
[![License](https://img.shields.io/badge/license-Apche%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![License](https://img.shields.io/badge/license-Apche%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
[![Blog](https://img.shields.io/badge/blog-Jenly-9933CC.svg)](https://jenly1314.github.io/) [![Blog](https://img.shields.io/badge/blog-Jenly-9933CC.svg)](https://jenly1314.github.io/)
[![QQGroup](https://img.shields.io/badge/QQGroup-20867961-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=8fcc6a2f88552ea44b1.1.982c94fd124f7bb3ec227e2a400dbbfaad3dc2f5ad) [![QQGroup](https://img.shields.io/badge/QQGroup-20867961-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=8fcc6a2f88552ea44b1.1.982c94fd124f7bb3ec227e2a400dbbfaad3dc2f5ad)
@@ -44,7 +44,7 @@ ZXingLite for Android 是ZXing的精简版基于ZXing库优化扫码和生成
| scannerLineMoveDistance | dimension | 2dp | 扫描线每次移动距离 | | scannerLineMoveDistance | dimension | 2dp | 扫描线每次移动距离 |
| scannerLineHeight | dimension | 5dp | 扫描线高度 | | scannerLineHeight | dimension | 5dp | 扫描线高度 |
| frameLineWidth | dimension | 1dp | 边框线宽度 | | frameLineWidth | dimension | 1dp | 边框线宽度 |
| scannerAnimationDelay | integer | 15 | 扫描动画延迟间隔时间,单位:毫秒 | | scannerAnimationDelay | integer | 20 | 扫描动画延迟间隔时间,单位:毫秒 |
| frameRatio | float | 0.625f | 扫码框与屏幕占比 | | frameRatio | float | 0.625f | 扫码框与屏幕占比 |
@@ -74,10 +74,11 @@ implementation 'com.king.zxing:zxing-lite:1.1.9'
</dependency> </dependency>
``` ```
###### 如果Gradle出现compile失败的情况可以在Project的build.gradle里面添加如下也可以使用上面的GitPack来complie ###### 如果Gradle出现compile失败的情况可以在Project的build.gradle里面添加如下也可以使用上面的JitPack来compile
```gradle ```gradle
allprojects { allprojects {
repositories { repositories {
//...
maven { url 'https://dl.bintray.com/jenly/maven' } maven { url 'https://dl.bintray.com/jenly/maven' }
} }
} }
@@ -165,6 +166,17 @@ api 'com.google.zxing:core:3.3.3'
> 4、参照CaptureHelper写一个自定义的扫码帮助类其它步骤同方式3。扩展高级用法谨慎使用 > 4、参照CaptureHelper写一个自定义的扫码帮助类其它步骤同方式3。扩展高级用法谨慎使用
### 其他
需使用JDK8+编译在你项目中的build.gradle的android{}中添加配置:
```gradle
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
```
更多使用详情,请查看[app](app)中的源码使用示例或直接查看[API帮助文档](https://jenly1314.github.io/projects/ZXingLite/doc/) 更多使用详情,请查看[app](app)中的源码使用示例或直接查看[API帮助文档](https://jenly1314.github.io/projects/ZXingLite/doc/)
@@ -254,9 +266,11 @@ api 'com.google.zxing:core:3.3.3'
CNBlogs: <a title="博客园" href="https://www.cnblogs.com/jenly" target="_blank">jenly</a> CNBlogs: <a title="博客园" href="https://www.cnblogs.com/jenly" target="_blank">jenly</a>
Github: <a title="Github开源项目" href="https://github.com/jenly1314" target="_blank">jenly1314</a> GitHub: <a title="GitHub开源项目" href="https://github.com/jenly1314" target="_blank">jenly1314</a>
加入QQ群: <a title="点击加入QQ群" href="http://shang.qq.com/wpa/qunwpa?idkey=8fcc6a2f88552ea44b1.1.982c94fd124f7bb3ec227e2a400dbbfaad3dc2f5ad" target="_blank">20867961</a> Gitee: <a title="Gitee开源项目" href="https://gitee.com/jenly1314" target="_blank">jenly1314</a>
加入QQ群: <a title="点击加入QQ群" href="http://shang.qq.com/wpa/qunwpa?idkey=8fcc6a2f88552ea44b1411582c94fd124f7bb3ec227e2a400dbbfaad3dc2f5ad" target="_blank">20867961</a>
<div> <div>
<img src="https://jenly1314.github.io/image/jenly666.png"> <img src="https://jenly1314.github.io/image/jenly666.png">
<img src="https://jenly1314.github.io/image/qqgourp.png"> <img src="https://jenly1314.github.io/image/qqgourp.png">

View File

@@ -8,6 +8,7 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.zxing.Result;
import com.king.zxing.CaptureHelper; import com.king.zxing.CaptureHelper;
import com.king.zxing.OnCaptureCallback; import com.king.zxing.OnCaptureCallback;
import com.king.zxing.ViewfinderView; import com.king.zxing.ViewfinderView;
@@ -34,6 +35,7 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
private View ivTorch; private View ivTorch;
private Toast toast;
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
@@ -100,13 +102,23 @@ public class CustomActivity extends AppCompatActivity implements OnCaptureCallba
* @return * @return
*/ */
@Override @Override
public boolean onResultCallback(String result) { public boolean onResultCallback(Result result) {
if(isContinuousScan){ if(isContinuousScan){
Toast.makeText(this,result,Toast.LENGTH_SHORT).show(); showToast(result.getText());
} }
return false; return false;
} }
private void showToast(String text){
if(toast == null){
toast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
}else{
toast.setDuration(Toast.LENGTH_SHORT);
toast.setText(text);
}
toast.show();
}
public void onClick(View v){ public void onClick(View v){

View File

@@ -20,9 +20,10 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.zxing.Result;
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.FrontLightMode;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
@@ -33,6 +34,9 @@ import androidx.appcompat.widget.Toolbar;
public class CustomCaptureActivity extends CaptureActivity { public class CustomCaptureActivity extends CaptureActivity {
private boolean isContinuousScan; private boolean isContinuousScan;
private Toast toast;
@Override @Override
public int getLayoutId() { public int getLayoutId() {
return R.layout.custom_capture_activity; return R.layout.custom_capture_activity;
@@ -51,12 +55,12 @@ public class CustomCaptureActivity extends CaptureActivity {
//获取CaptureHelper里面有扫码相关的配置设置 //获取CaptureHelper里面有扫码相关的配置设置
getCaptureHelper().playBeep(false)//播放音效 getCaptureHelper().playBeep(false)//播放音效
.vibrate(true)//震动 .vibrate(true)//震动
.fullScreenScan(true)
.supportVerticalCode(true)//支持扫垂直条码,建议有此需求时才使用。 .supportVerticalCode(true)//支持扫垂直条码,建议有此需求时才使用。
// .decodeFormats(DecodeFormatManager.QR_CODE_FORMATS)//设置只识别二维码会提升速度 // .decodeFormats(DecodeFormatManager.QR_CODE_FORMATS)//设置只识别二维码会提升速度
// .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)//设置光线太暗时,自动触发开启闪光灯的照度值 .tooDarkLux(45f)//设置光线太暗时,自动触发开启闪光灯的照度值
.brightEnoughLux(100f)//设置光线足够明亮时,自动触发关闭闪光灯的照度值 .brightEnoughLux(100f)//设置光线足够明亮时,自动触发关闭闪光灯的照度值
.continuousScan(isContinuousScan)//是否连扫 .continuousScan(isContinuousScan)//是否连扫
@@ -70,14 +74,24 @@ public class CustomCaptureActivity extends CaptureActivity {
* @return * @return
*/ */
@Override @Override
public boolean onResultCallback(String result) { public boolean onResultCallback(Result result) {
if(isContinuousScan){//连续扫码时,直接弹出结果 if(isContinuousScan){//连续扫码时,直接弹出结果
Toast.makeText(this,result,Toast.LENGTH_SHORT).show(); showToast(result.getText());
} }
return super.onResultCallback(result); return super.onResultCallback(result);
} }
private void showToast(String text){
if(toast == null){
toast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
}else{
toast.setDuration(Toast.LENGTH_SHORT);
toast.setText(text);
}
toast.show();
}
public void onClick(View v){ public void onClick(View v){
switch (v.getId()){ switch (v.getId()){
case R.id.ivLeft: case R.id.ivLeft:

View File

@@ -31,6 +31,8 @@ import com.king.zxing.Intents;
import com.king.zxing.app.util.UriUtils; import com.king.zxing.app.util.UriUtils;
import com.king.zxing.util.CodeUtils; import com.king.zxing.util.CodeUtils;
import org.w3c.dom.Text;
import java.util.List; import java.util.List;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
@@ -70,6 +72,8 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
private String title; private String title;
private boolean isContinuousScan; private boolean isContinuousScan;
private Toast toast;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -83,7 +87,7 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
switch (requestCode){ switch (requestCode){
case REQUEST_CODE_SCAN: case REQUEST_CODE_SCAN:
String result = data.getStringExtra(Intents.Scan.RESULT); String result = data.getStringExtra(Intents.Scan.RESULT);
Toast.makeText(this,result,Toast.LENGTH_SHORT).show(); showToast(result);
break; break;
case REQUEST_CODE_PHOTO: case REQUEST_CODE_PHOTO:
parsePhoto(data); parsePhoto(data);
@@ -93,6 +97,16 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
} }
} }
private void showToast(String text){
if(toast == null){
toast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
}else{
toast.setDuration(Toast.LENGTH_SHORT);
toast.setText(text);
}
toast.show();
}
private void parsePhoto(Intent data){ private void parsePhoto(Intent data){
final String path = UriUtils.getImagePath(this,data); final String path = UriUtils.getImagePath(this,data);
Log.d("Jenly","path:" + path); Log.d("Jenly","path:" + path);

View File

@@ -20,7 +20,8 @@
app:cornerColor="@color/colorPrimary" app:cornerColor="@color/colorPrimary"
app:resultPointColor="@color/colorAccent" app:resultPointColor="@color/colorAccent"
app:labelTextLocation="bottom" app:labelTextLocation="bottom"
app:laserStyle="grid"/> app:laserStyle="grid"
app:showResultPoint="true"/>
<ImageView <ImageView
android:id="@+id/ivTorch" android:id="@+id/ivTorch"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -18,15 +18,12 @@ package com.king.zxing;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.preference.PreferenceManager;
import com.king.zxing.camera.CameraManager; import com.king.zxing.camera.CameraManager;
import com.king.zxing.camera.FrontLightMode;
/** /**
* Detects ambient light and switches on the front light when very dark, and off again when sufficiently light. * Detects ambient light and switches on the front light when very dark, and off again when sufficiently light.
@@ -36,6 +33,8 @@ import com.king.zxing.camera.FrontLightMode;
*/ */
final class AmbientLightManager implements SensorEventListener { final class AmbientLightManager implements SensorEventListener {
private static final int INTERVAL_TIME = 200;
protected static final float TOO_DARK_LUX = 45.0f; protected static final float TOO_DARK_LUX = 45.0f;
protected static final float BRIGHT_ENOUGH_LUX = 100.0f; protected static final float BRIGHT_ENOUGH_LUX = 100.0f;
@@ -52,19 +51,18 @@ final class AmbientLightManager implements SensorEventListener {
private CameraManager cameraManager; private CameraManager cameraManager;
private Sensor lightSensor; private Sensor lightSensor;
private long lastTime;
AmbientLightManager(Context context) { AmbientLightManager(Context context) {
this.context = context; this.context = context;
} }
void start(CameraManager cameraManager) { void start(CameraManager cameraManager) {
this.cameraManager = cameraManager; this.cameraManager = cameraManager;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if (FrontLightMode.readPref(sharedPrefs) == FrontLightMode.AUTO) { lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); if (lightSensor != null) {
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
if (lightSensor != null) {
sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
} }
} }
@@ -79,6 +77,12 @@ final class AmbientLightManager implements SensorEventListener {
@Override @Override
public void onSensorChanged(SensorEvent sensorEvent) { public void onSensorChanged(SensorEvent sensorEvent) {
long currentTime = System.currentTimeMillis();
if(currentTime - lastTime < INTERVAL_TIME){//降低频率
return;
}
lastTime = currentTime;
float ambientLightLux = sensorEvent.values[0]; float ambientLightLux = sensorEvent.values[0];
if (cameraManager != null) { if (cameraManager != null) {
if (ambientLightLux <= tooDarkLux) { if (ambientLightLux <= tooDarkLux) {

View File

@@ -16,16 +16,13 @@ package com.king.zxing;
*/ */
import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.os.Build;
import android.os.Vibrator; import android.os.Vibrator;
import android.preference.PreferenceManager;
import com.king.zxing.util.LogUtils; import com.king.zxing.util.LogUtils;
@@ -37,9 +34,7 @@ import java.io.IOException;
*/ */
public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable { public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
private static final String TAG = BeepManager.class.getSimpleName(); // private static final float BEEP_VOLUME = 0.10f;
private static final float BEEP_VOLUME = 0.10f;
private static final long VIBRATE_DURATION = 200L; private static final long VIBRATE_DURATION = 200L;
private final Activity activity; private final Activity activity;
@@ -62,8 +57,8 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
} }
synchronized void updatePrefs() { synchronized void updatePrefs() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); // SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
shouldBeep(prefs, activity); // shouldBeep(prefs, activity);
// vibrate = prefs.getBoolean(Preferences.KEY_VIBRATE, false); // vibrate = prefs.getBoolean(Preferences.KEY_VIBRATE, false);
if (playBeep && mediaPlayer == null) { if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it too loud, // The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
@@ -77,6 +72,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
if (playBeep && mediaPlayer != null) { if (playBeep && mediaPlayer != null) {
mediaPlayer.start(); mediaPlayer.start();
} }
LogUtils.d("vibrate:" + vibrate);
if (vibrate) { if (vibrate) {
Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE); Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION); vibrator.vibrate(VIBRATE_DURATION);
@@ -95,7 +91,6 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
return shouldPlayBeep; return shouldPlayBeep;
} }
@TargetApi(Build.VERSION_CODES.KITKAT)
private MediaPlayer buildMediaPlayer(Context activity) { private MediaPlayer buildMediaPlayer(Context activity) {
MediaPlayer mediaPlayer = new MediaPlayer(); MediaPlayer mediaPlayer = new MediaPlayer();
try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.zxl_beep)) { try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.zxl_beep)) {
@@ -103,7 +98,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
mediaPlayer.setOnErrorListener(this); mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false); mediaPlayer.setLooping(false);
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME); // mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare(); mediaPlayer.prepare();
return mediaPlayer; return mediaPlayer;
} catch (IOException ioe) { } catch (IOException ioe) {

View File

@@ -20,6 +20,7 @@ import android.view.MotionEvent;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager; import com.king.zxing.camera.CameraManager;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
@@ -62,7 +63,6 @@ public class CaptureActivity extends AppCompatActivity implements OnCaptureCallb
int ivTorchId = getIvTorchId(); int ivTorchId = getIvTorchId();
if(ivTorchId != 0){ if(ivTorchId != 0){
ivTorch = findViewById(ivTorchId); ivTorch = findViewById(ivTorchId);
ivTorch.setVisibility(View.INVISIBLE);
} }
initCaptureHelper(); initCaptureHelper();
} }
@@ -161,7 +161,7 @@ public class CaptureActivity extends AppCompatActivity implements OnCaptureCallb
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截 * @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截
*/ */
@Override @Override
public boolean onResultCallback(String result) { public boolean onResultCallback(Result result) {
return false; return false;
} }
} }

View File

@@ -21,6 +21,7 @@ import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager; import com.king.zxing.camera.CameraManager;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
@@ -74,7 +75,6 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
int ivTorchId = getIvTorchId(); int ivTorchId = getIvTorchId();
if(ivTorchId != 0){ if(ivTorchId != 0){
ivTorch = mRootView.findViewById(ivTorchId); ivTorch = mRootView.findViewById(ivTorchId);
ivTorch.setVisibility(View.INVISIBLE);
} }
initCaptureHelper(); initCaptureHelper();
} }
@@ -185,7 +185,7 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截 * @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截
*/ */
@Override @Override
public boolean onResultCallback(String result) { public boolean onResultCallback(Result result) {
return false; return false;
} }

View File

@@ -26,7 +26,6 @@ import java.util.Map;
*/ */
public class CaptureHandler extends Handler implements ResultPointCallback { public class CaptureHandler extends Handler implements ResultPointCallback {
private static final String TAG = CaptureHandler.class.getSimpleName();
private final OnCaptureListener onCaptureListener; private final OnCaptureListener onCaptureListener;
private final DecodeThread decodeThread; private final DecodeThread decodeThread;
@@ -155,27 +154,13 @@ public class CaptureHandler extends Handler implements ResultPointCallback {
*/ */
private ResultPoint transform(ResultPoint originPoint) { private ResultPoint transform(ResultPoint originPoint) {
Point screenPoint = cameraManager.getScreenResolution(); Point screenPoint = cameraManager.getScreenResolution();
Point cameraPoint = cameraManager.getCameraResolution(); Point previewPoint = cameraManager.getPreviewSizeOnScreen();
float scaleX; float scaleX = 1.0f * screenPoint.x / previewPoint.x;
float scaleY; float scaleY = 1.0f * screenPoint.y / previewPoint.y;
float x;
float y;
if(screenPoint.x < screenPoint.y){
scaleX = 1.0f * screenPoint.x / cameraPoint.y;
scaleY = 1.0f * screenPoint.y / cameraPoint.x;
x = originPoint.getX() * scaleX - Math.max(screenPoint.x,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.min(screenPoint.y,cameraPoint.x)/2;
}else{
scaleX = 1.0f * screenPoint.x / cameraPoint.x;
scaleY = 1.0f * screenPoint.y / cameraPoint.y;
x = originPoint.getX() * scaleX - Math.min(screenPoint.y,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.max(screenPoint.x,cameraPoint.x)/2;
}
float x = originPoint.getX() * scaleX - Math.min(screenPoint.y,previewPoint.y)/2;
float y = originPoint.getY() * scaleY - Math.max(screenPoint.x,previewPoint.x)/2;
return new ResultPoint(x,y); return new ResultPoint(x,y);
} }

View File

@@ -31,7 +31,6 @@ 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 com.king.zxing.util.LogUtils; import com.king.zxing.util.LogUtils;
import java.io.IOException; import java.io.IOException;
@@ -153,6 +152,11 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
private boolean hasCameraFlash; private boolean hasCameraFlash;
/**
* 是否启用光线传感器
*/
private boolean isAmbientLightEnabled = true;
/** /**
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)} * use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
* @param fragment * @param fragment
@@ -233,7 +237,10 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
} else { } else {
surfaceHolder.addCallback(this); surfaceHolder.addCallback(this);
} }
ambientLightManager.start(cameraManager); if(isAmbientLightEnabled){
ambientLightManager.start(cameraManager);
}
} }
@@ -244,7 +251,9 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
captureHandler = null; captureHandler = null;
} }
inactivityTimer.onPause(); inactivityTimer.onPause();
ambientLightManager.stop(); if(isAmbientLightEnabled) {
ambientLightManager.stop();
}
beepManager.close(); beepManager.close();
cameraManager.closeDriver(); cameraManager.closeDriver();
if (!hasSurface) { if (!hasSurface) {
@@ -491,7 +500,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
* 重新启动扫码和解码器 * 重新启动扫码和解码器
*/ */
public void restartPreviewAndDecode(){ public void restartPreviewAndDecode(){
if(captureHandler!=null){ if(captureHandler != null){
captureHandler.restartPreviewAndDecode(); captureHandler.restartPreviewAndDecode();
} }
} }
@@ -517,7 +526,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
final String text = result.getText(); final String text = result.getText();
if(isContinuousScan){ if(isContinuousScan){
if(onCaptureCallback!=null){ if(onCaptureCallback!=null){
onCaptureCallback.onResultCallback(text); onCaptureCallback.onResultCallback(result);
} }
if(isAutoRestartPreviewAndDecode){ if(isAutoRestartPreviewAndDecode){
restartPreviewAndDecode(); restartPreviewAndDecode();
@@ -528,7 +537,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
if(isPlayBeep && captureHandler != null){//如果播放音效,则稍微延迟一点,给予播放音效时间 if(isPlayBeep && captureHandler != null){//如果播放音效,则稍微延迟一点,给予播放音效时间
captureHandler.postDelayed(() -> { captureHandler.postDelayed(() -> {
//如果设置了回调并且onCallback返回为true则表示拦截 //如果设置了回调并且onCallback返回为true则表示拦截
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(text)){ if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(result)){
return; return;
} }
Intent intent = new Intent(); Intent intent = new Intent();
@@ -541,7 +550,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
} }
//如果设置了回调并且onCallback返回为true则表示拦截 //如果设置了回调并且onCallback返回为true则表示拦截
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(text)){ if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(result)){
return; return;
} }
Intent intent = new Intent(); Intent intent = new Intent();
@@ -662,23 +671,6 @@ 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} * @param tooDarkLux 默认:{@link AmbientLightManager#TOO_DARK_LUX}
@@ -798,6 +790,16 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
return this; return this;
} }
/**
* 是否启用光线传感器
* @param isAmbientLightEnabled
* @return
*/
public CaptureHelper ambientLightEnabled(boolean isAmbientLightEnabled){
this.isAmbientLightEnabled = isAmbientLightEnabled;
return this;
}
/** /**
* 设置扫码回调 * 设置扫码回调

View File

@@ -27,7 +27,6 @@ import android.os.Message;
import android.view.Display; import android.view.Display;
import android.view.WindowManager; import android.view.WindowManager;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap; import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType; import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatReader;
@@ -148,16 +147,22 @@ final class DecodeHandler extends Handler {
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
LogUtils.d("Found barcode in " + (end - start) + " ms"); LogUtils.d("Found barcode in " + (end - start) + " ms");
BarcodeFormat barcodeFormat = rawResult.getBarcodeFormat(); if(handler.isSupportAutoZoom()){//是否支持自动放大
if(handler!=null && handler.isSupportAutoZoom() && barcodeFormat == BarcodeFormat.QR_CODE){
ResultPoint[] resultPoints = rawResult.getResultPoints(); ResultPoint[] resultPoints = rawResult.getResultPoints();
if(resultPoints.length >= 3){ LogUtils.d("resultPoints:" +resultPoints.length);
float distance1 = ResultPoint.distance(resultPoints[0],resultPoints[1]);
float distance2 = ResultPoint.distance(resultPoints[1],resultPoints[2]); final int length = resultPoints.length;
float distance3 = ResultPoint.distance(resultPoints[0],resultPoints[2]); if(length >= 2){//超过两个点则计算距离
int maxDistance = (int)Math.max(Math.max(distance1,distance2),distance3); int ratio = 6;
if(handleAutoZoom(maxDistance,width)){ int maxDistance = (int)ResultPoint.distance(resultPoints[0],resultPoints[1]);
if(length >= 3){
float distance2 = ResultPoint.distance(resultPoints[1],resultPoints[2]);
float distance3 = ResultPoint.distance(resultPoints[0],resultPoints[2]);
maxDistance = (int)Math.max(Math.max(maxDistance,distance2),distance3);
ratio = 5;
}
if(handleAutoZoom(maxDistance,width,ratio)){//根据点之间的最大距离
Message message = Message.obtain(); Message message = Message.obtain();
message.what = R.id.decode_succeeded; message.what = R.id.decode_succeeded;
message.obj = rawResult; message.obj = rawResult;
@@ -170,23 +175,19 @@ final class DecodeHandler extends Handler {
return; return;
} }
} }
} }
if (handler != null) { Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult); if(handler.isReturnBitmap()){
if(handler.isReturnBitmap()){ Bundle bundle = new Bundle();
Bundle bundle = new Bundle(); bundleThumbnail(source, bundle);
bundleThumbnail(source, bundle); message.setData(bundle);
message.setData(bundle);
}
message.sendToTarget();
} }
message.sendToTarget();
} else { } else {
if (handler != null) { Message message = Message.obtain(handler, R.id.decode_failed);
Message message = Message.obtain(handler, R.id.decode_failed); message.sendToTarget();
message.sendToTarget();
}
} }
} }
@@ -219,12 +220,12 @@ final class DecodeHandler extends Handler {
bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth()); bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth());
} }
private boolean handleAutoZoom(int length,int width){ private boolean handleAutoZoom(int length,int width,int ratio){
if(lastZoomTime > System.currentTimeMillis() - 1000){ if(lastZoomTime > System.currentTimeMillis() - 1000){
return true; return false;
} }
if(length < width/ 5){ if(length < width / ratio){
Camera camera = cameraManager.getOpenCamera().getCamera(); Camera camera = cameraManager.getOpenCamera().getCamera();
if(camera!=null){ if(camera!=null){

View File

@@ -35,8 +35,6 @@ import java.util.concurrent.RejectedExecutionException;
*/ */
final class InactivityTimer { final class InactivityTimer {
private static final String TAG = InactivityTimer.class.getSimpleName();
private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L; private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
private final Activity activity; private final Activity activity;
@@ -106,7 +104,7 @@ final class InactivityTimer {
// 0 indicates that we're on battery // 0 indicates that we're on battery
InactivityTimer inactivityTimer = weakReference.get(); InactivityTimer inactivityTimer = weakReference.get();
if(inactivityTimer!=null){ if(inactivityTimer != null){
boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0; boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
if (onBatteryNow) { if (onBatteryNow) {
inactivityTimer.onActivity(); inactivityTimer.onActivity();

View File

@@ -1,6 +1,7 @@
package com.king.zxing; package com.king.zxing;
import com.google.zxing.Result;
/** /**
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> * @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
@@ -12,5 +13,5 @@ public interface OnCaptureCallback {
* @param result 扫码结果 * @param result 扫码结果
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截 * @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截
*/ */
boolean onResultCallback(String result); boolean onResultCallback(Result result);
} }

View File

@@ -52,7 +52,7 @@ public final class ViewfinderView extends View {
private static final int CURRENT_POINT_OPACITY = 0xA0; private static final int CURRENT_POINT_OPACITY = 0xA0;
private static final int MAX_RESULT_POINTS = 20; private static final int MAX_RESULT_POINTS = 20;
private static final int POINT_SIZE = 20; private static final int POINT_SIZE = 30;
/** /**
* 画笔 * 画笔
@@ -176,7 +176,7 @@ public final class ViewfinderView extends View {
private int frameLineWidth; private int frameLineWidth;
/** /**
* 扫描动画延迟间隔时间 默认15毫秒 * 扫描动画延迟间隔时间 默认20毫秒
*/ */
private int scannerAnimationDelay; private int scannerAnimationDelay;
@@ -274,7 +274,7 @@ public final class ViewfinderView extends View {
scannerLineMoveDistance = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineMoveDistance,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,2,getResources().getDisplayMetrics())); scannerLineMoveDistance = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineMoveDistance,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,2,getResources().getDisplayMetrics()));
scannerLineHeight = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineHeight,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics())); scannerLineHeight = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineHeight,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics()));
frameLineWidth = (int)array.getDimension(R.styleable.ViewfinderView_frameLineWidth,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())); frameLineWidth = (int)array.getDimension(R.styleable.ViewfinderView_frameLineWidth,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics()));
scannerAnimationDelay = array.getInteger(R.styleable.ViewfinderView_scannerAnimationDelay,15); scannerAnimationDelay = array.getInteger(R.styleable.ViewfinderView_scannerAnimationDelay,20);
frameRatio = array.getFloat(R.styleable.ViewfinderView_frameRatio,0.625f); frameRatio = array.getFloat(R.styleable.ViewfinderView_frameRatio,0.625f);
array.recycle(); array.recycle();

View File

@@ -42,7 +42,6 @@ final class CameraConfigurationManager {
private int cwNeededRotation; private int cwNeededRotation;
private int cwRotationFromDisplayToCamera; private int cwRotationFromDisplayToCamera;
private Point screenResolution; private Point screenResolution;
private Point cameraResolution;
private Point bestPreviewSize; private Point bestPreviewSize;
private Point previewSizeOnScreen; private Point previewSizeOnScreen;
@@ -81,6 +80,7 @@ final class CameraConfigurationManager {
throw new IllegalArgumentException("Bad rotation: " + displayRotation); throw new IllegalArgumentException("Bad rotation: " + displayRotation);
} }
} }
LogUtils.i("Display at: " + cwRotationFromNaturalToDisplay); LogUtils.i("Display at: " + cwRotationFromNaturalToDisplay);
int cwRotationFromNaturalToCamera = camera.getOrientation(); int cwRotationFromNaturalToCamera = camera.getOrientation();
@@ -92,19 +92,6 @@ final class CameraConfigurationManager {
LogUtils.i("Front camera overriden to: " + cwRotationFromNaturalToCamera); LogUtils.i("Front camera overriden to: " + cwRotationFromNaturalToCamera);
} }
/*
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String overrideRotationString;
if (camera.getFacing() == CameraFacing.FRONT) {
overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION_FRONT, null);
} else {
overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION, null);
}
if (overrideRotationString != null && !"-".equals(overrideRotationString)) {
LogUtils.i("Overriding camera manually to " + overrideRotationString);
cwRotationFromNaturalToCamera = Integer.parseInt(overrideRotationString);
}
*/
cwRotationFromDisplayToCamera = (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360; cwRotationFromDisplayToCamera = (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
LogUtils.i("Final display orientation: " + cwRotationFromDisplayToCamera); LogUtils.i("Final display orientation: " + cwRotationFromDisplayToCamera);
@@ -116,32 +103,26 @@ final class CameraConfigurationManager {
} }
LogUtils.i("Clockwise rotation from display to camera: " + cwNeededRotation); LogUtils.i("Clockwise rotation from display to camera: " + cwNeededRotation);
Point theScreenResolution = new Point(); screenResolution = new Point();
display.getSize(theScreenResolution); display.getSize(screenResolution);
screenResolution = theScreenResolution;
LogUtils.i("Screen resolution in current orientation: " + screenResolution); LogUtils.i("Screen resolution in current orientation: " + screenResolution);
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
LogUtils.i("Camera resolution: " + cameraResolution);
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution); bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
LogUtils.i("Best available preview size: " + bestPreviewSize); LogUtils.i("Best available preview size: " + bestPreviewSize);
boolean isScreenPortrait = screenResolution.x < screenResolution.y; boolean isScreenPortrait = screenResolution.x < screenResolution.y;
boolean isPreviewSizePortrait = bestPreviewSize.x < bestPreviewSize.y; if (isScreenPortrait) {
if (isScreenPortrait == isPreviewSizePortrait) {
previewSizeOnScreen = bestPreviewSize;
} else {
previewSizeOnScreen = new Point(bestPreviewSize.y, bestPreviewSize.x); previewSizeOnScreen = new Point(bestPreviewSize.y, bestPreviewSize.x);
} else {
previewSizeOnScreen = bestPreviewSize;
} }
LogUtils.i("Preview size on screen: " + previewSizeOnScreen); LogUtils.i("Preview size on screen: " + previewSizeOnScreen);
} }
void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) { void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
Camera theCamera = camera.getCamera(); Camera theCamera = camera.getCamera();
Camera.Parameters parameters = theCamera.getParameters(); Camera.Parameters parameters = theCamera.getParameters();
if (parameters == null) { if (parameters == null) {
LogUtils.w("Device error: no camera parameters are available. Proceeding without configuration."); LogUtils.w("Device error: no camera parameters are available. Proceeding without configuration.");
return; return;
@@ -159,7 +140,7 @@ final class CameraConfigurationManager {
parameters.setZoom(parameters.getMaxZoom() / 10); parameters.setZoom(parameters.getMaxZoom() / 10);
} }
initializeTorch(parameters, prefs, safeMode); // initializeTorch(parameters, prefs, safeMode);
CameraConfigurationUtils.setFocus( CameraConfigurationUtils.setFocus(
parameters, parameters,
@@ -189,9 +170,9 @@ final class CameraConfigurationManager {
} }
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y); parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
theCamera.setParameters(parameters); theCamera.setParameters(parameters);
theCamera.cancelAutoFocus();
theCamera.setDisplayOrientation(cwRotationFromDisplayToCamera); theCamera.setDisplayOrientation(cwRotationFromDisplayToCamera);
Camera.Parameters afterParameters = theCamera.getParameters(); Camera.Parameters afterParameters = theCamera.getParameters();
@@ -202,6 +183,7 @@ final class CameraConfigurationManager {
bestPreviewSize.x = afterSize.width; bestPreviewSize.x = afterSize.width;
bestPreviewSize.y = afterSize.height; bestPreviewSize.y = afterSize.height;
} }
} }
Point getBestPreviewSize() { Point getBestPreviewSize() {
@@ -212,10 +194,6 @@ final class CameraConfigurationManager {
return previewSizeOnScreen; return previewSizeOnScreen;
} }
Point getCameraResolution() {
return cameraResolution;
}
Point getScreenResolution() { Point getScreenResolution() {
return screenResolution; return screenResolution;
} }
@@ -243,17 +221,16 @@ final class CameraConfigurationManager {
camera.setParameters(parameters); camera.setParameters(parameters);
} }
private void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs, boolean safeMode) { private void initializeTorch(Camera.Parameters parameters, boolean safeMode) {
boolean currentSetting = FrontLightMode.readPref(prefs) == FrontLightMode.ON; doSetTorch(parameters, false, safeMode);
doSetTorch(parameters, currentSetting, safeMode);
} }
private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) { private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
CameraConfigurationUtils.setTorch(parameters, newSetting); CameraConfigurationUtils.setTorch(parameters, newSetting);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); // SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (!safeMode && !prefs.getBoolean(Preferences.KEY_DISABLE_EXPOSURE, true)) { // if (!safeMode && !prefs.getBoolean(Preferences.KEY_DISABLE_EXPOSURE, true)) {
CameraConfigurationUtils.setBestExposure(parameters, newSetting); // CameraConfigurationUtils.setBestExposure(parameters, newSetting);
} // }
} }
} }

View File

@@ -26,6 +26,7 @@ import com.king.zxing.util.LogUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -269,89 +270,56 @@ public final class CameraConfigurationUtils {
} }
} }
/**
* 预览尺寸与给定的宽高尺寸比较器。首先比较宽高的比例,在宽高比相同的情况下,根据宽和高的最小差进行比较。
*/
private static class SizeComparator implements Comparator<Camera.Size> {
private final int width;
private final int height;
private final float ratio;
SizeComparator(int width, int height) {
//不管横屏还是竖屏parameters.getSupportedPreviewSizes()的size.width 始终大于或等于 size.height
if (width < height) {
this.width = height;
this.height = width;
} else {
this.width = width;
this.height = height;
}
this.ratio = (float) this.height / this.width;
}
@Override
public int compare(Camera.Size size1, Camera.Size size2) {
int width1 = size1.width;
int height1 = size1.height;
int width2 = size2.width;
int height2 = size2.height;
float ratio1 = Math.abs((float) height1 / width1 - ratio);
float ratio2 = Math.abs((float) height2 / width2 - ratio);
int result = Float.compare(ratio1, ratio2);
if (result != 0) {
return result;
} else {
int minGap1 = Math.abs(width - width1) + Math.abs(height - height1);
int minGap2 = Math.abs(width - width2) + Math.abs(height - height2);
return minGap1 - minGap2;
}
}
}
/**
* 在Camera支持的预览尺寸中找到最佳的预览尺寸
* @param parameters
* @param screenResolution
* @return
*/
public static Point findBestPreviewSizeValue(Camera.Parameters parameters,final Point screenResolution) { public static Point findBestPreviewSizeValue(Camera.Parameters parameters,final Point screenResolution) {
List<Camera.Size> preList = parameters.getSupportedPreviewSizes();
List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes(); Collections.sort(preList, new SizeComparator(screenResolution.x, screenResolution.y));
if (rawSupportedSizes == null) { Camera.Size size = preList.get(0);
LogUtils.w( "Device returned no supported preview sizes; using default"); return new Point(size.width,size.height);
Camera.Size defaultSize = parameters.getPreviewSize();
if (defaultSize == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
return new Point(defaultSize.width, defaultSize.height);
}
if (LogUtils.isShowLog()) {
StringBuilder previewSizesString = new StringBuilder();
for (Camera.Size size : rawSupportedSizes) {
previewSizesString.append(size.width).append('x').append(size.height).append(' ');
}
LogUtils.d( "Supported preview sizes: " + previewSizesString);
}
double screenAspectRatio;
if(screenResolution.x < screenResolution.y){
screenAspectRatio = screenResolution.x / (double) screenResolution.y;
}else{
screenAspectRatio = screenResolution.y / (double) screenResolution.x;
}
LogUtils.d( "screenAspectRatio: " + screenAspectRatio);
// Find a suitable size, with max resolution
int maxResolution = 0;
Camera.Size maxResPreviewSize = null;
for (Camera.Size size : rawSupportedSizes) {
int realWidth = size.width;
int realHeight = size.height;
int resolution = realWidth * realHeight;
if (resolution < MIN_PREVIEW_PIXELS) {
continue;
}
boolean isCandidatePortrait = realWidth < realHeight;
int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
LogUtils.d( String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
LogUtils.d( "aspectRatio: " + aspectRatio);
double distortion = Math.abs(aspectRatio - screenAspectRatio);
LogUtils.d( "distortion: " + distortion);
if (distortion > MAX_ASPECT_DISTORTION) {
continue;
}
if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
Point exactPoint = new Point(realWidth, realHeight);
LogUtils.d( "Found preview size exactly matching screen size: " + exactPoint);
return exactPoint;
}
// Resolution is suitable; record the one with max resolution
if (resolution > maxResolution) {
maxResolution = resolution;
maxResPreviewSize = size;
}
}
// If no exact match, use largest preview size. This was not a great idea on older devices because
// of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
// the CPU is much more powerful.
if (maxResPreviewSize != null) {
Point largestSize = new Point(maxResPreviewSize.width, maxResPreviewSize.height);
LogUtils.d( "Using largest suitable preview size: " + largestSize);
return largestSize;
}
// If there is nothing at all suitable, return current preview size
Camera.Size defaultPreview = parameters.getPreviewSize();
if (defaultPreview == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
LogUtils.d( "No suitable preview sizes, using default: " + defaultSize);
return defaultSize;
} }
private static String findSettableValue(String name, private static String findSettableValue(String name,

View File

@@ -168,7 +168,7 @@ public final class CameraManager {
if (theCamera != null && !previewing) { if (theCamera != null && !previewing) {
theCamera.getCamera().startPreview(); theCamera.getCamera().startPreview();
previewing = true; previewing = true;
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera()); // autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
} }
} }
@@ -204,7 +204,7 @@ public final class CameraManager {
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){ if(onTorchListener!=null){
@@ -225,6 +225,7 @@ public final class CameraManager {
* @param message The what field of the message to be sent. * @param message The what field of the message to be sent.
*/ */
public synchronized void requestPreviewFrame(Handler handler, int message) { public synchronized void requestPreviewFrame(Handler handler, int message) {
LogUtils.d("requestPreviewFrame");
OpenCamera theCamera = camera; OpenCamera theCamera = camera;
if (theCamera != null && previewing) { if (theCamera != null && previewing) {
previewCallback.setHandler(handler, message); previewCallback.setHandler(handler, message);
@@ -244,7 +245,7 @@ public final class CameraManager {
if (camera == null) { if (camera == null) {
return null; return null;
} }
Point point = configManager.getCameraResolution(); Point point = configManager.getBestPreviewSize();
if (point == null) { if (point == null) {
// Called early, before init even finished // Called early, before init even finished
return null; return null;
@@ -281,22 +282,17 @@ public final class CameraManager {
return null; return null;
} }
Rect rect = new Rect(framingRect); Rect rect = new Rect(framingRect);
Point cameraResolution = configManager.getCameraResolution(); Point preViewResolution = configManager.getPreviewSizeOnScreen();
Point screenResolution = configManager.getScreenResolution(); Point screenResolution = configManager.getScreenResolution();
if (cameraResolution == null || screenResolution == null) { if (preViewResolution == null || screenResolution == null) {
// Called early, before init even finished // Called early, before init even finished
return null; return null;
} }
// rect.left = rect.left * cameraResolution.x / screenResolution.x; rect.left = rect.left * preViewResolution.x / screenResolution.x;
// rect.right = rect.right * cameraResolution.x / screenResolution.x; rect.right = rect.right * preViewResolution.x / screenResolution.x;
// rect.top = rect.top * cameraResolution.y / screenResolution.y; rect.top = rect.top * preViewResolution.y / screenResolution.y;
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y; rect.bottom = rect.bottom * preViewResolution.y / screenResolution.y;
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
framingRectInPreview = rect; framingRectInPreview = rect;
@@ -321,8 +317,12 @@ public final class CameraManager {
this.framingRectHorizontalOffset = framingRectHorizontalOffset; this.framingRectHorizontalOffset = framingRectHorizontalOffset;
} }
public Point getCameraResolution() { public Point getBestPreviewSize(){
return configManager.getCameraResolution(); return configManager.getBestPreviewSize();
}
public Point getPreviewSizeOnScreen() {
return configManager.getPreviewSizeOnScreen();
} }
public Point getScreenResolution() { public Point getScreenResolution() {

View File

@@ -44,7 +44,7 @@ final class PreviewCallback implements Camera.PreviewCallback {
@Override @Override
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution(); Point cameraResolution = configManager.getBestPreviewSize();
Handler thePreviewHandler = previewHandler; Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) { if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x, Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,

View File

@@ -59,6 +59,7 @@ public final class OpenCameraInterface {
cameraId = 0; cameraId = 0;
while (cameraId < numCameras) { while (cameraId < numCameras) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, cameraInfo); Camera.getCameraInfo(cameraId, cameraInfo);
if (CameraFacing.values()[cameraInfo.facing] == CameraFacing.BACK) { if (CameraFacing.values()[cameraInfo.facing] == CameraFacing.BACK) {
break; break;

View File

@@ -1,7 +1,7 @@
//App //App
def app_version = [:] def app_version = [:]
app_version.versionCode = 26 app_version.versionCode = 27
app_version.versionName = "1.1.9-androidx" app_version.versionName = "2.0.0-beta1"
ext.app_version = app_version ext.app_version = app_version
//build version //build version
@@ -28,7 +28,7 @@ versions.runner = "1.2.0"
versions.espresso = "3.2.0" versions.espresso = "3.2.0"
//zxing //zxing
versions.zxing = "3.3.3" versions.zxing = "3.4.0"
versions.easypermissions = "3.0.0" versions.easypermissions = "3.0.0"