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