From 5308d04e20f3dca6d56ccc3e2b460374540716a6 Mon Sep 17 00:00:00 2001
From: wjc <1243177876@qq.com>
Date: 星期二, 06 六月 2023 18:20:13 +0800
Subject: [PATCH] 2023年06月06日18:19:36
---
third-zxing/src/main/res/values/styles.xml | 24
third-zxing/src/main/java/com/zxing/camera/CameraManager.java | 195 ++
third-zxing/src/main/java/com/zxing/camera/CameraConfigurationManager.java | 207 +++
app/src/main/res/drawable/fast_scan_light_close.png | 0
third-zxing/.gitignore | 1
third-zxing/src/main/java/com/zxing/decode/DecodeHandler.java | 136 ++
third-zxing/src/main/java/com/zxing/qrcode/CaptureActivity.java | 398 +++++
third-zxing/src/main/res/drawable/transparent_divider.xml | 5
third-zxing/src/main/res/values/strings.xml | 13
third-zxing/src/main/java/com/zxing/camera/PreviewCallback.java | 40
third-zxing/src/main/java/com/zxing/Extras.java | 34
.idea/misc.xml | 19
third-zxing/libs/zxing_3.3.0.jar | 0
third-zxing/src/main/res/values/ids.xml | 9
app/src/main/res/drawable/fast_scan_light_open.png | 0
third-zxing/src/main/java/com/zxing/ContextHelper.java | 131 +
third-zxing/src/main/res/drawable/fast_scan_light_open.png | 0
third-zxing/src/main/res/drawable-xxhdpi/scan_line.png | 0
third-zxing/src/main/res/raw/beep.ogg | 0
app/build.gradle | 3
third-zxing/build.gradle | 45
app/src/main/res/values/strings.xml | 1
third-zxing/src/main/java/com/zxing/utils/CaptureActivityHandler.java | 95 +
third-zxing/src/main/java/com/zxing/utils/Validator.java | 202 +++
third-zxing/src/main/res/drawable/fast_scan_light_close.png | 0
third-zxing/src/main/res/drawable/back.png | 0
third-zxing/src/main/java/com/zxing/DeviceHelper.java | 469 +++++++
third-zxing/src/main/java/com/zxing/utils/ZXingBitmapUtils.java | 333 ++++
third-zxing/src/main/java/com/zxing/utils/BeepManager.java | 125 +
third-zxing/src/main/java/com/zxing/camera/AutoFocusManager.java | 114 +
third-zxing/src/main/java/com/zxing/decode/RGBLuminanceSource.java | 72 +
third-zxing/src/main/res/values/colors_ui.xml | 33
app/src/main/res/values/colors.xml | 3
app/src/main/res/layout/toolbar_top_view_52.xml | 1
third-zxing/src/main/java/com/zxing/IZxingActivity.java | 28
app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java | 415 ++++++
third-zxing/src/main/java/com/zxing/utils/InactivityTimer.java | 108 +
settings.gradle | 1
third-zxing/src/main/java/com/zxing/decode/DecodeFormatManager.java | 37
app/src/main/res/layout/activity_fast_scan.xml | 109 +
third-zxing/src/main/res/layout/activity_capture.xml | 117 +
third-zxing/src/main/java/com/zxing/utils/Strings.java | 179 ++
app/src/main/AndroidManifest.xml | 15
third-zxing/src/main/AndroidManifest.xml | 14
gradle.properties | 4
third-zxing/src/main/res/drawable-xxhdpi/ic_shadow.png | 0
app/src/main/res/drawable/back.png | 0
third-zxing/proguard-rules.pro | 25
third-zxing/src/main/res/drawable-xxhdpi/scan_capture.9.png | 0
third-zxing/src/main/java/com/zxing/decode/DecodeThread.java | 82 +
app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java | 1
third-zxing/src/main/java/com/zxing/camera/open/OpenCameraInterface.java | 69 +
third-zxing/src/main/res/layout/toolbar.xml | 34
app/src/main/java/com/hdl/photovoltaic/base/BaseFragment.java | 6
app/src/main/java/com/hdl/photovoltaic/ui/powerstation/HouseListFragment.java | 16
55 files changed, 3,939 insertions(+), 29 deletions(-)
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 2a2e4cc..613a21b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,7 +3,26 @@
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
+ <entry key="../../../../../layout/custom_preview.xml" value="0.22923076923076924" />
+ <entry key="../../../.gradle/caches/transforms-2/files-2.1/7c2cbaa925629e10707989293f119941/jetified-zxing-android-embedded-3.4.0/res/layout/zxing_barcode_scanner.xml" value="0.20625" />
+ <entry key="../../../.gradle/caches/transforms-2/files-2.1/7c2cbaa925629e10707989293f119941/jetified-zxing-android-embedded-3.4.0/res/layout/zxing_capture.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_1.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_123.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_capture.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_fast_scan.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_home_login.xml" value="0.20625" />
<entry key="app/src/main/res/layout/activity_my_power_station.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/activity_new_capture.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/fragment_house_list.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/fragment_me.xml" value="0.1" />
+ <entry key="app/src/main/res/layout/frgment_house_list_line.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/toolbar_top_view_52.xml" value="0.20625" />
+ <entry key="app/src/main/res/layout/toolbar_top_view_53.xml" value="0.20625" />
+ <entry key="third-zxing/src/main/res/drawable/transparent_divider.xml" value="0.1275" />
+ <entry key="third-zxing/src/main/res/layout/activity_capture.xml" value="0.20625" />
+ <entry key="third-zxing/src/main/res/layout/toolbar.xml" value="0.20625" />
+ <entry key="third-zxing/src/main/res/layout/toolbar_top_view.xml" value="0.20625" />
+ <entry key="third-zxing/src/main/res/layout/toolbar_top_view_52.xml" value="0.20625" />
</map>
</option>
</component>
diff --git a/app/build.gradle b/app/build.gradle
index 2c43ce4..f2ec162 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -39,8 +39,11 @@
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation project(path: ':third-zxing')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'org.greenrobot:eventbus:3.0.0'
+
+
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 09168e4..85db82f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.hdl.photovoltaic">
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.hdl.photovoltaic" >
+
+ <uses-permission
+ android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
+ tools:ignore="ProtectedPermissions" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".HDLApp"
@@ -9,7 +18,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/Theme.PhotovoltaicDebug">
+ android:theme="@style/Theme.PhotovoltaicDebug" >
<activity
android:name=".ui.device.FastScanActivity"
android:exported="false" />
@@ -21,7 +30,7 @@
android:exported="false" />
<activity
android:name=".ui.StartActivity"
- android:exported="true">
+ android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/app/src/main/java/com/hdl/photovoltaic/base/BaseFragment.java b/app/src/main/java/com/hdl/photovoltaic/base/BaseFragment.java
index 4a88c53..5598bea 100644
--- a/app/src/main/java/com/hdl/photovoltaic/base/BaseFragment.java
+++ b/app/src/main/java/com/hdl/photovoltaic/base/BaseFragment.java
@@ -123,7 +123,7 @@
/**
* 鏄剧ずView
*
- * @param view
+ * @param view -
*/
public void setViewVisible(View view) {
if (view.getVisibility() != View.VISIBLE && _mActivity != null) {
@@ -134,7 +134,7 @@
/**
* 闅愯棌View
*
- * @param view
+ * @param view -
*/
protected void setViewGone(View view) {
if (view.getVisibility() != View.GONE && _mActivity != null) {
@@ -145,7 +145,7 @@
/**
* 绠�鍗曠殑璺宠浆Activity
*
- * @param clazz
+ * @param clazz -
*/
protected void startActivity(Class<?> clazz) {
if (_mActivity != null) {
diff --git a/app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java b/app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java
index b82cea7..77d9ac2 100644
--- a/app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java
+++ b/app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java
@@ -58,7 +58,6 @@
private void bottomViewChangeOfStyle() {
if (this.currentFragmentIndex == 0) {
-
viewBinding.myPowerStationFcv1.setVisibility(View.VISIBLE);
viewBinding.myPowerStationFcv2.setVisibility(View.GONE);
viewBinding.myPowerStationBottomIl1.iconIv.setImageDrawable(AppCompatResources.getDrawable(_mActivity, R.drawable.selectedpowerstation));
diff --git a/app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java b/app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java
index 7c31db8..93ddc2f 100644
--- a/app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java
+++ b/app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java
@@ -1,17 +1,78 @@
package com.hdl.photovoltaic.ui.device;
-import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.content.res.AppCompatResources;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Rect;
+import android.hardware.Camera;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.provider.MediaStore;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.Toast;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.ChecksumException;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.FormatException;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.QRCodeReader;
import com.hdl.photovoltaic.R;
import com.hdl.photovoltaic.base.CustomBaseActivity;
import com.hdl.photovoltaic.databinding.ActivityFastScanBinding;
+import com.zxing.IZxingActivity;
+import com.zxing.camera.CameraManager;
+import com.zxing.decode.DecodeThread;
+import com.zxing.decode.RGBLuminanceSource;
+import com.zxing.utils.BeepManager;
+import com.zxing.utils.CaptureActivityHandler;
+import com.zxing.utils.InactivityTimer;
-public class FastScanActivity extends CustomBaseActivity {
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Hashtable;
-
+public class FastScanActivity extends CustomBaseActivity implements IZxingActivity, SurfaceHolder.Callback {
+ private static final String TAG = com.zxing.qrcode.CaptureActivity.class.getSimpleName();
+ private final int REQUEST_CODE = 33;
+ private CameraManager cameraManager;
+ private CaptureActivityHandler handler;
+ private InactivityTimer inactivityTimer;
+ private BeepManager beepManager;
+ private SurfaceView scanPreview = null;
+ private RelativeLayout scanContainer;
+ private RelativeLayout scanCropView;
+ private Rect mCropRect = null;
+ private boolean isHasSurface = false;
private ActivityFastScanBinding viewBinding;
+
+ @Override
+ public Handler getHandler() {
+ return handler;
+ }
+
+ @Override
+ public void drawViewfinder() {
+
+ }
+
+ @Override
+ public CameraManager getCameraManager() {
+ return cameraManager;
+ }
@Override
public Object getContentView() {
@@ -21,6 +82,352 @@
@Override
public void onBindView(Bundle savedInstanceState) {
+// Window window = getWindow();
+// window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+// //璁剧疆鏍硅鍥�
+// View mContentView = LayoutInflater.from(this).inflate(R.layout.activity_new_capture, null);
+// setContentView(mContentView);
+ //鍒濆鍖�
+ initView(savedInstanceState);
+ //鍒濆鍖栫晫闈㈢洃鍚櫒
+ initEvent();
+ }
+
+
+ private void initView(Bundle savedInstanceState) {
+
+
+ scanPreview = findViewById(R.id.new_capture_preview);
+ scanContainer = findViewById(R.id.new_capture_rl);
+ scanCropView = findViewById(R.id.new_capture_crop_view);
+ ImageView scanLine = findViewById(R.id.new_capture_scan_line);
+ inactivityTimer = new InactivityTimer(this);
+ beepManager = new BeepManager(this);
+
+ TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation
+ .RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
+ 0.9f);
+ animation.setDuration(2000);
+ animation.setRepeatCount(-1);
+ animation.setRepeatMode(Animation.RESTART);
+ scanLine.startAnimation(animation);
+ }
+
+ private void initEvent() {
+ viewBinding.newTopBackBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ viewBinding.newTopMoreBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //璺冲埌鍏ョ綉
+ }
+ });
+
+ viewBinding.newLightIv.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ v.setSelected(!v.isSelected());
+ if (v.isSelected()) {
+ viewBinding.newLightIv.setImageDrawable(AppCompatResources.getDrawable(FastScanActivity.this, com.zxing.R.drawable.fast_scan_light_open));
+ } else {
+ viewBinding.newLightIv.setImageDrawable(AppCompatResources.getDrawable(FastScanActivity.this, com.zxing.R.drawable.fast_scan_light_close));
+ }
+ flashLightOnOrOff();
+
+ }
+ });
+ }
+
+
+ public void enterGallery() {
+ // 杩涘叆鍥惧簱
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("image/*");
+ intent.putExtra("return-data", true);
+ startActivityForResult(intent, REQUEST_CODE);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ cameraManager = new CameraManager(getApplication());
+ handler = null;
+ if (isHasSurface) {
+ initCamera(scanPreview.getHolder());
+ } else {
+ scanPreview.getHolder().addCallback(this);
+ }
+
+ inactivityTimer.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ if (handler != null) {
+ handler.quitSynchronously();
+ handler = null;
+ }
+ inactivityTimer.onPause();
+ beepManager.close();
+ cameraManager.closeDriver();
+ if (!isHasSurface) {
+ scanPreview.getHolder().removeCallback(this);
+ }
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ inactivityTimer.shutdown();
+ super.onDestroy();
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (holder == null) {
+ Log.d(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+ }
+ if (!isHasSurface) {
+ isHasSurface = true;
+ initCamera(holder);
+ }
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ isHasSurface = false;
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
-}
\ No newline at end of file
+
+ /**
+ * A valid barcode has been found, so give an indication of success and show
+ * the results.
+ *
+ * @param rawResult The contents of the barcode.
+ * @param bundle The extras
+ */
+ @Override
+ public void handleDecode(Result rawResult, Bundle bundle) {
+ inactivityTimer.onActivity();
+ beepManager.playBeepSoundAndVibrate();
+ doProcess(rawResult.getText());
+ restartPreviewAfterDelay(3000);
+ }
+
+ private void initCamera(SurfaceHolder surfaceHolder) {
+ if (surfaceHolder == null) {
+ throw new IllegalStateException("No SurfaceHolder provided");
+ }
+ if (cameraManager.isOpen()) {
+ Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
+ return;
+ }
+ try {
+ cameraManager.openDriver(surfaceHolder);
+ // Creating the handler starts the preview, which can also throw a
+ // RuntimeException.
+ if (handler == null) {
+ handler = new CaptureActivityHandler(this, cameraManager, DecodeThread.ALL_MODE);
+ }
+
+ initCrop();
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ Toast.makeText(this, com.zxing.R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
+ finish();
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Unexpected error initializing camera", e);
+ Toast.makeText(this, com.zxing.R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ }
+
+ public void restartPreviewAfterDelay(long delayMS) {
+ if (handler != null) {
+ handler.sendEmptyMessageDelayed(com.zxing.R.id.restart_preview, delayMS);
+ }
+ }
+
+ @Override
+ public Rect getCropRect() {
+ return mCropRect;
+ }
+
+ /**
+ * 鍒濆鍖栨埅鍙栫殑鐭╁舰鍖哄煙
+ */
+ private void initCrop() {
+ int cameraWidth = cameraManager.getCameraResolution().y;
+ int cameraHeight = cameraManager.getCameraResolution().x;
+
+ /** 鑾峰彇甯冨眬涓壂鎻忔鐨勪綅缃俊鎭� */
+ int[] location = new int[2];
+ scanCropView.getLocationInWindow(location);
+
+ int cropLeft = location[0];
+ int cropTop = location[1] - getStatusBarHeight();
+
+ int cropWidth = scanCropView.getWidth();
+ int cropHeight = scanCropView.getHeight();
+
+ /** 鑾峰彇甯冨眬瀹瑰櫒鐨勫楂� */
+ int containerWidth = scanContainer.getWidth();
+ int containerHeight = scanContainer.getHeight();
+
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫乏涓婅椤剁偣x鍧愭爣 */
+ int x = cropLeft * cameraWidth / containerWidth;
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫乏涓婅椤剁偣y鍧愭爣 */
+ int y = cropTop * cameraHeight / containerHeight;
+
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫搴� */
+ int width = cropWidth * cameraWidth / containerWidth;
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勯珮搴� */
+ int height = cropHeight * cameraHeight / containerHeight;
+
+ /** 鐢熸垚鏈�缁堢殑鎴彇鐨勭煩褰� */
+ mCropRect = new Rect(x, y, width + x, height + y);
+ }
+
+ private int getStatusBarHeight() {
+ try {
+ Class<?> c = Class.forName("com.android.internal.R$dimen");
+ Object obj = c.newInstance();
+ Field field = c.getField("status_bar_height");
+ int x = Integer.parseInt(field.get(obj).toString());
+ return getResources().getDimensionPixelSize(x);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ private void doProcess(String result) {
+ Log.d("panlili", "scanResult: " + result);
+ /*if (!DeviceHelper.getNetworkState()) {
+ Toast.makeText(this, R.string.capture_no_network, Toast.LENGTH_SHORT).show();
+ return;
+ }*/
+
+ if (TextUtils.isEmpty(result)) {
+ Toast.makeText(this, com.zxing.R.string.capture_no_result, Toast.LENGTH_SHORT).show();
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("data", result);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
+ Uri originalUri = data.getData();
+ if (originalUri != null) {
+ String path = originalUri.getPath();
+ String[] proj = {MediaStore.Images.Media.DATA};
+ Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null);
+ if (cursor != null) {
+ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ path = cursor.getString(column_index);
+ cursor.close();
+ }
+
+ if (!TextUtils.isEmpty(path)) {
+ handleQRCodeFormPhoto(path);
+ } else {
+ Toast.makeText(this, "鍥剧墖宸叉崯鍧忥紝璇烽噸鏂伴�夋嫨锛�", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ }
+
+ /**
+ * 瑙f瀽鍥惧簱閫夋嫨鐨勪簩缁寸爜
+ */
+ public void handleQRCodeFormPhoto(final String filePath) {
+ Thread dealThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Hashtable<DecodeHintType, String> hints = new Hashtable<>();
+ hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
+ RGBLuminanceSource source = null;
+ try {
+ source = new RGBLuminanceSource(filePath);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
+ QRCodeReader reader = new QRCodeReader();
+ Result result;
+ try {
+ result = reader.decode(binaryBitmap, hints);
+ if (!TextUtils.isEmpty(result.getText())) {
+ dealUIInfo(result.getText());
+ } else {
+ dealUIInfo(null);
+ }
+ } catch (NotFoundException | ChecksumException | FormatException e) {
+ dealUIInfo(null);
+ e.printStackTrace();
+ }
+ }
+ });
+ dealThread.start();
+ }
+
+ private void dealUIInfo(final Object progressInfo) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (progressInfo == null) {
+ Toast.makeText(FastScanActivity.this, com.zxing.R.string.capture_no_result2, Toast.LENGTH_SHORT).show();
+ } else {
+ doProcess(progressInfo.toString());
+ }
+ }
+ });
+ }
+
+
+ /**
+ * 闂厜鐏紑鍚垨鑰呭叧闂�
+ */
+ private void flashLightOnOrOff() {
+//
+ android.hardware.Camera camera = cameraManager.getCamera();
+ if (camera == null) {
+ return;
+ }
+ android.hardware.Camera.Parameters parameters = camera.getParameters();
+// 鍒ゆ柇闂厜鐏綋鍓嶇姸鎬�
+ if (Camera.Parameters.FLASH_MODE_OFF.equals(parameters.getFlashMode())) {
+ onLight(camera, parameters);
+ } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(parameters.getFlashMode())) {
+ offLight(camera, parameters);
+ }
+ }
+
+ private void onLight(android.hardware.Camera camera, Camera.Parameters parameters) {
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
+ camera.setParameters(parameters);
+ }
+
+ private void offLight(android.hardware.Camera camera, Camera.Parameters parameters) {
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ camera.setParameters(parameters);
+ }
+
+
+}
diff --git a/app/src/main/java/com/hdl/photovoltaic/ui/powerstation/HouseListFragment.java b/app/src/main/java/com/hdl/photovoltaic/ui/powerstation/HouseListFragment.java
index 346bf75..55b887a 100644
--- a/app/src/main/java/com/hdl/photovoltaic/ui/powerstation/HouseListFragment.java
+++ b/app/src/main/java/com/hdl/photovoltaic/ui/powerstation/HouseListFragment.java
@@ -1,6 +1,7 @@
package com.hdl.photovoltaic.ui.powerstation;
import android.content.Context;
+import android.content.Intent;
import android.hardware.camera2.CameraManager;
import android.os.Bundle;
import android.util.Log;
@@ -14,6 +15,7 @@
import com.hdl.photovoltaic.base.CustomBaseFragment;
import com.hdl.photovoltaic.ui.adapter.HouseInfoAdapter;
import com.hdl.photovoltaic.ui.bean.HouseInfoBean;
+import com.hdl.photovoltaic.ui.device.FastScanActivity;
import com.hdl.photovoltaic.utils.FlashLightUtils;
import java.util.ArrayList;
@@ -22,7 +24,6 @@
public class HouseListFragment extends CustomBaseFragment {
private FragmentHouseListBinding viewBinding;
private HouseInfoAdapter houseInfoAdapter;
- private FlashLightUtils flashLightUtils;
private CameraManager manager;
private List<HouseInfoBean> houseInfoBeanList = null;
@@ -35,7 +36,6 @@
@Override
public void onBindView(Bundle savedInstanceState) {
- flashLightUtils = new FlashLightUtils(_mActivity);
manager = (CameraManager) _mActivity.getSystemService(Context.CAMERA_SERVICE);
initData();
@@ -49,12 +49,12 @@
private void initEvent() {
-
-
viewBinding.toolbarTopFragmentHouseListRl.topMoreIv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
-
+ Intent intent = new Intent();
+ intent.setClass(_mActivity, FastScanActivity.class);
+ startActivity(intent);
}
});
//璁剧疆涓嬫媺绠ご棰滆壊
@@ -73,7 +73,6 @@
viewBinding.toolbarTopFragmentHouseListRl.topTitleTv.setText(R.string.my_power_station_鎴戠殑鐢电珯);
viewBinding.toolbarTopFragmentHouseListRl.topMoreIv.setVisibility(View.VISIBLE);
viewBinding.toolbarTopFragmentHouseListRl.topMoreIv.setImageResource(R.drawable.add);
-
LinearLayoutManager linearLayout = new LinearLayoutManager(_mActivity);
houseInfoAdapter = new HouseInfoAdapter(this.houseInfoBeanList);
viewBinding.fragmentHouseSrlListRc.setLayoutManager(linearLayout);
@@ -89,11 +88,6 @@
houseInfoBean.setName("鐢电珯" + i);
this.houseInfoBeanList.add(houseInfoBean);
}
-
-
- }
-
- private void openCamera() {
}
diff --git a/app/src/main/res/drawable/back.png b/app/src/main/res/drawable/back.png
new file mode 100644
index 0000000..64507b9
--- /dev/null
+++ b/app/src/main/res/drawable/back.png
Binary files differ
diff --git a/app/src/main/res/drawable/fast_scan_light_close.png b/app/src/main/res/drawable/fast_scan_light_close.png
new file mode 100644
index 0000000..56f42cf
--- /dev/null
+++ b/app/src/main/res/drawable/fast_scan_light_close.png
Binary files differ
diff --git a/app/src/main/res/drawable/fast_scan_light_open.png b/app/src/main/res/drawable/fast_scan_light_open.png
new file mode 100644
index 0000000..454e02f
--- /dev/null
+++ b/app/src/main/res/drawable/fast_scan_light_open.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_fast_scan.xml b/app/src/main/res/layout/activity_fast_scan.xml
index ce5b771..66cbe7f 100644
--- a/app/src/main/res/layout/activity_fast_scan.xml
+++ b/app/src/main/res/layout/activity_fast_scan.xml
@@ -1,9 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/new_capture_rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".ui.device.FastScanActivity">
+ android:background="#636363">
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+ <RelativeLayout
+ android:id="@+id/new_top_bar_view"
+ android:layout_width="match_parent"
+ android:layout_height="52dp"
+ android:background="#245EC3"
+ android:orientation="horizontal">
+
+ <!--1.杩斿洖鎸夐挳 澧炲ぇ鐐瑰嚮鍖哄煙-->
+ <LinearLayout
+ android:id="@+id/new_top_back_btn"
+ android:layout_width="56dp"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="center"
+ android:layout_marginLeft="16dp"
+ android:scaleType="centerInside"
+ android:src="@drawable/back" />
+ </LinearLayout>
+
+ <!--2.鏍囬鏂囨湰-->
+ <TextView
+ android:id="@+id/new_top_title_tv"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:layout_marginLeft="60dp"
+ android:layout_marginRight="60dp"
+ android:fontFamily="sans-serif-medium"
+ android:gravity="center"
+ android:maxLines="1"
+ android:text="蹇�熸壂鐮�"
+ android:textColor="#FFFFFFFF"
+ android:textSize="18sp" />
+
+ <!--3.鏇村鎸夐挳 榛樿闅愯棌-->
+ <LinearLayout
+ android:id="@+id/new_top_more_btn"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentEnd="true"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/new_top_connect_tv"
+ android:layout_width="wrap_content"
+ android:layout_height="20dp"
+ android:layout_marginEnd="20dp"
+ android:text="@string/device_鎵嬪姩杩炴帴"
+ android:textColor="@color/text_FFFFFFFF"
+ android:textSize="@dimen/text_14" />
+
+ </LinearLayout>
+
+ </RelativeLayout>
+
+ <SurfaceView
+ android:id="@+id/new_capture_preview"
+ android:layout_width="367dp"
+ android:layout_height="367dp"
+ android:layout_centerInParent="true" />
+
+ <RelativeLayout
+ android:id="@+id/new_capture_crop_view"
+ android:layout_width="367dp"
+ android:layout_height="367dp"
+ android:layout_centerInParent="true"
+ android:background="@drawable/scan_capture">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="367dp"
+ android:layout_marginTop="182dp">
+
+ <ImageView
+ android:id="@+id/new_capture_scan_line"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="5dp"
+ android:src="@drawable/scan_line" />
+ </RelativeLayout>
+
+ </RelativeLayout>
+
+ <ImageView
+ android:id="@+id/new_light_iv"
+ android:layout_width="127dp"
+ android:layout_height="127dp"
+ android:layout_alignParentBottom="true"
+ android:layout_centerInParent="true"
+ android:layout_marginBottom="13dp"
+ android:background="@drawable/fast_scan_light_close" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar_top_view_52.xml b/app/src/main/res/layout/toolbar_top_view_52.xml
index 02e2249..2ce085a 100644
--- a/app/src/main/res/layout/toolbar_top_view_52.xml
+++ b/app/src/main/res/layout/toolbar_top_view_52.xml
@@ -57,6 +57,7 @@
android:scaleType="centerInside"
android:visibility="gone" />
+
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 05de233..864d506 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -29,6 +29,7 @@
<color name="text_06B92A">#06B92A</color>
<color name="text_F9FAFB">#F9FAFB</color>
<color name="text_CBCDD1">#CBCDD1</color>/
- <color name="text_FF245EC3">#FF245EC3</color>
+ <color name="text_FF245EC3">#FF245EC3</color>#
+ <color name="text_636363">#636363</color>
</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2bd4d75..750d136 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -42,6 +42,7 @@
<string name="my_power_station_绂荤嚎">绂荤嚎</string>
<string name="my_power_station_鏁呴殰">鏁呴殰</string>
<string name="my_power_station_杩愯">杩愯</string>
+ <string name="device_鎵嬪姩杩炴帴">鎵嬪姩杩炴帴</string>
<!--鎴戠殑-->
diff --git a/gradle.properties b/gradle.properties
index dab7c28..98aeb05 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,4 +18,6 @@
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+# 鍙互灏唙4,v7搴撹浆鎴怉ndroid X
+android.enableJetifier=true
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index d2a636d..c8e8029 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,3 @@
rootProject.name = "PhotovoltaicDebug"
include ':app'
+include ':third-zxing'
diff --git a/third-zxing/.gitignore b/third-zxing/.gitignore
new file mode 100644
index 0000000..3543521
--- /dev/null
+++ b/third-zxing/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/third-zxing/build.gradle b/third-zxing/build.gradle
new file mode 100644
index 0000000..fd81dd7
--- /dev/null
+++ b/third-zxing/build.gradle
@@ -0,0 +1,45 @@
+apply plugin: 'com.android.library'
+
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.1"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [moduleName: project.getName()]
+ }
+ }
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ android {
+ lintOptions {
+ abortOnError false
+ }
+ }
+}
+
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+// compileOnly fileTree(include: ['*.jar'], dir: 'libs')
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ testImplementation 'junit:junit:4.12'
+ implementation 'com.android.support:support-annotations:28.0.0'
+// api 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+}
diff --git a/third-zxing/libs/zxing_3.3.0.jar b/third-zxing/libs/zxing_3.3.0.jar
new file mode 100644
index 0000000..94f7406
--- /dev/null
+++ b/third-zxing/libs/zxing_3.3.0.jar
Binary files differ
diff --git a/third-zxing/proguard-rules.pro b/third-zxing/proguard-rules.pro
new file mode 100644
index 0000000..48f7715
--- /dev/null
+++ b/third-zxing/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/ye/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/third-zxing/src/main/AndroidManifest.xml b/third-zxing/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..bd46698
--- /dev/null
+++ b/third-zxing/src/main/AndroidManifest.xml
@@ -0,0 +1,14 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.zxing">
+
+ <application >
+
+ <activity
+ android:name=".qrcode.CaptureActivity"
+ android:configChanges="orientation|keyboardHidden|screenSize|locale"
+ android:exported="false"
+ android:screenOrientation="portrait"
+ android:theme="@style/AppTheme.Base"/>
+ </application>
+
+</manifest>
diff --git a/third-zxing/src/main/java/com/zxing/ContextHelper.java b/third-zxing/src/main/java/com/zxing/ContextHelper.java
new file mode 100644
index 0000000..9975547
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/ContextHelper.java
@@ -0,0 +1,131 @@
+package com.zxing;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Build;
+
+import com.zxing.utils.Strings;
+
+public final class ContextHelper {
+
+ private static Application application;
+ private static Class splashCls;
+
+ /**
+ * 鍒濆鍖�
+ *
+ * @param application app
+ */
+ public static void init(Application application) {
+ if (ContextHelper.application == null) {
+ ContextHelper.application = application;
+ }
+ }
+
+ public static Context getAppContext() {
+ if (application != null) {
+ return application.getApplicationContext();
+ }
+ return null;
+ }
+
+ public static Application getApp() {
+ return application;
+ }
+
+ public static Resources getResources() {
+ Context context = getAppContext();
+ if (context != null) {
+ return context.getResources();
+ }
+ return null;
+ }
+
+ public static void setSplashCls(Class cls) {
+ ContextHelper.splashCls = cls;
+ }
+
+ public static Class getSplashCls() {
+ return splashCls;
+ }
+
+ /**
+ * 璧勬簮ID鑾峰彇String
+ */
+ public static String getString(int stringId) {
+ if (getAppContext() == null) {
+ return Strings.EMPTY;
+ }
+ return getAppContext().getString(stringId);
+ }
+
+ public static String getString(int stringId, Object... formatArgs) {
+ if (getAppContext() == null) {
+ return Strings.EMPTY;
+ }
+ return getAppContext().getString(stringId, formatArgs);
+ }
+
+
+ public static int getDimensionPixelSize(int dimenId) {
+ try {
+ return getResources().getDimensionPixelSize(dimenId);
+ } catch (Resources.NotFoundException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ public static int getDimen(int dimenId) {
+ try {
+ return getResources().getDimensionPixelSize(dimenId);
+ } catch (Resources.NotFoundException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 鑾峰彇搴旂敤鐨勭増鏈彿
+ */
+ public static String getAppVersion() {
+ Context context = getAppContext();
+ if (context != null) {
+ PackageManager packageManager = context.getPackageManager();
+ PackageInfo packageInfo;
+ try {
+ packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
+ return packageInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return Strings.EMPTY;
+ }
+
+ public static boolean isUsable(Context context) {
+ if (context == null) {
+ return false;
+ }
+
+ if (context instanceof Activity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ return !((Activity) context).isDestroyed();
+ }
+ return true;
+ }
+
+ public static void startAppSetting(){
+ if(getAppContext()!=null) {
+ Intent intent = new Intent("android.settings.SETTINGS");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ getAppContext().startActivity(intent);
+ }
+ }
+
+}
+
diff --git a/third-zxing/src/main/java/com/zxing/DeviceHelper.java b/third-zxing/src/main/java/com/zxing/DeviceHelper.java
new file mode 100644
index 0000000..adb06bb
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/DeviceHelper.java
@@ -0,0 +1,469 @@
+package com.zxing;
+
+import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.os.StatFs;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+
+import com.zxing.utils.Strings;
+import com.zxing.utils.Validator;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.List;
+import java.util.Locale;
+
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
+
+/**
+ * 鐢ㄩ�旓細鍙栬澶囩浉鍏充俊鎭�
+ */
+public class DeviceHelper {
+
+ /**
+ * 鑾峰彇搴旂敤鐨勭増鏈彿
+ */
+ public static String getAppVersion() {
+ Context context = ContextHelper.getAppContext();
+ if (context != null) {
+ PackageManager packageManager = context.getPackageManager();
+ PackageInfo packageInfo;
+ try {
+ packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
+ return packageInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return Strings.EMPTY;
+ }
+
+ public static void ClipData(String content) {
+ ClipboardManager cm = (ClipboardManager) ContextHelper.getAppContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ // 灏嗘枃鏈唴瀹规斁鍒扮郴缁熷壀璐存澘閲屻��
+ if (cm != null) {
+ cm.setText(content);
+ }
+ }
+
+ /**
+ * 鍚姩搴旂敤鐨勮缃�
+ */
+ public static void startAppSettings(Activity activity, int requestCode) {
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
+ intent.setData(uri);
+ activity.startActivityForResult(intent, requestCode);
+ }
+
+ /**
+ * 鑾峰彇鐗堟湰淇℃伅 versioncode
+ */
+ public static int getVersionCode() {
+ final Context context = ContextHelper.getAppContext();
+ int version = 1;
+ if (context != null) {
+ PackageManager packageManager = context.getPackageManager();
+ PackageInfo packInfo = null;
+ try {
+ packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ if (packInfo != null) {
+ version = packInfo.versionCode;
+ }
+ }
+ return version;
+ }
+
+ /**
+ * 鑾峰彇璁惧鐨勫埗閫犲晢
+ */
+ public static String getFactory() {
+ return Build.MANUFACTURER;
+ }
+
+ /**
+ * 鑾峰彇绯荤粺鐗堟湰鍙�
+ */
+ public static String getPhoneOS() {
+ return "Android " + getSysVersion() + " " + Build.VERSION.RELEASE;
+ }
+
+ /**
+ * 鐗堟湰鏄惁鍦ˋndroid6.0 浠ヤ笂
+ */
+ public static boolean isOverMarshmallow() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
+ }
+
+ /**
+ * 鑾峰彇Android API鐗堟湰
+ */
+ public static String getSysVersion() {
+ return Build.VERSION.SDK_INT + Strings.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇Android API鐗堟湰
+ */
+ public static int getSysVersionInt() {
+ return Build.VERSION.SDK_INT;
+ }
+
+ /**
+ * 鑾峰彇鎵嬫満鍨嬪彿
+ */
+ public static String getPhoneModel() {
+ String model = Build.BRAND + " " + Build.MODEL;
+ if (!TextUtils.isEmpty(model) && model.length() > 50) {
+ model = model.substring(0, 49);
+ }
+ return Validator.replaceHanzi(model);
+ }
+
+ /**
+ * 鍒ゆ柇IMEI鏄惁涓虹函鏁板瓧涓�
+ */
+ private static boolean isNumber(String str) {
+ if (TextUtils.isEmpty(str)) {
+ return false;
+ }
+ boolean isNumber = true;
+ int i;
+ char c;
+ for (i = 0; i < str.length(); i++) {
+ c = str.charAt(i);
+ if (!((c >= '0') && (c <= '9')) || "000000000000000".equals(str) || "0".equals(str)) {
+ isNumber = false;
+ break;
+ }
+ }
+ return isNumber;
+ }
+
+ private static String loadFileAsString(String fileName) throws Exception {
+ FileReader reader = new FileReader(fileName);
+ String text = loadReaderAsString(reader);
+ reader.close();
+ return text;
+ }
+
+ private static String loadReaderAsString(Reader reader) throws Exception {
+ StringBuilder builder = new StringBuilder();
+ char[] buffer = new char[4096];
+ int readLength = reader.read(buffer);
+ while (readLength >= 0) {
+ builder.append(buffer, 0, readLength);
+ readLength = reader.read(buffer);
+ }
+ return builder.toString();
+ }
+
+ /**
+ * 鍒ゆ柇mac鍦板潃鏄惁鍚堟硶
+ */
+ private static boolean isCorrectMacAddress(String address) {
+ boolean flag = false;
+ if (!TextUtils.isEmpty(address) && address.length() == 17) {
+ address = address.replaceAll(":", Strings.EMPTY);
+ flag = isHex(address);
+ }
+ return flag;
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓虹函16杩涘埗鏁板瓧涓�
+ */
+ private static boolean isHex(String str) {
+ boolean isHexFlg = true;
+ int i;
+ char c;
+ for (i = 0; i < str.length(); i++) {
+ c = str.charAt(i);
+ if (!(((c >= '0') && (c <= '9')) ||
+ ((c >= 'A') && (c <= 'F')) ||
+ (c >= 'a') && (c <= 'f'))) {
+ isHexFlg = false;
+ break;
+ }
+ }
+ return isHexFlg;
+ }
+
+ /**
+ * 鍒ゆ柇绯荤粺涓槸鍚﹀瓨鍦ㄥ彲浠ュ惎鍔ㄧ殑鐩告満搴旂敤
+ *
+ * @return 瀛樺湪杩斿洖true锛屼笉瀛樺湪杩斿洖false
+ */
+ public static boolean hasCamera(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ return list.size() > 0;
+ }
+
+
+ /**
+ * 妫�娴嬬郴缁熸槸鍚︿负MIUI
+ */
+ private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
+ private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
+ private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
+
+ /**
+ * 鑾峰彇娓犻亾
+ */
+ public static String getChannel() {
+ return "";
+ }
+
+ /**
+ * 鑾峰彇鎵嬫満瀹介珮
+ */
+ public static String getPhonePixels(Activity activity) {
+ if (activity != null) {
+ DisplayMetrics dm = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+ int widthPixels = dm.widthPixels;
+ int heightPixels = dm.heightPixels;
+ return widthPixels + "-" + heightPixels;
+ }
+ return "0-0";
+ }
+
+ /**
+ * x
+ * 灞忓箷瀹藉害
+ */
+ public static int getDeviceWidth(Context context) {
+ if (context != null) {
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ if (wm != null) {
+ Point p = new Point();
+ wm.getDefaultDisplay().getSize(p);
+ return p.x;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * 灞忓箷瀹藉害
+ */
+ public static int getDeviceWidth(Activity activity) {
+ if (activity != null) {
+ DisplayMetrics dm = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+ return dm.widthPixels;
+ }
+ return 0;
+ }
+
+ /**
+ * 灞忓箷楂樺害
+ */
+ public static int getDeviceHeight(Activity activity) {
+ if (activity != null) {
+ DisplayMetrics dm = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+ return dm.heightPixels;
+ }
+ return 0;
+ }
+
+
+ /**
+ * 鍒ゆ柇褰撳墠鏈夋病鏈夌綉缁滆繛鎺�
+ */
+ public static boolean getNetworkState() {
+ Context context = ContextHelper.getAppContext();
+ if (context != null) {
+ ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkinfo = manager.getActiveNetworkInfo();
+ return !(networkinfo == null || !networkinfo.isAvailable());
+ }
+ return false;
+ }
+
+ /**
+ * SD鍗℃槸鍚︽寕杞�
+ */
+ public static boolean mountedSdCard() {
+ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
+ }
+
+ /**
+ * 妫�娴嬪簲鐢ㄦ槸鍚﹀畨瑁�
+ **/
+ public static boolean isApkInstalled(String packageName) {
+ Context context = ContextHelper.getAppContext();
+ if (context != null) {
+ final PackageManager packageManager = context.getPackageManager();
+ List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
+ for (int i = 0; i < pinfo.size(); i++) {
+ if (pinfo.get(i).packageName.equalsIgnoreCase(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * 鎵撶數璇�
+ */
+ public static void callPhone(Activity activity, String phone) {
+ Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ activity.startActivity(intent);
+ }
+
+ /**
+ * 璋冪敤绯荤粺鍙戦�佺煭淇�
+ */
+ public static void sendSMSView(Activity activity, String phone, String sms) {
+ Uri smsToUri = Uri.parse("smsto:" + phone);
+ Intent sendIntent = new Intent(Intent.ACTION_SENDTO, smsToUri);
+ sendIntent.putExtra("sms_body", sms);
+ activity.startActivity(sendIntent);
+ }
+
+ private static TelephonyManager getTelManager() {
+ Context context = ContextHelper.getAppContext();
+ if (context == null) {
+ return null;
+ }
+ return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ /**
+ * 鑾峰彇ISO鍥藉鐮侊紝鐩稿綋浜庢彁渚汼IM鍗$殑鍥藉鐮�
+ */
+ public static String getSimCountryIso() {
+ if (getTelManager() != null) {
+ return getTelManager().getSimCountryIso();
+ }
+
+ return Strings.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇杩愯惀鍟嗗悕绉�
+ */
+ public static String getSimOperatorName() {
+ if (getTelManager() != null && SIM_STATE_READY == getTelManager().getSimState()) {
+ return getTelManager().getSimOperatorName();
+ }
+
+ return Strings.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇绯荤粺杩愯鍐呭瓨澶у皬 鍗曚綅KB
+ */
+ public static long getTotalMemory() {
+ String str1 = "/proc/meminfo";// 绯荤粺鍐呭瓨淇℃伅鏂囦欢
+ String str2;
+ String[] arrayOfString;
+ long initial_memory = 0;
+
+ try {
+ FileReader localFileReader = new FileReader(str1);
+ BufferedReader localBufferedReader = new BufferedReader(
+ localFileReader, 8192);
+ str2 = localBufferedReader.readLine();// 璇诲彇meminfo绗竴琛岋紝绯荤粺鎬诲唴瀛樺ぇ灏�
+ if (TextUtils.isEmpty(str2)) {
+ arrayOfString = str2.split("\\s+");
+ initial_memory = Integer.valueOf(arrayOfString[1]);// 鑾峰緱绯荤粺鎬诲唴瀛橈紝鍗曚綅鏄疜B
+ }
+ localBufferedReader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return initial_memory;// Byte杞崲涓篕B鎴栬�匨B锛屽唴瀛樺ぇ灏忚鏍煎寲
+ }
+
+ /**
+ * 璁惧璇█缂栫爜
+ */
+ public static String getLanguage() {
+ String language = Strings.EMPTY;
+ Resources resources = ContextHelper.getResources();
+ if (resources != null) {
+ Locale locale = ContextHelper.getResources().getConfiguration().locale;
+ language = locale.getLanguage();
+ }
+
+ return language;
+ }
+
+ /**
+ * 鑾峰彇鏈鸿韩鎬诲瓨鍌�(涓嶅寘鍚玈D鍗�)
+ */
+ public static long getRomMemory() {
+ long[] romInfo = new long[1];
+ File path = Environment.getDataDirectory();
+ StatFs stat = new StatFs(path.getPath());
+ long blockSize = stat.getBlockSize();
+ long totalBlocks = stat.getBlockCount();
+ //Total rom memory
+ romInfo[0] = blockSize * totalBlocks;
+ return romInfo[0];
+ }
+
+ /**
+ * 鑾峰彇CPU鏈�澶ч鐜囷紙鍗曚綅KHZ锛�
+ */
+ public static String getMaxCpuFreq() {
+ StringBuilder result = new StringBuilder(Strings.EMPTY);
+ ProcessBuilder cmd;
+ try {
+ String[] args = {"/system/bin/cat",
+ "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"};
+ cmd = new ProcessBuilder(args);
+ Process process = cmd.start();
+ InputStream in = process.getInputStream();
+ byte[] re = new byte[24];
+ while (in.read(re) != -1) {
+ result.append(new String(re));
+ }
+ in.close();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ result = new StringBuilder("N/A");
+ }
+ return result.toString().trim();
+ }
+
+ /**
+ * 鏄惁鍙栧埌鎵�鏈変俊鎭�
+ */
+ private static boolean isGetSuccess() {
+ return !TextUtils.isEmpty(getPhoneModel()) && !TextUtils.isEmpty(getFactory())
+ && !TextUtils.isEmpty(getMaxCpuFreq()) && getRomMemory() > 0 && getTotalMemory() > 0;
+ }
+}
diff --git a/third-zxing/src/main/java/com/zxing/Extras.java b/third-zxing/src/main/java/com/zxing/Extras.java
new file mode 100644
index 0000000..62090d9
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/Extras.java
@@ -0,0 +1,34 @@
+package com.zxing;
+
+/**
+ * 璺ㄦā鍧楀弬鏁板畾涔�
+ * 娉ㄦ剰锛氭绫讳粎浠呯敤浜庡瓨鏀捐法妯″潡鐨勫弬鏁帮紝妯″潡鍐呯殑鍙傛暟璇锋斁鍦ㄦā鍧楃殑constants鐞�
+ * <p>
+ *
+ */
+public interface Extras {
+
+ interface device{
+ String EXREAS_CHANNEL = "extra_channel";
+ String EXTRAS_DEVICE_DISPATCH = "extra_device_dispatch";
+ String EXTRAS_FROM_DISPATCH = "extra_from_dispatch";
+ }
+
+ interface enterprise {
+ String cropId = "extra_crop_id";
+ String appId = "extra_app_id";
+ String deptId = "extra_dept_id";
+ String CREATE_DEPT = "extra_create_dept";//缁勭粐鏋舵瀯鍒涘缓閮ㄩ棬
+ }
+
+
+ /**
+ * from
+ **/
+ interface FROM {
+ String FROM = "from";
+ String SCAN_BACK = "scan";
+ String H5_SCAN_JUMP = "scan_jump";
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/IZxingActivity.java b/third-zxing/src/main/java/com/zxing/IZxingActivity.java
new file mode 100644
index 0000000..a8b496a
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/IZxingActivity.java
@@ -0,0 +1,28 @@
+package com.zxing;
+
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+
+import com.google.zxing.Result;
+import com.zxing.camera.CameraManager;
+
+
+public interface IZxingActivity {
+ Handler getHandler();
+
+ void startActivity(Intent intent);
+
+ void setResult(int code, Intent intent);
+
+ void finish();
+
+ void drawViewfinder();
+
+ CameraManager getCameraManager();
+
+ Rect getCropRect();
+
+ void handleDecode(Result obj, Bundle bundle);
+}
diff --git a/third-zxing/src/main/java/com/zxing/camera/AutoFocusManager.java b/third-zxing/src/main/java/com/zxing/camera/AutoFocusManager.java
new file mode 100644
index 0000000..f87262a
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/camera/AutoFocusManager.java
@@ -0,0 +1,114 @@
+package com.zxing.camera;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.hardware.Camera;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.RejectedExecutionException;
+
+public class AutoFocusManager implements Camera.AutoFocusCallback {
+
+ private static final String TAG = AutoFocusManager.class.getSimpleName();
+
+ private static final long AUTO_FOCUS_INTERVAL_MS = 1800L;
+ private static final Collection<String> FOCUS_MODES_CALLING_AF;
+
+ static {
+ FOCUS_MODES_CALLING_AF = new ArrayList<String>(2);
+ FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
+ FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
+ }
+
+ private final boolean useAutoFocus;
+ private final Camera camera;
+ private boolean stopped;
+ private boolean focusing;
+ private AsyncTask<?, ?, ?> outstandingTask;
+
+ public AutoFocusManager(Context context, Camera camera) {
+ this.camera = camera;
+ String currentFocusMode = camera.getParameters().getFocusMode();
+ useAutoFocus = FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
+ Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
+ start();
+ }
+
+ @Override
+ public synchronized void onAutoFocus(boolean success, Camera theCamera) {
+ focusing = false;
+ autoFocusAgainLater();
+ }
+
+ @SuppressLint("NewApi")
+ private synchronized void autoFocusAgainLater() {
+ if (!stopped && outstandingTask == null) {
+ AutoFocusTask newTask = new AutoFocusTask();
+ try {
+ newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ outstandingTask = newTask;
+ } catch (RejectedExecutionException ree) {
+ Log.w(TAG, "Could not request auto focus", ree);
+ }
+ }
+ }
+
+ public synchronized void start() {
+ if (useAutoFocus) {
+ outstandingTask = null;
+ if (!stopped && !focusing) {
+ try {
+ camera.autoFocus(this);
+ focusing = true;
+ } catch (RuntimeException re) {
+ // Have heard RuntimeException reported in Android 4.0.x+;
+ // continue?
+ Log.w(TAG, "Unexpected exception while focusing", re);
+ // Try again later to keep cycle going
+ autoFocusAgainLater();
+ }
+ }
+ }
+ }
+
+ private synchronized void cancelOutstandingTask() {
+ if (outstandingTask != null) {
+ if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
+ outstandingTask.cancel(true);
+ }
+ outstandingTask = null;
+ }
+ }
+
+ public synchronized void stop() {
+ stopped = true;
+ if (useAutoFocus) {
+ cancelOutstandingTask();
+ // Doesn't hurt to call this even if not focusing
+ try {
+ camera.cancelAutoFocus();
+ } catch (RuntimeException re) {
+ // Have heard RuntimeException reported in Android 4.0.x+;
+ // continue?
+ Log.w(TAG, "Unexpected exception while cancelling focusing", re);
+ }
+ }
+ }
+
+ private final class AutoFocusTask extends AsyncTask<Object, Object, Object> {
+ @Override
+ protected Object doInBackground(Object... voids) {
+ try {
+ Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
+ } catch (InterruptedException e) {
+ // continue
+ }
+ start();
+ return null;
+ }
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/camera/CameraConfigurationManager.java b/third-zxing/src/main/java/com/zxing/camera/CameraConfigurationManager.java
new file mode 100644
index 0000000..e55cb14
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/camera/CameraConfigurationManager.java
@@ -0,0 +1,207 @@
+package com.zxing.camera;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * 鎻忚堪: 璇ョ被涓昏璐熻矗璁剧疆鐩告満鐨勫弬鏁颁俊鎭紝鑾峰彇鏈�浣崇殑棰勮鐣岄潰
+ */
+public final class CameraConfigurationManager {
+
+ private static final String TAG = "CameraConfiguration";
+
+ private static final int MIN_PREVIEW_PIXELS = 480 * 320;
+ private static final double MAX_ASPECT_DISTORTION = 0.15;
+
+ private final Context context;
+
+ // 灞忓箷鍒嗚鲸鐜�
+ private Point screenResolution;
+ // 鐩告満鍒嗚鲸鐜�
+ private Point cameraResolution;
+
+ public CameraConfigurationManager(Context context) {
+ this.context = context;
+ }
+
+ public void initFromCameraParameters(Camera camera) {
+ Camera.Parameters parameters = camera.getParameters();
+ WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = manager.getDefaultDisplay();
+ Point theScreenResolution = new Point();
+ theScreenResolution = getDisplaySize(display);
+
+ screenResolution = theScreenResolution;
+ Log.i(TAG, "Screen resolution: " + screenResolution);
+
+ /** 鍥犱负鎹㈡垚浜嗙珫灞忔樉绀猴紝鎵�浠ヤ笉鏇挎崲灞忓箷瀹介珮寰楀嚭鐨勯瑙堝浘鏄彉褰㈢殑 */
+ Point screenResolutionForCamera = new Point();
+ screenResolutionForCamera.x = screenResolution.x;
+ screenResolutionForCamera.y = screenResolution.y;
+
+ if (screenResolution.x < screenResolution.y) {
+ screenResolutionForCamera.x = screenResolution.y;
+ screenResolutionForCamera.y = screenResolution.x;
+ }
+
+ cameraResolution = findBestPreviewSizeValue(parameters, screenResolutionForCamera);
+ Log.i(TAG, "Camera resolution x: " + cameraResolution.x);
+ Log.i(TAG, "Camera resolution y: " + cameraResolution.y);
+ }
+
+ @SuppressWarnings("deprecation")
+ @SuppressLint("NewApi")
+ private Point getDisplaySize(final Display display) {
+ final Point point = new Point();
+ try {
+ display.getSize(point);
+ } catch (NoSuchMethodError ignore) {
+ point.x = display.getWidth();
+ point.y = display.getHeight();
+ }
+ return point;
+ }
+
+ public void setDesiredCameraParameters(Camera camera, boolean safeMode) {
+ Camera.Parameters parameters = camera.getParameters();
+
+ if (parameters == null) {
+ Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
+ return;
+ }
+
+ Log.i(TAG, "Initial camera parameters: " + parameters.flatten());
+
+ if (safeMode) {
+ Log.w(TAG, "In camera config safe mode -- most settings will not be honored");
+ }
+
+ parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
+ camera.setParameters(parameters);
+
+ Camera.Parameters afterParameters = camera.getParameters();
+ Camera.Size afterSize = afterParameters.getPreviewSize();
+ if (afterSize != null && (cameraResolution.x != afterSize.width || cameraResolution.y != afterSize
+ .height)) {
+ Log.w(TAG, "Camera said it supported preview size " + cameraResolution.x + 'x' +
+ cameraResolution.y + ", but after setting it, preview size is " + afterSize.width + 'x'
+ + afterSize.height);
+ cameraResolution.x = afterSize.width;
+ cameraResolution.y = afterSize.height;
+ }
+
+ /** 璁剧疆鐩告満棰勮涓虹珫灞� */
+ camera.setDisplayOrientation(90);
+ }
+
+ public Point getCameraResolution() {
+ return cameraResolution;
+ }
+
+ public Point getScreenResolution() {
+ return screenResolution;
+ }
+
+ /**
+ * 浠庣浉鏈烘敮鎸佺殑鍒嗚鲸鐜囦腑璁$畻鍑烘渶閫傚悎鐨勯瑙堢晫闈㈠昂瀵�
+ *
+ * @param parameters
+ * @param screenResolution
+ * @return
+ */
+ private Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {
+ List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
+ if (rawSupportedSizes == null) {
+ Log.w(TAG, "Device returned no supported preview sizes; using default");
+ Camera.Size defaultSize = parameters.getPreviewSize();
+ return new Point(defaultSize.width, defaultSize.height);
+ }
+
+ // Sort by size, descending
+ List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(rawSupportedSizes);
+ Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {
+ @Override
+ public int compare(Camera.Size a, Camera.Size b) {
+ int aPixels = a.height * a.width;
+ int bPixels = b.height * b.width;
+ if (bPixels < aPixels) {
+ return -1;
+ }
+ if (bPixels > aPixels) {
+ return 1;
+ }
+ return 0;
+ }
+ });
+
+ if (Log.isLoggable(TAG, Log.INFO)) {
+ StringBuilder previewSizesString = new StringBuilder();
+ for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
+ previewSizesString.append(supportedPreviewSize.width).append('x').append
+ (supportedPreviewSize.height).append(' ');
+ }
+ Log.i(TAG, "Supported preview sizes: " + previewSizesString);
+ }
+
+ double screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;
+
+ // Remove sizes that are unsuitable
+ Iterator<Camera.Size> it = supportedPreviewSizes.iterator();
+ while (it.hasNext()) {
+ Camera.Size supportedPreviewSize = it.next();
+ int realWidth = supportedPreviewSize.width;
+ int realHeight = supportedPreviewSize.height;
+ if (realWidth * realHeight < MIN_PREVIEW_PIXELS) {
+ it.remove();
+ continue;
+ }
+
+ boolean isCandidatePortrait = realWidth < realHeight;
+ int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
+ int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
+
+ double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;
+ double distortion = Math.abs(aspectRatio - screenAspectRatio);
+ if (distortion > MAX_ASPECT_DISTORTION) {
+ it.remove();
+ continue;
+ }
+
+ if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
+ Point exactPoint = new Point(realWidth, realHeight);
+ Log.i(TAG, "Found preview size exactly matching screen size: " + exactPoint);
+ return exactPoint;
+ }
+ }
+
+ // 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 (!supportedPreviewSizes.isEmpty()) {
+ Camera.Size largestPreview = supportedPreviewSizes.get(0);
+ Point largestSize = new Point(largestPreview.width, largestPreview.height);
+ Log.i(TAG, "Using largest suitable preview size: " + largestSize);
+ return largestSize;
+ }
+
+ // If there is nothing at all suitable, return current preview size
+ Camera.Size defaultPreview = parameters.getPreviewSize();
+ Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
+ Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
+
+ return defaultSize;
+ }
+}
diff --git a/third-zxing/src/main/java/com/zxing/camera/CameraManager.java b/third-zxing/src/main/java/com/zxing/camera/CameraManager.java
new file mode 100644
index 0000000..289b6fb
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/camera/CameraManager.java
@@ -0,0 +1,195 @@
+package com.zxing.camera;
+
+import android.content.Context;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.os.Build;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.zxing.camera.open.OpenCameraInterface;
+
+import java.io.IOException;
+
+/**
+ * This object wraps the Camera service object and expects to be the only one
+ * talking to it. The implementation encapsulates the steps needed to take
+ * preview-sized images, which are used for both preview and decoding.
+ */
+public class CameraManager {
+
+ private static final String TAG = CameraManager.class.getSimpleName();
+ private boolean status = false; // 璁板綍鎵嬫満鐘舵��
+ private final Context context;
+ private final CameraConfigurationManager configManager;
+ /**
+ * Preview frames are delivered here, which we pass on to the registered
+ * handler. Make sure to clear the handler so it will only receive one
+ * message.
+ */
+ private final PreviewCallback previewCallback;
+ private Camera camera;
+ private AutoFocusManager autoFocusManager;
+ private boolean initialized;
+ private boolean previewing;
+ private int requestedCameraId = -1;
+
+ public CameraManager(Context context) {
+ this.context = context;
+ this.configManager = new CameraConfigurationManager(context);
+ previewCallback = new PreviewCallback(configManager);
+ }
+
+ /**
+ * Opens the camera driver and initializes the hardware parameters.
+ *
+ * @param holder The surface object which the camera will draw preview frames
+ * into.
+ * @throws IOException Indicates the camera driver failed to open.
+ */
+ public synchronized void openDriver(SurfaceHolder holder) throws IOException {
+ Camera theCamera = camera;
+ if (theCamera == null) {
+
+ if (requestedCameraId >= 0) {
+ theCamera = OpenCameraInterface.open(requestedCameraId);
+ } else {
+ theCamera = OpenCameraInterface.open();
+ }
+
+ if (theCamera == null) {
+ throw new IOException();
+ }
+ camera = theCamera;
+ }
+ theCamera.setPreviewDisplay(holder);
+
+ if (!initialized) {
+ initialized = true;
+ configManager.initFromCameraParameters(theCamera);
+ }
+
+ Camera.Parameters parameters = theCamera.getParameters();
+ String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save
+ // these,
+ // temporarily
+ try {
+ configManager.setDesiredCameraParameters(theCamera, false);
+ } catch (RuntimeException re) {
+ // Driver failed
+ Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters");
+ Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
+ // Reset:
+ if (parametersFlattened != null) {
+ parameters = theCamera.getParameters();
+ parameters.unflatten(parametersFlattened);
+ try {
+ theCamera.setParameters(parameters);
+ configManager.setDesiredCameraParameters(theCamera, true);
+ } catch (RuntimeException re2) {
+ // Well, darn. Give up
+ Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
+ }
+ }
+ }
+
+ }
+
+ public synchronized boolean isOpen() {
+ return camera != null;
+ }
+
+ /**
+ * Closes the camera driver if still in use.
+ */
+ public synchronized void closeDriver() {
+ if (camera != null) {
+ camera.release();
+ camera = null;
+ // Make sure to clear these each time we close the camera, so that
+ // any scanning rect
+ // requested by intent is forgotten.
+ }
+ }
+
+ /**
+ * Asks the camera hardware to begin drawing preview frames to the screen.
+ */
+ public synchronized void startPreview() {
+ Camera theCamera = camera;
+ if (theCamera != null && !previewing) {
+ theCamera.startPreview();
+ previewing = true;
+ autoFocusManager = new AutoFocusManager(context, camera);
+ }
+ }
+
+ /**
+ * Tells the camera to stop drawing preview frames.
+ */
+ public synchronized void stopPreview() {
+ if (autoFocusManager != null) {
+ autoFocusManager.stop();
+ autoFocusManager = null;
+ }
+ if (camera != null && previewing) {
+ camera.stopPreview();
+ previewCallback.setHandler(null, 0);
+ previewing = false;
+ }
+ }
+
+ /**
+ * 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, respectively.
+ *
+ * @param handler The handler to send the message to.
+ * @param message The what field of the message to be sent.
+ */
+ public synchronized void requestPreviewFrame(Handler handler, int message) {
+ Camera theCamera = camera;
+ if (theCamera != null && previewing) {
+ previewCallback.setHandler(handler, message);
+ theCamera.setOneShotPreviewCallback(previewCallback);
+ }
+ }
+
+ /**
+ * Allows third party apps to specify the camera ID, rather than determine
+ * it automatically based on available cameras and their orientation.
+ *
+ * @param cameraId camera ID of the camera to use. A negative value means
+ * "no preference".
+ */
+ public synchronized void setManualCameraId(int cameraId) {
+ requestedCameraId = cameraId;
+ }
+
+ /**
+ * 鑾峰彇鐩告満鍒嗚鲸鐜�
+ *
+ * @return
+ */
+ public Point getCameraResolution() {
+ return configManager.getCameraResolution();
+ }
+
+ public Camera.Size getPreviewSize() {
+ if (null != camera) {
+ return camera.getParameters().getPreviewSize();
+ }
+ return null;
+ }
+
+ public Camera getCamera() {
+ return camera;
+ }
+
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/camera/PreviewCallback.java b/third-zxing/src/main/java/com/zxing/camera/PreviewCallback.java
new file mode 100644
index 0000000..214d334
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/camera/PreviewCallback.java
@@ -0,0 +1,40 @@
+package com.zxing.camera;
+
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+public class PreviewCallback implements Camera.PreviewCallback {
+
+ private static final String TAG = PreviewCallback.class.getSimpleName();
+
+ private final CameraConfigurationManager configManager;
+ private Handler previewHandler;
+ private int previewMessage;
+
+ public PreviewCallback(CameraConfigurationManager configManager) {
+ this.configManager = configManager;
+ }
+
+ public void setHandler(Handler previewHandler, int previewMessage) {
+ this.previewHandler = previewHandler;
+ this.previewMessage = previewMessage;
+ }
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ Point cameraResolution = configManager.getCameraResolution();
+ Handler thePreviewHandler = previewHandler;
+ if (cameraResolution != null && thePreviewHandler != null) {
+ Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
+ cameraResolution.y, data);
+ message.sendToTarget();
+ previewHandler = null;
+ } else {
+ Log.d(TAG, "Got preview callback, but no handler or resolution available");
+ }
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/camera/open/OpenCameraInterface.java b/third-zxing/src/main/java/com/zxing/camera/open/OpenCameraInterface.java
new file mode 100644
index 0000000..79fd06f
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/camera/open/OpenCameraInterface.java
@@ -0,0 +1,69 @@
+package com.zxing.camera.open;
+
+import android.hardware.Camera;
+import android.util.Log;
+
+public class OpenCameraInterface {
+
+ private static final String TAG = OpenCameraInterface.class.getName();
+
+ /**
+ * Opens the requested camera with {@link Camera#open(int)}, if one exists.
+ *
+ * @param cameraId camera ID of the camera to use. A negative value means
+ * "no preference"
+ * @return handle to {@link Camera} that was opened
+ */
+ public static Camera open(int cameraId) {
+
+ int numCameras = Camera.getNumberOfCameras();
+ if (numCameras == 0) {
+ Log.w(TAG, "No cameras!");
+ return null;
+ }
+
+ boolean explicitRequest = cameraId >= 0;
+
+ if (!explicitRequest) {
+ // Select a camera if no explicit camera requested
+ int index = 0;
+ while (index < numCameras) {
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ Camera.getCameraInfo(index, cameraInfo);
+ if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
+ break;
+ }
+ index++;
+ }
+
+ cameraId = index;
+ }
+
+ Camera camera;
+ if (cameraId < numCameras) {
+ Log.i(TAG, "Opening camera #" + cameraId);
+ camera = Camera.open(cameraId);
+ } else {
+ if (explicitRequest) {
+ Log.w(TAG, "Requested camera does not exist: " + cameraId);
+ camera = null;
+ } else {
+ Log.i(TAG, "No camera facing back; returning camera #0");
+ camera = Camera.open(0);
+ }
+ }
+
+ return camera;
+ }
+
+ /**
+ * Opens a rear-facing camera with {@link Camera#open(int)}, if one exists,
+ * or opens camera 0.
+ *
+ * @return handle to {@link Camera} that was opened
+ */
+ public static Camera open() {
+ return open(-1);
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/decode/DecodeFormatManager.java b/third-zxing/src/main/java/com/zxing/decode/DecodeFormatManager.java
new file mode 100644
index 0000000..b7c9b74
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/decode/DecodeFormatManager.java
@@ -0,0 +1,37 @@
+package com.zxing.decode;
+
+import com.google.zxing.BarcodeFormat;
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+public class DecodeFormatManager {
+
+ // 1D瑙g爜
+ private static final Set<BarcodeFormat> PRODUCT_FORMATS;
+ private static final Set<BarcodeFormat> INDUSTRIAL_FORMATS;
+ private static final Set<BarcodeFormat> ONE_D_FORMATS;
+
+ // 浜岀淮鐮佽В鐮�
+ private static final Set<BarcodeFormat> QR_CODE_FORMATS;
+
+ static {
+ PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A, BarcodeFormat.UPC_E, BarcodeFormat.EAN_13,
+ BarcodeFormat.EAN_8, BarcodeFormat.RSS_14, BarcodeFormat.RSS_EXPANDED);
+ INDUSTRIAL_FORMATS = EnumSet.of(BarcodeFormat.CODE_39, BarcodeFormat.CODE_93, BarcodeFormat
+ .CODE_128, BarcodeFormat.ITF, BarcodeFormat.CODABAR);
+ ONE_D_FORMATS = EnumSet.copyOf(PRODUCT_FORMATS);
+ ONE_D_FORMATS.addAll(INDUSTRIAL_FORMATS);
+
+ QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
+ }
+
+ public static Collection<BarcodeFormat> getQrCodeFormats() {
+ return QR_CODE_FORMATS;
+ }
+
+ public static Collection<BarcodeFormat> getBarCodeFormats() {
+ return ONE_D_FORMATS;
+ }
+}
diff --git a/third-zxing/src/main/java/com/zxing/decode/DecodeHandler.java b/third-zxing/src/main/java/com/zxing/decode/DecodeHandler.java
new file mode 100644
index 0000000..6c6212f
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/decode/DecodeHandler.java
@@ -0,0 +1,136 @@
+package com.zxing.decode;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.hardware.Camera.Size;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.PlanarYUVLuminanceSource;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+import com.zxing.IZxingActivity;
+import com.zxing.R;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Map;
+
+public class DecodeHandler extends Handler {
+
+ private final IZxingActivity activity;
+ private final MultiFormatReader multiFormatReader;
+ private boolean running = true;
+
+ public DecodeHandler(IZxingActivity activity, Map<DecodeHintType, Object> hints) {
+ multiFormatReader = new MultiFormatReader();
+ multiFormatReader.setHints(hints);
+ this.activity = activity;
+ }
+
+ private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
+ int[] pixels = source.renderThumbnail();
+ int width = source.getThumbnailWidth();
+ int height = source.getThumbnailHeight();
+ Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
+ bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (!running) {
+ return;
+ }
+ if (message.what == R.id.decode) {
+ decode((byte[]) message.obj, message.arg1, message.arg2);
+
+ } else if (message.what == R.id.quit) {
+ running = false;
+ Looper.myLooper().quit();
+
+ }
+ }
+
+ /**
+ * Decode the data within the viewfinder rectangle, and time how long it
+ * took. For efficiency, reuse the same reader objects from one decode to
+ * the next.
+ *
+ * @param data The YUV preview frame.
+ * @param width The width of the preview frame.
+ * @param height The height of the preview frame.
+ */
+ private void decode(byte[] data, int width, int height) {
+ Size size = activity.getCameraManager().getPreviewSize();
+
+ // 杩欓噷闇�瑕佸皢鑾峰彇鐨刣ata缈昏浆涓�涓嬶紝鍥犱负鐩告満榛樿鎷跨殑鐨勬í灞忕殑鏁版嵁
+ byte[] rotatedData = new byte[data.length];
+ for (int y = 0; y < size.height; y++) {
+ for (int x = 0; x < size.width; x++)
+ rotatedData[x * size.height + size.height - y - 1] = data[x + y * size.width];
+ }
+
+ // 瀹介珮涔熻璋冩暣
+ int tmp = size.width;
+ size.width = size.height;
+ size.height = tmp;
+
+ Result rawResult = null;
+ PlanarYUVLuminanceSource source = buildLuminanceSource(rotatedData, size.width, size.height);
+ if (source != null) {
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ try {
+ rawResult = multiFormatReader.decodeWithState(bitmap);
+ } catch (ReaderException re) {
+ // continue
+ } finally {
+ multiFormatReader.reset();
+ }
+ }
+
+ Handler handler = activity.getHandler();
+ if (rawResult != null) {
+ // Don't log the barcode contents for security.
+ if (handler != null) {
+ Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
+ Bundle bundle = new Bundle();
+ bundleThumbnail(source, bundle);
+ message.setData(bundle);
+ message.sendToTarget();
+ }
+ } else {
+ if (handler != null) {
+ Message message = Message.obtain(handler, R.id.decode_failed);
+ message.sendToTarget();
+ }
+ }
+
+ }
+
+ /**
+ * A factory method to build the appropriate LuminanceSource object based on
+ * the format of the preview buffers, as described by Camera.Parameters.
+ *
+ * @param data A preview frame.
+ * @param width The width of the image.
+ * @param height The height of the image.
+ * @return A PlanarYUVLuminanceSource instance.
+ */
+ public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
+ Rect rect = activity.getCropRect();
+ if (rect == null) {
+ return null;
+ }
+ // Go ahead and assume it's YUV rather than die.
+ return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect
+ .height(), false);
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/decode/DecodeThread.java b/third-zxing/src/main/java/com/zxing/decode/DecodeThread.java
new file mode 100644
index 0000000..319461b
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/decode/DecodeThread.java
@@ -0,0 +1,82 @@
+package com.zxing.decode;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
+import com.zxing.IZxingActivity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This thread does all the heavy lifting of decoding the images.
+ */
+public class DecodeThread extends Thread {
+
+ public static final String BARCODE_BITMAP = "barcode_bitmap";
+
+ public static final int BARCODE_MODE = 0X100;
+ public static final int QRCODE_MODE = 0X200;
+ public static final int ALL_MODE = 0X300;
+
+ private final IZxingActivity activity;
+ private final Map<DecodeHintType, Object> hints;
+ private final CountDownLatch handlerInitLatch;
+ private Handler handler;
+
+ public DecodeThread(IZxingActivity activity, int decodeMode) {
+
+ this.activity = activity;
+ handlerInitLatch = new CountDownLatch(1);
+
+ hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
+
+ Collection<BarcodeFormat> decodeFormats = new ArrayList<BarcodeFormat>();
+ decodeFormats.addAll(EnumSet.of(BarcodeFormat.AZTEC));
+ decodeFormats.addAll(EnumSet.of(BarcodeFormat.PDF_417));
+
+ switch (decodeMode) {
+ case BARCODE_MODE:
+ decodeFormats.addAll(DecodeFormatManager.getBarCodeFormats());
+ break;
+
+ case QRCODE_MODE:
+ decodeFormats.addAll(DecodeFormatManager.getQrCodeFormats());
+ break;
+
+ case ALL_MODE:
+ decodeFormats.addAll(DecodeFormatManager.getBarCodeFormats());
+ decodeFormats.addAll(DecodeFormatManager.getQrCodeFormats());
+ break;
+
+ default:
+ break;
+ }
+
+ hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+ }
+
+ public Handler getHandler() {
+ try {
+ handlerInitLatch.await();
+ } catch (InterruptedException ie) {
+ // continue?
+ }
+ return handler;
+ }
+
+ @Override
+ public void run() {
+ Looper.prepare();
+ handler = new DecodeHandler(activity, hints);
+ handlerInitLatch.countDown();
+ Looper.loop();
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/decode/RGBLuminanceSource.java b/third-zxing/src/main/java/com/zxing/decode/RGBLuminanceSource.java
new file mode 100644
index 0000000..bc53f0a
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/decode/RGBLuminanceSource.java
@@ -0,0 +1,72 @@
+package com.zxing.decode;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.google.zxing.LuminanceSource;
+
+import java.io.FileNotFoundException;
+
+public class RGBLuminanceSource extends LuminanceSource {
+ private final byte[] luminances;
+
+ public RGBLuminanceSource(String path) throws FileNotFoundException {
+ this(loadBitmap(path));
+ }
+
+ public RGBLuminanceSource(Bitmap bitmap) {
+ super(bitmap.getWidth(), bitmap.getHeight());
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+ int[] pixels = new int[width * height];
+ bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
+ // In order to measure pure decoding speed, we convert the entire image
+ // to a greyscale array
+ // up front, which is the same as the Y channel of the
+ // YUVLuminanceSource in the real app.
+ luminances = new byte[width * height];
+ for (int y = 0; y < height; y++) {
+ int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ int pixel = pixels[offset + x];
+ int r = (pixel >> 16) & 0xff;
+ int g = (pixel >> 8) & 0xff;
+ int b = pixel & 0xff;
+ if (r == g && g == b) {
+ // Image is already greyscale, so pick any channel.
+ luminances[offset + x] = (byte) r;
+ } else {
+ // Calculate luminance cheaply, favoring green.
+ luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
+ }
+ }
+ }
+ }
+
+ @Override
+ public byte[] getRow(int y, byte[] row) {
+ if (y < 0 || y >= getHeight()) {
+ throw new IllegalArgumentException(
+ "Requested row is outside the image: " + y);
+ }
+ int width = getWidth();
+ if (row == null || row.length < width) {
+ row = new byte[width];
+ }
+ System.arraycopy(luminances, y * width, row, 0, width);
+ return row;
+ }
+
+ @Override
+ public byte[] getMatrix() {
+ return luminances;
+ }
+
+ private static Bitmap loadBitmap(String path) throws FileNotFoundException {
+ Bitmap bitmap = BitmapFactory.decodeFile(path);
+ if (bitmap == null) {
+ throw new FileNotFoundException("Couldn't open " + path);
+ }
+ return bitmap;
+ }
+}
diff --git a/third-zxing/src/main/java/com/zxing/qrcode/CaptureActivity.java b/third-zxing/src/main/java/com/zxing/qrcode/CaptureActivity.java
new file mode 100644
index 0000000..8e15982
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/qrcode/CaptureActivity.java
@@ -0,0 +1,398 @@
+package com.zxing.qrcode;///*
+
+import android.app.Activity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.MediaStore;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.Toast;
+
+import androidx.appcompat.content.res.AppCompatResources;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.ChecksumException;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.FormatException;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.Result;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.QRCodeReader;
+import com.zxing.IZxingActivity;
+import com.zxing.R;
+import com.zxing.camera.CameraManager;
+import com.zxing.decode.DecodeThread;
+import com.zxing.decode.RGBLuminanceSource;
+import com.zxing.utils.BeepManager;
+import com.zxing.utils.CaptureActivityHandler;
+import com.zxing.utils.InactivityTimer;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+
+/**
+ * 鐢ㄩ�旓細鎵竴鎵�
+ */
+public final class CaptureActivity extends Activity implements IZxingActivity, SurfaceHolder.Callback {
+ private static final String TAG = CaptureActivity.class.getSimpleName();
+ private final int REQUEST_CODE = 33;
+ private CameraManager cameraManager;
+ private CaptureActivityHandler handler;
+ private InactivityTimer inactivityTimer;
+ private BeepManager beepManager;
+ private SurfaceView scanPreview = null;
+ private RelativeLayout scanContainer;
+ private RelativeLayout scanCropView;
+ private LinearLayout backll;
+ private ImageView light_iv;
+ private Rect mCropRect = null;
+ private boolean isHasSurface = false;
+
+ @Override
+ public Handler getHandler() {
+ return handler;
+ }
+
+ @Override
+ public void drawViewfinder() {
+
+ }
+
+ @Override
+ public CameraManager getCameraManager() {
+ return cameraManager;
+ }
+
+ public int getRootLayoutId() {
+ return R.layout.activity_capture;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Window window = getWindow();
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ //璁剧疆鏍硅鍥�
+ View mContentView = LayoutInflater.from(this).inflate(getRootLayoutId(), null);
+ setContentView(mContentView);
+ afterViewBind(mContentView, savedInstanceState);
+
+
+ }
+
+ public void afterViewBind(View rootView, Bundle savedInstanceState) {
+
+ light_iv = findViewById(R.id.light_iv);
+ backll = findViewById(R.id.top_back_btn);
+ backll.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ scanPreview = findViewById(R.id.capture_preview);
+ scanContainer = findViewById(R.id.capture_container);
+ scanCropView = findViewById(R.id.capture_crop_view);
+ ImageView scanLine = findViewById(R.id.capture_scan_line);
+ inactivityTimer = new InactivityTimer(this);
+ beepManager = new BeepManager(this);
+
+ TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation
+ .RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
+ 0.9f);
+ animation.setDuration(2000);
+ animation.setRepeatCount(-1);
+ animation.setRepeatMode(Animation.RESTART);
+ scanLine.startAnimation(animation);
+ light_iv.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ v.setSelected(!v.isSelected());
+ if (v.isSelected()) {
+// cameraManager.open();
+ light_iv.setImageDrawable(AppCompatResources.getDrawable(CaptureActivity.this, R.drawable.fast_scan_light_open));
+ } else {
+// cameraManager.close();
+ light_iv.setImageDrawable(AppCompatResources.getDrawable(CaptureActivity.this, R.drawable.fast_scan_light_close));
+ }
+
+ }
+ });
+
+ }
+
+ public void enterGallery() {
+ // 杩涘叆鍥惧簱
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("image/*");
+ intent.putExtra("return-data", true);
+ startActivityForResult(intent, REQUEST_CODE);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ cameraManager = new CameraManager(getApplication());
+ handler = null;
+ if (isHasSurface) {
+ initCamera(scanPreview.getHolder());
+ } else {
+ scanPreview.getHolder().addCallback(this);
+ }
+
+ inactivityTimer.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ if (handler != null) {
+ handler.quitSynchronously();
+ handler = null;
+ }
+ inactivityTimer.onPause();
+ beepManager.close();
+ cameraManager.closeDriver();
+ if (!isHasSurface) {
+ scanPreview.getHolder().removeCallback(this);
+ }
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ inactivityTimer.shutdown();
+ super.onDestroy();
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (holder == null) {
+ Log.d(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
+ }
+ if (!isHasSurface) {
+ isHasSurface = true;
+ initCamera(holder);
+ }
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ isHasSurface = false;
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ /**
+ * A valid barcode has been found, so give an indication of success and show
+ * the results.
+ *
+ * @param rawResult The contents of the barcode.
+ * @param bundle The extras
+ */
+ @Override
+ public void handleDecode(Result rawResult, Bundle bundle) {
+ inactivityTimer.onActivity();
+ beepManager.playBeepSoundAndVibrate();
+ doProcess(rawResult.getText());
+ restartPreviewAfterDelay(3000);
+ }
+
+ private void initCamera(SurfaceHolder surfaceHolder) {
+ if (surfaceHolder == null) {
+ throw new IllegalStateException("No SurfaceHolder provided");
+ }
+ if (cameraManager.isOpen()) {
+ Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
+ return;
+ }
+ try {
+ cameraManager.openDriver(surfaceHolder);
+ // Creating the handler starts the preview, which can also throw a
+ // RuntimeException.
+ if (handler == null) {
+ handler = new CaptureActivityHandler(this, cameraManager, DecodeThread.ALL_MODE);
+ }
+
+ initCrop();
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ Toast.makeText(this, R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
+ finish();
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Unexpected error initializing camera", e);
+ Toast.makeText(this, R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ }
+
+ public void restartPreviewAfterDelay(long delayMS) {
+ if (handler != null) {
+ handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
+ }
+ }
+
+ @Override
+ public Rect getCropRect() {
+ return mCropRect;
+ }
+
+ /**
+ * 鍒濆鍖栨埅鍙栫殑鐭╁舰鍖哄煙
+ */
+ private void initCrop() {
+ int cameraWidth = cameraManager.getCameraResolution().y;
+ int cameraHeight = cameraManager.getCameraResolution().x;
+
+ /** 鑾峰彇甯冨眬涓壂鎻忔鐨勪綅缃俊鎭� */
+ int[] location = new int[2];
+ scanCropView.getLocationInWindow(location);
+
+ int cropLeft = location[0];
+ int cropTop = location[1] - getStatusBarHeight();
+
+ int cropWidth = scanCropView.getWidth();
+ int cropHeight = scanCropView.getHeight();
+
+ /** 鑾峰彇甯冨眬瀹瑰櫒鐨勫楂� */
+ int containerWidth = scanContainer.getWidth();
+ int containerHeight = scanContainer.getHeight();
+
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫乏涓婅椤剁偣x鍧愭爣 */
+ int x = cropLeft * cameraWidth / containerWidth;
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫乏涓婅椤剁偣y鍧愭爣 */
+ int y = cropTop * cameraHeight / containerHeight;
+
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勫搴� */
+ int width = cropWidth * cameraWidth / containerWidth;
+ /** 璁$畻鏈�缁堟埅鍙栫殑鐭╁舰鐨勯珮搴� */
+ int height = cropHeight * cameraHeight / containerHeight;
+
+ /** 鐢熸垚鏈�缁堢殑鎴彇鐨勭煩褰� */
+ mCropRect = new Rect(x, y, width + x, height + y);
+ }
+
+ private int getStatusBarHeight() {
+ try {
+ Class<?> c = Class.forName("com.android.internal.R$dimen");
+ Object obj = c.newInstance();
+ Field field = c.getField("status_bar_height");
+ int x = Integer.parseInt(field.get(obj).toString());
+ return getResources().getDimensionPixelSize(x);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ private void doProcess(String result) {
+ Log.d("panlili", "scanResult: " + result);
+ /*if (!DeviceHelper.getNetworkState()) {
+ Toast.makeText(this, R.string.capture_no_network, Toast.LENGTH_SHORT).show();
+ return;
+ }*/
+
+ if (TextUtils.isEmpty(result)) {
+ Toast.makeText(this, R.string.capture_no_result, Toast.LENGTH_SHORT).show();
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("data", result);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
+ Uri originalUri = data.getData();
+ if (originalUri != null) {
+ String path = originalUri.getPath();
+ String[] proj = {MediaStore.Images.Media.DATA};
+ Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null);
+ if (cursor != null) {
+ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ path = cursor.getString(column_index);
+ cursor.close();
+ }
+
+ if (!TextUtils.isEmpty(path)) {
+ handleQRCodeFormPhoto(path);
+ } else {
+ Toast.makeText(this, "鍥剧墖宸叉崯鍧忥紝璇烽噸鏂伴�夋嫨锛�", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ }
+
+ /**
+ * 瑙f瀽鍥惧簱閫夋嫨鐨勪簩缁寸爜
+ */
+ public void handleQRCodeFormPhoto(final String filePath) {
+ Thread dealThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Hashtable<DecodeHintType, String> hints = new Hashtable<>();
+ hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
+ RGBLuminanceSource source = null;
+ try {
+ source = new RGBLuminanceSource(filePath);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
+ QRCodeReader reader = new QRCodeReader();
+ Result result;
+ try {
+ result = reader.decode(binaryBitmap, hints);
+ if (!TextUtils.isEmpty(result.getText())) {
+ dealUIInfo(result.getText());
+ } else {
+ dealUIInfo(null);
+ }
+ } catch (NotFoundException | ChecksumException | FormatException e) {
+ dealUIInfo(null);
+ e.printStackTrace();
+ }
+ }
+ });
+ dealThread.start();
+ }
+
+ private void dealUIInfo(final Object progressInfo) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (progressInfo == null) {
+ Toast.makeText(CaptureActivity.this, R.string.capture_no_result2, Toast.LENGTH_SHORT).show();
+ } else {
+ doProcess(progressInfo.toString());
+ }
+ }
+ });
+ }
+
+
+}
\ No newline at end of file
diff --git a/third-zxing/src/main/java/com/zxing/utils/BeepManager.java b/third-zxing/src/main/java/com/zxing/utils/BeepManager.java
new file mode 100644
index 0000000..c0fca3c
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/BeepManager.java
@@ -0,0 +1,125 @@
+package com.zxing.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.zxing.R;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Manages beeps and vibrations for {}.
+ */
+public class BeepManager implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, Closeable {
+
+ private static final String TAG = BeepManager.class.getSimpleName();
+
+ private static final float BEEP_VOLUME = 0.10f;
+ private static final long VIBRATE_DURATION = 200L;
+
+ private final Activity activity;
+ private MediaPlayer mediaPlayer;
+ private boolean playBeep;
+ private boolean vibrate;
+
+ public BeepManager(Activity activity) {
+ this.activity = activity;
+ this.mediaPlayer = null;
+ updatePrefs();
+ }
+
+ private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
+ boolean shouldPlayBeep = true;
+ if (shouldPlayBeep) {
+ // See if sound settings overrides this
+ AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
+ if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
+ shouldPlayBeep = false;
+ }
+ }
+ return shouldPlayBeep;
+ }
+
+ private synchronized void updatePrefs() {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+ playBeep = shouldBeep(prefs, activity);
+ vibrate = true;
+ if (playBeep && mediaPlayer == null) {
+ // The volume on STREAM_SYSTEM is not adjustable, and users found it
+ // too loud,
+ // so we now play on the music stream.
+ activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ mediaPlayer = buildMediaPlayer(activity);
+ }
+ }
+
+ public synchronized void playBeepSoundAndVibrate() {
+ if (playBeep && mediaPlayer != null) {
+ mediaPlayer.start();
+ }
+ if (vibrate) {
+ Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.vibrate(VIBRATE_DURATION);
+ }
+ }
+
+ private MediaPlayer buildMediaPlayer(Context activity) {
+ MediaPlayer mediaPlayer = new MediaPlayer();
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ mediaPlayer.setOnCompletionListener(this);
+ mediaPlayer.setOnErrorListener(this);
+ try {
+ AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep);
+ try {
+ mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
+ } finally {
+ file.close();
+ }
+ mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
+ mediaPlayer.prepare();
+ return mediaPlayer;
+ } catch (IOException ioe) {
+ Log.w(TAG, ioe);
+ mediaPlayer.release();
+ return null;
+ }
+ }
+
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ // When the beep has finished playing, rewind to queue up another one.
+ mp.seekTo(0);
+ }
+
+ @Override
+ public synchronized boolean onError(MediaPlayer mp, int what, int extra) {
+ if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+ // we are finished, so put up an appropriate error toast if required
+ // and finish
+ activity.finish();
+ } else {
+ // possibly media player error, so release and recreate
+ mp.release();
+ mediaPlayer = null;
+ updatePrefs();
+ }
+ return true;
+ }
+
+ @Override
+ public synchronized void close() {
+ if (mediaPlayer != null) {
+ mediaPlayer.release();
+ mediaPlayer = null;
+ }
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/utils/CaptureActivityHandler.java b/third-zxing/src/main/java/com/zxing/utils/CaptureActivityHandler.java
new file mode 100644
index 0000000..9be31c5
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/CaptureActivityHandler.java
@@ -0,0 +1,95 @@
+package com.zxing.utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+
+import com.google.zxing.Result;
+import com.zxing.IZxingActivity;
+import com.zxing.R;
+import com.zxing.camera.CameraManager;
+import com.zxing.decode.DecodeThread;
+
+/**
+ * This class handles all the messaging which comprises the state machine for
+ * capture.
+ */
+public class CaptureActivityHandler extends Handler {
+
+ private final IZxingActivity activity;
+ private final DecodeThread decodeThread;
+ private final CameraManager cameraManager;
+ private State state;
+
+ public CaptureActivityHandler(IZxingActivity activity, CameraManager cameraManager, int decodeMode) {
+ this.activity = activity;
+ decodeThread = new DecodeThread(activity, decodeMode);
+ decodeThread.start();
+ state = State.SUCCESS;
+
+ // Start ourselves capturing previews and decoding.
+ this.cameraManager = cameraManager;
+ cameraManager.startPreview();
+ restartPreviewAndDecode();
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == R.id.restart_preview) {
+ restartPreviewAndDecode();
+
+ } else if (message.what == R.id.decode_succeeded) {
+ state = State.SUCCESS;
+ Bundle bundle = message.getData();
+
+ activity.handleDecode((Result) message.obj, bundle);
+
+ } else if (message.what == R.id.decode_failed) {// We're decoding as fast as possible, so when one
+ // decode fails,
+ // start another.
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+
+ } else if (message.what == R.id.return_scan_result) {
+ activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
+ activity.finish();
+
+ }
+ }
+
+ public void quitSynchronously() {
+ state = State.DONE;
+ try {
+ cameraManager.stopPreview();
+ } catch (RuntimeException e) {
+
+ }
+ Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
+ quit.sendToTarget();
+ try {
+ // Wait at most half a second; should be enough time, and onPause()
+ // will timeout quickly
+ decodeThread.join(500L);
+ } catch (InterruptedException e) {
+ // continue
+ }
+
+ // Be absolutely sure we don't send any queued up messages
+ removeMessages(R.id.decode_succeeded);
+ removeMessages(R.id.decode_failed);
+ }
+
+ private void restartPreviewAndDecode() {
+ if (state == State.SUCCESS) {
+ state = State.PREVIEW;
+ cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
+ }
+ }
+
+ private enum State {
+ PREVIEW, SUCCESS, DONE
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/utils/InactivityTimer.java b/third-zxing/src/main/java/com/zxing/utils/InactivityTimer.java
new file mode 100644
index 0000000..750b01f
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/InactivityTimer.java
@@ -0,0 +1,108 @@
+package com.zxing.utils;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.os.Build;
+import android.util.Log;
+
+/**
+ * Finishes an activity after a period of inactivity if the device is on battery
+ * power.
+ */
+public class InactivityTimer {
+
+ private static final String TAG = InactivityTimer.class.getSimpleName();
+
+ private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
+
+ private Activity activity;
+ private BroadcastReceiver powerStatusReceiver;
+ private boolean registered;
+ private AsyncTask<Object, Object, Object> inactivityTask;
+
+ public InactivityTimer(Activity activity) {
+ this.activity = activity;
+ powerStatusReceiver = new PowerStatusReceiver();
+ registered = false;
+ onActivity();
+ }
+
+ @SuppressLint("NewApi")
+ public synchronized void onActivity() {
+ cancel();
+ inactivityTask = new InactivityAsyncTask();
+ if (Build.VERSION.SDK_INT >= 11) {
+ inactivityTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
+ inactivityTask.execute();
+ }
+ }
+
+ public synchronized void onPause() {
+ cancel();
+ if (registered) {
+ activity.unregisterReceiver(powerStatusReceiver);
+ registered = false;
+ } else {
+ Log.w(TAG, "PowerStatusReceiver was never registered?");
+ }
+ }
+
+ public synchronized void onResume() {
+ if (registered) {
+ Log.w(TAG, "PowerStatusReceiver was already registered?");
+ } else {
+ activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ registered = true;
+ }
+ onActivity();
+ }
+
+ private synchronized void cancel() {
+ AsyncTask<?, ?, ?> task = inactivityTask;
+ if (task != null) {
+ task.cancel(true);
+ inactivityTask = null;
+ }
+ }
+
+ public void shutdown() {
+ cancel();
+ }
+
+ private class PowerStatusReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+ // 0 indicates that we're on battery
+ boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
+ if (onBatteryNow) {
+ InactivityTimer.this.onActivity();
+ } else {
+ InactivityTimer.this.cancel();
+ }
+ }
+ }
+ }
+
+ private class InactivityAsyncTask extends AsyncTask<Object, Object, Object> {
+ @Override
+ protected Object doInBackground(Object... objects) {
+ try {
+ Thread.sleep(INACTIVITY_DELAY_MS);
+ Log.i(TAG, "Finishing activity due to inactivity");
+ activity.finish();
+ } catch (InterruptedException e) {
+ // continue without killing
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/third-zxing/src/main/java/com/zxing/utils/Strings.java b/third-zxing/src/main/java/com/zxing/utils/Strings.java
new file mode 100644
index 0000000..f736e6b
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/Strings.java
@@ -0,0 +1,179 @@
+package com.zxing.utils;
+
+import android.text.TextUtils;
+
+import java.util.Iterator;
+import java.util.regex.Pattern;
+
+public abstract class Strings {
+ public static final String EMPTY = "";
+ public static final String BLANK = " ";
+ public static final String EQUAL = "=";
+ public static final String AND = "&";
+ public static final String QMARK = "?";
+ public static final String TRUE = "true";
+ public static final String FALSE = "false";
+ public static final String CANCEL = "cancel";
+ public static final String NULL_STR = "null";
+ public static final String SUCCESS = "success";
+ public static final String FAIL = "fail";
+ public static final String ZERO = "0";
+ public static final String SEMICOLON = ";";
+ public static final String SPLITE = "/";
+ public static final String AT = "@";
+ public static final String COMMA = ",";
+ public static final String FILE_PRE = "file://";
+ public static final String HTTP_PRE = "http";
+ public static final String COLON = ":";
+ public static final String WRAP = "";
+ public static final String STAR = "*";
+ public static final String MORE = "...";
+
+ /**
+ * 鍘婚櫎瀛楃涓蹭腑鐨勭┖鏍�
+ */
+ public static String trimAll(CharSequence s) {
+ if (s == null || s.length() == 0) return Strings.EMPTY;
+ StringBuilder sb = new StringBuilder(s.length());
+ for (int i = 0, L = s.length(); i < L; i++) {
+ char c = s.charAt(i);
+ if (c != ' ') sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓烘墜鏈哄彿鐮�
+ */
+ public static boolean isPhoneNum(String phoneNum) {
+ if (phoneNum == null || phoneNum.length() != 11) return false;
+ if (!TextUtils.isDigitsOnly(phoneNum)) return false;
+ Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[^4,\\D])|(17[0-9])|(18[0-9]))\\d{8}$");
+ return p.matcher(phoneNum).find();
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄骇鏈哄彿鐮�
+ */
+ public static boolean isTelNum(String num) {
+ if (TextUtils.isEmpty(num)) return false;
+ Pattern p = Pattern.compile("(\\(\\d{3,4}\\)|\\d{3,4}-|\\s)?\\d{8}");
+ return p.matcher(num).find();
+ }
+
+ /**
+ * 鍒ゆ柇瀛楃涓蹭腑鏄惁鏈変腑鏂囷紝鏈変腑鏂囪繑鍥瀟rue
+ */
+ public static boolean isChinese(String string) {
+ boolean flag = false;
+ for (int i = 0, L = string.length(); i < L; i++) {
+ char c = string.charAt(i);
+ if ((c >= 0x4e00) && (c <= 0x9FA5)) {
+ flag = true;
+ } else {
+ return false;
+ }
+ }
+ return flag;
+ }
+
+ /**
+ * 鍒ゆ柇瀛楃闀垮害鏄惁鍦ㄨ寖鍥撮噷闈€�� 褰搒tart end 涓� -1 鏃讹紝琛ㄧず瀛楃闀垮害涓嶈�冭檻涓婄嚎鎴栦笅绾�
+ *
+ * @param str
+ * @param start
+ * @param end
+ * @return
+ */
+ public static boolean isLengthInRange(String str, int start, int end) {
+ boolean isInRange = true;
+ int length = str.length();
+ if (start != -1 && length < start) {
+ isInRange = false;
+ }
+ if (end != -1 && end < length) {
+ isInRange = false;
+ }
+ return isInRange;
+ }
+
+ /**
+ * 瀛楃涓茶浆鎹负long鍨�
+ */
+ public static long toLong(String text, long defaultVal) {
+ if (TextUtils.isDigitsOnly(text)) {
+ try {
+ return Long.parseLong(text);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return defaultVal;
+ }
+
+ /**
+ * 瀛楃涓茶浆鎹负int
+ */
+ public static int toInt(String text, int defaultVal) {
+ if (TextUtils.isDigitsOnly(text)) {
+ try {
+ return Integer.parseInt(text);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return defaultVal;
+ }
+
+
+ public static String join(Iterable<?> iterable, String separator) {
+
+ // handle null, zero and one elements before building a buffer
+ if (iterable == null) {
+ return null;
+ }
+ Iterator<?> iterator = iterable.iterator();
+ if (!iterator.hasNext()) {
+ return EMPTY;
+ }
+ Object first = iterator.next();
+ if (!iterator.hasNext()) {
+ return toString(first);
+ }
+
+ // two or more elements
+ StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small
+ if (first != null) {
+ buf.append(first);
+ }
+
+ while (iterator.hasNext()) {
+ if (separator != null) {
+ buf.append(separator);
+ }
+ Object obj = iterator.next();
+ if (obj != null) {
+ buf.append(obj);
+ }
+ }
+ return buf.toString();
+ }
+
+ public static String toString(Object obj) {
+ return obj == null ? "" : obj.toString();
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄瓧绗︿覆鏄惁涓虹┖
+ */
+ public static boolean toBoolean(String property, boolean defaultVal) {
+ return property == null ? defaultVal : Boolean.valueOf(property);
+ }
+
+ public static String format(String str, Object... obj) {
+ try {
+ return String.format(str, obj);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return str;
+ }
+}
diff --git a/third-zxing/src/main/java/com/zxing/utils/Validator.java b/third-zxing/src/main/java/com/zxing/utils/Validator.java
new file mode 100644
index 0000000..f461d5a
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/Validator.java
@@ -0,0 +1,202 @@
+package com.zxing.utils;
+
+import android.annotation.SuppressLint;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 姝e垯琛ㄨ揪寮�
+ *
+ */
+@SuppressLint("WrongConstant")
+public class Validator {
+
+ public static boolean password(String password) {
+ return password.matches("[0-9a-zA-Z]{8,16}") && !password.matches("[0-9]+") && !password.matches("[a-zA-Z]+");
+ }
+
+ public static List<String> findMac(String src) {
+ List<String> list = new ArrayList<String>();
+ if (src == null || "".equals(src))
+ return list;
+ Pattern pattern = Pattern
+ .compile("[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}");
+ Matcher matcher = pattern.matcher(src);
+ while (matcher.find()) {
+ list.add(matcher.group(0));
+ }
+ return list;
+ }
+
+ public static List<String> findColor(String src) {
+ List<String> list = new ArrayList<String>();
+ if (src == null || src.equals(""))
+ return list;
+ Pattern pattern = Pattern
+ .compile("#[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8}");
+ Matcher matcher = pattern.matcher(src);
+ while (matcher.find()) {
+ list.add(matcher.group(0));
+ }
+ return list;
+ }
+
+ /**
+ * 鍘婚櫎姹夊瓧,褰掓缂栫爜
+ */
+ public static String replaceHanzi(String input) {
+ if (TextUtils.isEmpty(input)) {
+ return "";
+ }
+
+ /**
+ * 褰掓缂栫爜
+ */
+ byte[] bytes = input.getBytes();
+ String info = "";
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] < 0) {
+ bytes[i] = 32;
+ }
+ info = info + new String(new byte[]{bytes[i]});
+ }
+
+ /**
+ * 鍘婚櫎涓枃
+ */
+ Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
+ Matcher m = p.matcher(info);
+ List<String> inputs = new ArrayList<>();
+
+ if (m.find()) {
+ for (int i = 0; i < info.length(); i++) {
+ String ever = info.substring(i, i + 1);
+ Matcher m1 = p.matcher(ever);
+ if (m1.find()) {
+ ever = "";
+ }
+ inputs.add(ever);
+ }
+
+ String inputNew = "";
+ for (int i = 0; i < inputs.size(); i++) {
+ inputNew = inputNew + inputs.get(i);
+ }
+ return inputNew.trim();
+
+ }
+ return info.trim();
+ }
+
+ /**
+ * 楠岃瘉閭
+ */
+ public static boolean checkEmail(String email) {
+ boolean flag;
+ try {
+ String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
+ Pattern regex = Pattern.compile(check);
+ Matcher matcher = regex.matcher(email);
+ flag = matcher.matches();
+ } catch (Exception e) {
+ flag = false;
+ }
+ return flag;
+ }
+
+ /**
+ * 鑾峰緱姹夎鎷奸煶棣栧瓧姣�
+ */
+ public static String getAlpha(String str) {
+ if (str == null) {
+ return "#";
+ }
+
+ if (str.trim().length() == 0) {
+ return "#";
+ }
+
+ char c = str.trim().substring(0, 1).charAt(0);
+ // 姝e垯琛ㄨ揪寮忥紝鍒ゆ柇棣栧瓧姣嶆槸鍚︽槸鑻辨枃瀛楁瘝
+ Pattern pattern = Pattern.compile("^[A-Za-z]+$");
+ if (pattern.matcher(c + "").matches()) {
+ return (c + "").toUpperCase();
+ } else {
+ return "#";
+ }
+ }
+
+ /**
+ * 鏍¢獙URL
+ */
+ public static boolean checkUrl(String url) {
+ if (TextUtils.isEmpty(url)) return false;
+ boolean flag;
+ try {
+ String check = "^((https|http|ftp|rtsp|mms|axd):\\/\\/)[^\\s]+";
+ Pattern regex = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = regex.matcher(url.replaceAll(" ", ""));
+ flag = matcher.matches();
+ } catch (Exception e) {
+ flag = false;
+ }
+
+ return flag;
+ }
+
+ /**
+ * 鏍¢獙鍥剧墖URL
+ */
+ public static boolean checkImageUrl(String url) {
+ if (TextUtils.isEmpty(url)) return false;
+ boolean flag;
+ try {
+ String check = "^((https|http):\\/\\/)[^\\s]+.(png|jpg|gif|webp)";
+ Pattern regex = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = regex.matcher(url);
+ flag = matcher.matches();
+ } catch (Exception e) {
+ flag = false;
+ }
+
+ return flag;
+ }
+
+ /**
+ * 鏍¢獙姝f暣鏁�
+ */
+ public static boolean checkInt(String intContent) {
+ if (TextUtils.isEmpty(intContent)) return false;
+ boolean flag;
+ try {
+ String check = "^[1-9]\\d*$";
+ Pattern regex = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = regex.matcher(intContent);
+ flag = matcher.matches();
+ } catch (Exception e) {
+ flag = false;
+ }
+
+ return flag;
+ }
+
+ public static boolean checkColor(String color) {
+ if (TextUtils.isEmpty(color))
+ return false;
+ boolean flag;
+ try {
+ String check = "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$";
+ Pattern regex = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = regex.matcher(color);
+ flag = matcher.matches();
+ } catch (Exception e) {
+ flag = false;
+ }
+ return flag;
+ }
+}
\ No newline at end of file
diff --git a/third-zxing/src/main/java/com/zxing/utils/ZXingBitmapUtils.java b/third-zxing/src/main/java/com/zxing/utils/ZXingBitmapUtils.java
new file mode 100644
index 0000000..85d2e29
--- /dev/null
+++ b/third-zxing/src/main/java/com/zxing/utils/ZXingBitmapUtils.java
@@ -0,0 +1,333 @@
+package com.zxing.utils;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.media.ExifInterface;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Bitmap鎿嶄綔甯哥敤宸ュ叿绫�
+ */
+public class ZXingBitmapUtils {
+
+ private final static String TAG = ZXingBitmapUtils.class.getCanonicalName();
+ public final static String JPG_SUFFIX = ".jpg";
+ private final static String TIME_FORMAT = "yyyyMMddHHmmss";
+
+ /**
+ * 鏄剧ず鍥剧墖鍒扮浉鍐�
+ *
+ * @param context
+ * @param photoFile 瑕佷繚瀛樼殑鍥剧墖鏂囦欢
+ */
+ public static void displayToGallery(Context context, File photoFile) {
+ if (photoFile == null || !photoFile.exists()) {
+ return;
+ }
+ String photoPath = photoFile.getAbsolutePath();
+ String photoName = photoFile.getName();
+ // 鍏舵鎶婃枃浠舵彃鍏ュ埌绯荤粺鍥惧簱
+ try {
+ ContentResolver contentResolver = context.getContentResolver();
+ MediaStore.Images.Media.insertImage(contentResolver, photoPath, photoName, null);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ // 鏈�鍚庨�氱煡鍥惧簱鏇存柊
+ context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + photoPath)));
+ }
+
+ /**
+ * 灏咮itmap淇濆瓨鍒版寚瀹氱洰褰曚笅
+ *
+ * @param bitmap
+ * @param folder
+ * @return 淇濆瓨鎴愬姛锛岃繑鍥炲叾瀵瑰簲鐨凢ile锛屼繚瀛樺け璐ュ垯杩斿洖null
+ */
+ public static File saveToFile(Bitmap bitmap, File folder) {
+ String fileName = new SimpleDateFormat(TIME_FORMAT).format(new Date());//鐩存帴浠ュ綋鍓嶆椂闂存埑浣滀负鏂囦欢鍚�
+ return saveToFile(bitmap, folder, fileName);
+ }
+
+ /**
+ * 灏咮itmap淇濆瓨鍒版寚瀹氱洰褰曚笅锛屽苟涓旀寚瀹氬ソ鏂囦欢鍚�
+ *
+ * @param bitmap
+ * @param folder
+ * @param fileName 鎸囧畾鐨勬枃浠跺悕鍖呭惈鍚庣紑
+ * @return 淇濆瓨鎴愬姛锛岃繑鍥炲叾瀵瑰簲鐨凢ile锛屼繚瀛樺け璐ュ垯杩斿洖null
+ */
+ public static File saveToFile(Bitmap bitmap, File folder, String fileName) {
+ if (bitmap != null) {
+ if (!folder.exists()) {
+ folder.mkdir();
+ }
+ File file = new File(folder, fileName + JPG_SUFFIX);
+ if (file.exists()) {
+ file.delete();
+ }
+ try {
+ file.createNewFile();
+ BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
+ bos.flush();
+ bos.close();
+ return file;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇鍥剧墖鐨勬棆杞搴�
+ *
+ * @param path 鍥剧墖缁濆璺緞
+ * @return 鍥剧墖鐨勬棆杞搴�
+ */
+ public static int getBitmapDegree(String path) {
+ int degree = 0;
+ try {
+ // 浠庢寚瀹氳矾寰勪笅璇诲彇鍥剧墖锛屽苟鑾峰彇鍏禘XIF淇℃伅
+ ExifInterface exifInterface = new ExifInterface(path);
+ // 鑾峰彇鍥剧墖鐨勬棆杞俊鎭�
+ int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
+ switch (orientation) {
+ case ExifInterface.ORIENTATION_ROTATE_90:
+ degree = 90;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_180:
+ degree = 180;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_270:
+ degree = 270;
+ break;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return degree;
+ }
+
+ /**
+ * 灏嗗浘鐗囨寜鐓ф寚瀹氱殑瑙掑害杩涜鏃嬭浆
+ *
+ * @param bitmap 闇�瑕佹棆杞殑鍥剧墖
+ * @param degree 鎸囧畾鐨勬棆杞搴�
+ * @return 鏃嬭浆鍚庣殑鍥剧墖
+ */
+ public static Bitmap rotateBitmapByDegree(Bitmap bitmap, int degree) {
+ // 鏍规嵁鏃嬭浆瑙掑害锛岀敓鎴愭棆杞煩闃�
+ Matrix matrix = new Matrix();
+ matrix.postRotate(degree);
+ // 灏嗗師濮嬪浘鐗囨寜鐓ф棆杞煩闃佃繘琛屾棆杞紝骞跺緱鍒版柊鐨勫浘鐗�
+ Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ if (bitmap != null && !bitmap.isRecycled()) {
+ bitmap.recycle();
+ }
+ return newBitmap;
+ }
+
+ /**
+ * 鍘嬬缉Bitmap鐨勫ぇ灏�
+ *
+ * @param imageFile 鍥剧墖鏂囦欢
+ * @param requestWidth 鍘嬬缉鍒版兂瑕佺殑瀹藉害
+ * @param requestHeight 鍘嬬缉鍒版兂瑕佺殑楂樺害
+ * @return
+ */
+ public static Bitmap decodeBitmapFromFile(File imageFile, int requestWidth, int requestHeight) {
+ if (imageFile != null) {
+ return decodeBitmapFromFile(imageFile.getAbsolutePath(), requestWidth, requestHeight);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 鍘嬬缉Bitmap鐨勫ぇ灏�
+ *
+ * @param imagePath 鍥剧墖鏂囦欢璺緞
+ * @param requestWidth 鍘嬬缉鍒版兂瑕佺殑瀹藉害
+ * @param requestHeight 鍘嬬缉鍒版兂瑕佺殑楂樺害
+ * @return
+ */
+ public static Bitmap decodeBitmapFromFile(String imagePath, int requestWidth, int requestHeight) {
+ if (!TextUtils.isEmpty(imagePath)) {
+ Log.i(TAG, "requestWidth: " + requestWidth);
+ Log.i(TAG, "requestHeight: " + requestHeight);
+ if (requestWidth <= 0 || requestHeight <= 0) {
+ Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
+ return bitmap;
+ }
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;//涓嶅姞杞藉浘鐗囧埌鍐呭瓨锛屼粎鑾峰緱鍥剧墖瀹介珮
+ BitmapFactory.decodeFile(imagePath, options);
+ Log.i(TAG, "original height: " + options.outHeight);
+ Log.i(TAG, "original width: " + options.outWidth);
+ if (options.outHeight == -1 || options.outWidth == -1) {
+ try {
+ ExifInterface exifInterface = new ExifInterface(imagePath);
+ int height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//鑾峰彇鍥剧墖鐨勯珮搴�
+ int width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//鑾峰彇鍥剧墖鐨勫搴�
+ Log.i(TAG, "exif height: " + height);
+ Log.i(TAG, "exif width: " + width);
+ options.outWidth = width;
+ options.outHeight = height;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ options.inSampleSize = calculateInSampleSize(options, requestWidth, requestHeight); //璁$畻鑾峰彇鏂扮殑閲囨牱鐜�
+ Log.i(TAG, "inSampleSize: " + options.inSampleSize);
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeFile(imagePath, options);
+
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Decode and sample down a bitmap from resources to the requested width and height.
+ *
+ * @param res The resources object containing the image data
+ * @param resId The resource id of the image data
+ * @param reqWidth The requested width of the resulting bitmap
+ * @param reqHeight The requested height of the resulting bitmap
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
+ * that are equal to or greater than the requested width and height
+ */
+ public static Bitmap decodeBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
+
+ // BEGIN_INCLUDE (read_bitmap_dimensions)
+ // First decode with inJustDecodeBounds=true to check dimensions
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeResource(res, resId, options);
+
+ // Calculate inSampleSize
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+ // END_INCLUDE (read_bitmap_dimensions)
+
+ // Decode bitmap with inSampleSize set
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeResource(res, resId, options);
+ }
+
+ /**
+ * Decode and sample down a bitmap from a file input stream to the requested width and height.
+ *
+ * @param fileDescriptor The file descriptor to read from
+ * @param reqWidth The requested width of the resulting bitmap
+ * @param reqHeight The requested height of the resulting bitmap
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
+ * that are equal to or greater than the requested width and height
+ */
+ public static Bitmap decodeBitmapFromDescriptor(FileDescriptor fileDescriptor, int reqWidth, int reqHeight) {
+
+ // First decode with inJustDecodeBounds=true to check dimensions
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
+
+ // Calculate inSampleSize
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+ // Decode bitmap with inSampleSize set
+ options.inJustDecodeBounds = false;
+
+ return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
+ }
+
+ /**
+ * Google瀹樻柟浠g爜锛岃绠楀悎閫傜殑閲囨牱鐜�
+ * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
+ * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
+ * the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap
+ * having a width and height equal to or larger than the requested width and height.
+ *
+ * @param options An options object with out* params already populated (run through a decode*
+ * method with inJustDecodeBounds==true
+ * @param reqWidth The requested width of the resulting bitmap
+ * @param reqHeight The requested height of the resulting bitmap
+ * @return The value to be used for inSampleSize
+ */
+ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
+ // BEGIN_INCLUDE (calculate_sample_size)
+ // Raw height and width of image
+ final int height = options.outHeight;
+ final int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > reqHeight || width > reqWidth) {
+
+ final int halfHeight = height / 2;
+ final int halfWidth = width / 2;
+
+ // Calculate the largest inSampleSize value that is a power of 2 and keeps both
+ // height and width larger than the requested height and width.
+ while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
+ inSampleSize *= 2;
+ }
+
+ // This offers some additional logic in case the image has a strange
+ // aspect ratio. For example, a panorama may have a much larger
+ // width than height. In these cases the total pixels might still
+ // end up being too large to fit comfortably in memory, so we should
+ // be more aggressive with sample down the image (=larger inSampleSize).
+
+ long totalPixels = width * height / inSampleSize;
+
+ // Anything more than 2x the requested pixels we'll sample down further
+ final long totalReqPixelsCap = reqWidth * reqHeight * 2;
+
+ while (totalPixels > totalReqPixelsCap) {
+ inSampleSize *= 2;
+ totalPixels /= 2;
+ }
+ }
+ return inSampleSize;
+ // END_INCLUDE (calculate_sample_size)
+ }
+
+ /**
+ * drawable杞琤itmap
+ */
+ public static Bitmap drawableToBitmap(Drawable drawable) {
+ int w = drawable.getIntrinsicWidth();
+ int h = drawable.getIntrinsicHeight();
+ Bitmap.Config config =
+ drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
+ : Bitmap.Config.RGB_565;
+ Bitmap bitmap = Bitmap.createBitmap(w, h, config);
+ //娉ㄦ剰锛屼笅闈笁琛屼唬鐮佽鐢ㄥ埌锛屽惁鍦ㄥ湪View鎴栬�卻urfaceview閲岀殑canvas.drawBitmap浼氱湅涓嶅埌鍥�
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, w, h);
+ drawable.draw(canvas);
+ return bitmap;
+ }
+}
diff --git a/third-zxing/src/main/res/drawable-xxhdpi/ic_shadow.png b/third-zxing/src/main/res/drawable-xxhdpi/ic_shadow.png
new file mode 100644
index 0000000..6be3091
--- /dev/null
+++ b/third-zxing/src/main/res/drawable-xxhdpi/ic_shadow.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable-xxhdpi/scan_capture.9.png b/third-zxing/src/main/res/drawable-xxhdpi/scan_capture.9.png
new file mode 100644
index 0000000..e03b3fc
--- /dev/null
+++ b/third-zxing/src/main/res/drawable-xxhdpi/scan_capture.9.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable-xxhdpi/scan_line.png b/third-zxing/src/main/res/drawable-xxhdpi/scan_line.png
new file mode 100644
index 0000000..23bebf8
--- /dev/null
+++ b/third-zxing/src/main/res/drawable-xxhdpi/scan_line.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable/back.png b/third-zxing/src/main/res/drawable/back.png
new file mode 100644
index 0000000..64507b9
--- /dev/null
+++ b/third-zxing/src/main/res/drawable/back.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable/fast_scan_light_close.png b/third-zxing/src/main/res/drawable/fast_scan_light_close.png
new file mode 100644
index 0000000..56f42cf
--- /dev/null
+++ b/third-zxing/src/main/res/drawable/fast_scan_light_close.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable/fast_scan_light_open.png b/third-zxing/src/main/res/drawable/fast_scan_light_open.png
new file mode 100644
index 0000000..454e02f
--- /dev/null
+++ b/third-zxing/src/main/res/drawable/fast_scan_light_open.png
Binary files differ
diff --git a/third-zxing/src/main/res/drawable/transparent_divider.xml b/third-zxing/src/main/res/drawable/transparent_divider.xml
new file mode 100644
index 0000000..a71236a
--- /dev/null
+++ b/third-zxing/src/main/res/drawable/transparent_divider.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <size android:height="13dp"/>
+ <solid android:color="@color/transparent"/>
+</shape>
\ No newline at end of file
diff --git a/third-zxing/src/main/res/layout/activity_capture.xml b/third-zxing/src/main/res/layout/activity_capture.xml
new file mode 100644
index 0000000..417171b
--- /dev/null
+++ b/third-zxing/src/main/res/layout/activity_capture.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/capture_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#636363">
+
+
+
+ <RelativeLayout
+ android:id="@+id/top_bar_view"
+ android:layout_width="match_parent"
+ android:layout_height="52dp"
+ android:background="#245EC3"
+ android:orientation="horizontal">
+
+ <!--1.杩斿洖鎸夐挳 澧炲ぇ鐐瑰嚮鍖哄煙-->
+ <LinearLayout
+ android:id="@+id/top_back_btn"
+ android:layout_width="56dp"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ >
+
+ <ImageView
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="center"
+ android:layout_marginLeft="16dp"
+ android:scaleType="centerInside"
+ android:src="@drawable/back"
+ />
+ </LinearLayout>
+
+ <!--2.鏍囬鏂囨湰-->
+ <TextView
+ android:id="@+id/top_title_tv"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:layout_marginLeft="60dp"
+ android:layout_marginRight="60dp"
+ android:fontFamily="sans-serif-medium"
+ android:gravity="center"
+ android:maxLines="1"
+ android:text="蹇�熸壂鐮�"
+ android:textColor="#FFFFFFFF"
+ android:textSize="18sp" />
+
+ <!--3.鏇村鎸夐挳 榛樿闅愯棌-->
+ <LinearLayout
+ android:id="@+id/top_more_btn"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentEnd="true"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/top_more_iv"
+ android:layout_width="28dp"
+ android:layout_height="28dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="20dp"
+ android:adjustViewBounds="true"
+ android:scaleType="centerInside"
+ android:visibility="gone" />
+
+ </LinearLayout>
+
+ </RelativeLayout>
+
+ <SurfaceView
+ android:id="@+id/capture_preview"
+ android:layout_width="367dp"
+ android:layout_height="367dp"
+ android:layout_centerInParent="true"
+
+ />
+
+
+ <RelativeLayout
+ android:id="@+id/capture_crop_view"
+ android:layout_width="367dp"
+ android:layout_height="367dp"
+ android:layout_centerInParent="true"
+ android:background="@drawable/scan_capture">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="367dp"
+ android:layout_marginTop="182dp">
+
+ <ImageView
+ android:id="@+id/capture_scan_line"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="5dp"
+ android:src="@drawable/scan_line" />
+ </RelativeLayout>
+
+ </RelativeLayout>
+
+ <ImageView
+ android:id="@+id/light_iv"
+ android:layout_width="127dp"
+ android:layout_height="127dp"
+ android:layout_alignParentBottom="true"
+ android:layout_centerInParent="true"
+ android:layout_marginBottom="13dp"
+ android:background="@drawable/fast_scan_light_close" />
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/third-zxing/src/main/res/layout/toolbar.xml b/third-zxing/src/main/res/layout/toolbar.xml
new file mode 100644
index 0000000..75014a6
--- /dev/null
+++ b/third-zxing/src/main/res/layout/toolbar.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ >
+
+ <RelativeLayout
+ android:id="@+id/rl_back"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginStart="32dp">
+
+ <TextView
+ android:id="@+id/tv_text_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:text="@string/scan_cancel"
+ android:textColor="#000000"
+ android:textSize="36sp" />
+ </RelativeLayout>
+
+ <TextView
+ android:id="@+id/tv_text_scan"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:text="@string/scan_title"
+ android:textColor="#000000"
+ android:textSize="36sp" />
+
+
+</RelativeLayout>
diff --git a/third-zxing/src/main/res/raw/beep.ogg b/third-zxing/src/main/res/raw/beep.ogg
new file mode 100644
index 0000000..dc6e719
--- /dev/null
+++ b/third-zxing/src/main/res/raw/beep.ogg
Binary files differ
diff --git a/third-zxing/src/main/res/values/colors_ui.xml b/third-zxing/src/main/res/values/colors_ui.xml
new file mode 100644
index 0000000..966918a
--- /dev/null
+++ b/third-zxing/src/main/res/values/colors_ui.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!--鍩虹鑹�-->
+ <color name="c0">#F18D00</color> <!--鐢ㄤ簬鎸夐挳銆佽緝澶ч潰绉壊鍧楄緟鑹� 鍘烠10-->
+ <color name="c1">#F18D00</color> <!--鐢ㄤ簬寮鸿皟鎬ф枃瀛�/鍥剧墖绛夐潪澶ч潰绉壊鍧楄壊鍊�-->
+ <color name="c2">#2C2C2C</color> <!--涓绘爣棰�/涓绘枃瀛楄壊-->
+ <!--涓绘爣棰�/涓绘枃瀛楄壊-->
+ <color name="c3">#C8D1E6</color> <!--Toolbar鏂囧瓧/鏅�氭寜閽瓸G鑹�-->
+ <!--鐐圭紑鑹�-->
+ <color name="c5">#888888</color> <!--鏅�氭枃妗�/寮曞/娆¤鏂囧瓧-->
+ <color name="c6">#CCCCCC</color> <!--缃伆/杈撳叆鎻愮ず-->
+
+ <!--搴曡壊/鍒嗗壊-->
+ <color name="c7">#F7F7F7</color> <!--瀹㈡埛绔簳鑹�/鍗$墖鎻忚竟-->
+ <color name="c8">#F2F2F2</color> <!--鍒嗗壊绾垮簳鑹�-->
+ <color name="c10">#FFFFFF</color> <!--鍙嶇櫧-->
+
+ <!--甯﹂�忔槑搴︾殑棰滆壊-->
+ <!--鍏ㄥ眬閬僵-->
+ <color name="c14">#7FF18D00</color> <!--寮鸿皟閽畃ressed-->
+ <color name="c15">#7FF18D00</color> <!--寮鸿皟閽甦isabled-->
+ <!--鏅�氶挳pressed-->
+ <!--鏅�氶挳disabled-->
+
+ <!--鎴愬姛澶辫触鎻愮ず-->
+ <color name="c12">#EF6545</color> <!--鍒犻櫎銆佽绀鸿壊锛涙坊鍔犺澶囪秴鏃剁孩鐏枃妗�-->
+ <color name="color_background">#ffffff</color>
+ <color name="transparent">#00000000</color>
+
+ <!--鏂癠I瑙勮寖棰滆壊鍊肩粺涓�鍛藉悕-->
+ <color name="color5">#424243</color>
+ <color name="color9">#cccccc</color>
+</resources>
diff --git a/third-zxing/src/main/res/values/ids.xml b/third-zxing/src/main/res/values/ids.xml
new file mode 100644
index 0000000..c16e2a0
--- /dev/null
+++ b/third-zxing/src/main/res/values/ids.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <item name="decode" type="id"/>
+ <item name="decode_failed" type="id"/>
+ <item name="decode_succeeded" type="id"/>
+ <item name="quit" type="id"/>
+ <item name="restart_preview" type="id"/>
+ <item name="return_scan_result" type="id"/>
+</resources>
\ No newline at end of file
diff --git a/third-zxing/src/main/res/values/strings.xml b/third-zxing/src/main/res/values/strings.xml
new file mode 100644
index 0000000..64eefbe
--- /dev/null
+++ b/third-zxing/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+<resources>
+ <string name="app_name">third_zxing2</string>
+ <string name="scan_title">浜岀淮鐮佹壂鎻�</string>
+
+ <!--鎵爜-->
+ <string name="zxing_scan_tips">灏嗕簩缁寸爜鏀惧叆妗嗗唴锛屽嵆鍙嚜鍔ㄦ壂鎻�</string>
+ <string name="capture_no_camera">娌℃湁璁块棶鐩告満鐨勬潈闄愶紝璇锋墦寮�璁块棶鏉冮檺鍐嶈瘯</string>
+ <string name="capture_no_result">娌℃湁鎵弿鍑虹粨鏋�</string>
+ <string name="capture_no_network">褰撳墠缃戠粶涓嶅彲鐢�,璇锋鏌ョ綉缁滃悗鍐嶈瘯</string>
+ <string name="capture_no_result2">娌℃湁鎵弿鍑虹粨鏋滐紝鍙兘涓嶆槸鏈夋晥鐨勪簩缁寸爜</string>
+ <string name="scan_cancel">鍙栨秷</string>
+
+</resources>
diff --git a/third-zxing/src/main/res/values/styles.xml b/third-zxing/src/main/res/values/styles.xml
new file mode 100644
index 0000000..956c150
--- /dev/null
+++ b/third-zxing/src/main/res/values/styles.xml
@@ -0,0 +1,24 @@
+<resources>
+
+ <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
+ <item name="android:windowBackground">@color/color_background</item>
+ <item name="android:listViewStyle">@style/List</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:textViewStyle">@style/TextView</item>
+ <item name="android:disabledAlpha">1</item>
+ <item name="android:listDivider">@drawable/transparent_divider</item>
+ </style>
+
+ <style name="List" parent="@android:style/Widget.ListView">
+ <item name="android:listSelector">@color/transparent</item>
+ <item name="android:cacheColorHint">@color/transparent</item>
+ <item name="android:divider">@null</item>
+ </style>
+
+
+ <style name="TextView" parent="@android:style/Widget.TextView">
+ <item name="android:textColorHint">@color/color9</item>
+ <item name="android:textColor">@color/color5</item>
+ <item name="android:textSize">14sp</item>
+ </style>
+</resources>
--
Gitblit v1.8.0