移除zxing库。
parent
985b06e3d6
commit
8aa8449173
Binary file not shown.
@ -0,0 +1,45 @@
|
|||||||
|
package com.rehome.bhdxj.Listener
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.camera.core.ImageAnalysis
|
||||||
|
import androidx.camera.core.ImageProxy
|
||||||
|
import com.google.mlkit.vision.barcode.Barcode
|
||||||
|
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
|
||||||
|
import com.google.mlkit.vision.barcode.BarcodeScanning
|
||||||
|
import com.google.mlkit.vision.common.InputImage
|
||||||
|
|
||||||
|
class QRCodeAnalyser(private val listener: (List<Barcode>, Int, Int) -> Unit) :
|
||||||
|
ImageAnalysis.Analyzer {
|
||||||
|
//配置当前扫码格式
|
||||||
|
private val options = BarcodeScannerOptions.Builder()
|
||||||
|
.setBarcodeFormats(
|
||||||
|
Barcode.FORMAT_QR_CODE,
|
||||||
|
Barcode.FORMAT_AZTEC
|
||||||
|
).build()
|
||||||
|
|
||||||
|
//获取解析器
|
||||||
|
private val detector = BarcodeScanning.getClient(options)
|
||||||
|
|
||||||
|
@SuppressLint("UnsafeExperimentalUsageError", "UnsafeOptInUsageError")
|
||||||
|
override fun analyze(imageProxy: ImageProxy) {
|
||||||
|
val mediaImage = imageProxy.image ?: kotlin.run {
|
||||||
|
imageProxy.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
|
||||||
|
detector.process(image)
|
||||||
|
.addOnSuccessListener { barCodes ->
|
||||||
|
Log.i("app", "barCodes: ${barCodes.size}")
|
||||||
|
if (barCodes.size > 0) {
|
||||||
|
listener.invoke(barCodes, imageProxy.width, imageProxy.height)
|
||||||
|
//接收到结果后,就关闭解析
|
||||||
|
detector.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.addOnFailureListener { Log.i("app", "Error: ${it.message}") }
|
||||||
|
.addOnCompleteListener { imageProxy.close() }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
final class AutoFocusCallback implements Camera.AutoFocusCallback {
|
|
||||||
|
|
||||||
private static final String TAG = AutoFocusCallback.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final long AUTOFOCUS_INTERVAL_MS = 1500L;
|
|
||||||
|
|
||||||
private Handler autoFocusHandler;
|
|
||||||
private int autoFocusMessage;
|
|
||||||
|
|
||||||
void setHandler(Handler autoFocusHandler, int autoFocusMessage) {
|
|
||||||
this.autoFocusHandler = autoFocusHandler;
|
|
||||||
this.autoFocusMessage = autoFocusMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAutoFocus(boolean success, Camera camera) {
|
|
||||||
if (autoFocusHandler != null) {
|
|
||||||
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
|
||||||
autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS);
|
|
||||||
autoFocusHandler = null;
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Got auto-focus callback, but no handler for it");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,283 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Display;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
final class CameraConfigurationManager {
|
|
||||||
|
|
||||||
private static final String TAG = CameraConfigurationManager.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final int TEN_DESIRED_ZOOM = 27;
|
|
||||||
private static final int DESIRED_SHARPNESS = 30;
|
|
||||||
|
|
||||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
private Point screenResolution;
|
|
||||||
private Point cameraResolution;
|
|
||||||
private int previewFormat;
|
|
||||||
private String previewFormatString;
|
|
||||||
|
|
||||||
CameraConfigurationManager(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads, one time, values from the camera that are needed by the app.
|
|
||||||
*/
|
|
||||||
void initFromCameraParameters(Camera camera) {
|
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
|
||||||
previewFormat = parameters.getPreviewFormat();
|
|
||||||
previewFormatString = parameters.get("preview-format");
|
|
||||||
Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
|
|
||||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
Display display = manager.getDefaultDisplay();
|
|
||||||
screenResolution = new Point(display.getWidth(), display.getHeight());
|
|
||||||
Log.d(TAG, "Screen resolution: " + screenResolution);
|
|
||||||
cameraResolution = getCameraResolution(parameters, screenResolution);
|
|
||||||
Log.d(TAG, "Camera resolution: " + screenResolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the camera up to take preview images which are used for both preview and decoding.
|
|
||||||
* We detect the preview format here so that buildLuminanceSource() can build an appropriate
|
|
||||||
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest,
|
|
||||||
* and the planar Y can be used for barcode scanning without background copy in some cases.
|
|
||||||
*/
|
|
||||||
void setDesiredCameraParameters(Camera camera) {
|
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
|
||||||
Log.d(TAG, "Setting preview size: " + cameraResolution);
|
|
||||||
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
|
|
||||||
setFlash(parameters);
|
|
||||||
setZoom(parameters);
|
|
||||||
setDisplayOrientation(camera, 90);
|
|
||||||
camera.setParameters(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
Point getCameraResolution() {
|
|
||||||
return cameraResolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point getScreenResolution() {
|
|
||||||
return screenResolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getPreviewFormat() {
|
|
||||||
return previewFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getPreviewFormatString() {
|
|
||||||
return previewFormatString;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) {
|
|
||||||
|
|
||||||
String previewSizeValueString = parameters.get("preview-size-values");
|
|
||||||
// saw this on Xperia
|
|
||||||
if (previewSizeValueString == null) {
|
|
||||||
previewSizeValueString = parameters.get("preview-size-value");
|
|
||||||
}
|
|
||||||
|
|
||||||
Point cameraResolution = null;
|
|
||||||
|
|
||||||
if (previewSizeValueString != null) {
|
|
||||||
Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString);
|
|
||||||
cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cameraResolution == null) {
|
|
||||||
// Ensure that the camera resolution is background multiple of 8, as the screen may not be.
|
|
||||||
cameraResolution = new Point(
|
|
||||||
(screenResolution.x >> 3) << 3,
|
|
||||||
(screenResolution.y >> 3) << 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cameraResolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {
|
|
||||||
int bestX = 0;
|
|
||||||
int bestY = 0;
|
|
||||||
int diff = Integer.MAX_VALUE;
|
|
||||||
for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {
|
|
||||||
|
|
||||||
previewSize = previewSize.trim();
|
|
||||||
int dimPosition = previewSize.indexOf('x');
|
|
||||||
if (dimPosition < 0) {
|
|
||||||
Log.w(TAG, "Bad preview-size: " + previewSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int newX;
|
|
||||||
int newY;
|
|
||||||
try {
|
|
||||||
newX = Integer.parseInt(previewSize.substring(0, dimPosition));
|
|
||||||
newY = Integer.parseInt(previewSize.substring(dimPosition + 1));
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
Log.w(TAG, "Bad preview-size: " + previewSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
|
|
||||||
if (newDiff == 0) {
|
|
||||||
bestX = newX;
|
|
||||||
bestY = newY;
|
|
||||||
break;
|
|
||||||
} else if (newDiff < diff) {
|
|
||||||
bestX = newX;
|
|
||||||
bestY = newY;
|
|
||||||
diff = newDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bestX > 0 && bestY > 0) {
|
|
||||||
return new Point(bestX, bestY);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) {
|
|
||||||
int tenBestValue = 0;
|
|
||||||
for (String stringValue : COMMA_PATTERN.split(stringValues)) {
|
|
||||||
stringValue = stringValue.trim();
|
|
||||||
double value;
|
|
||||||
try {
|
|
||||||
value = Double.parseDouble(stringValue);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
return tenDesiredZoom;
|
|
||||||
}
|
|
||||||
int tenValue = (int) (10.0 * value);
|
|
||||||
if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) {
|
|
||||||
tenBestValue = tenValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tenBestValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setFlash(Camera.Parameters parameters) {
|
|
||||||
// FIXME: This is background hack to turn the flash off on the Samsung Galaxy.
|
|
||||||
// And this is background hack-hack to work around background different value on the Behold II
|
|
||||||
// Restrict Behold II check to Cupcake, per Samsung's advice
|
|
||||||
//if (Build.MODEL.contains("Behold II") &&
|
|
||||||
// CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) {
|
|
||||||
if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // icon3 = Cupcake
|
|
||||||
parameters.set("flash-value", 1);
|
|
||||||
} else {
|
|
||||||
parameters.set("flash-value", 2);
|
|
||||||
}
|
|
||||||
// This is the standard setting to turn the flash off that all devices should honor.
|
|
||||||
parameters.set("flash-mode", "off");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setZoom(Camera.Parameters parameters) {
|
|
||||||
|
|
||||||
String zoomSupportedString = parameters.get("zoom-supported");
|
|
||||||
if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tenDesiredZoom = TEN_DESIRED_ZOOM;
|
|
||||||
|
|
||||||
String maxZoomString = parameters.get("max-zoom");
|
|
||||||
if (maxZoomString != null) {
|
|
||||||
try {
|
|
||||||
int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString));
|
|
||||||
if (tenDesiredZoom > tenMaxZoom) {
|
|
||||||
tenDesiredZoom = tenMaxZoom;
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
Log.w(TAG, "Bad max-zoom: " + maxZoomString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max");
|
|
||||||
if (takingPictureZoomMaxString != null) {
|
|
||||||
try {
|
|
||||||
int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString);
|
|
||||||
if (tenDesiredZoom > tenMaxZoom) {
|
|
||||||
tenDesiredZoom = tenMaxZoom;
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String motZoomValuesString = parameters.get("mot-zoom-values");
|
|
||||||
if (motZoomValuesString != null) {
|
|
||||||
tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
String motZoomStepString = parameters.get("mot-zoom-step");
|
|
||||||
if (motZoomStepString != null) {
|
|
||||||
try {
|
|
||||||
double motZoomStep = Double.parseDouble(motZoomStepString.trim());
|
|
||||||
int tenZoomStep = (int) (10.0 * motZoomStep);
|
|
||||||
if (tenZoomStep > 1) {
|
|
||||||
tenDesiredZoom -= tenDesiredZoom % tenZoomStep;
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set zoom. This helps encourage the user to pull back.
|
|
||||||
// Some devices like the Behold have background zoom parameter
|
|
||||||
if (maxZoomString != null || motZoomValuesString != null) {
|
|
||||||
parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Most devices, like the Hero, appear to expose this zoom parameter.
|
|
||||||
// It takes on values like "27" which appears to mean icon2.7x zoom
|
|
||||||
if (takingPictureZoomMaxString != null) {
|
|
||||||
parameters.set("taking-picture-zoom", tenDesiredZoom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getDesiredSharpness() {
|
|
||||||
return DESIRED_SHARPNESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* compatible icon1.icon6
|
|
||||||
* @param camera
|
|
||||||
* @param angle
|
|
||||||
*/
|
|
||||||
protected void setDisplayOrientation(Camera camera, int angle){
|
|
||||||
Method downPolymorphic;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", int.class);
|
|
||||||
if (downPolymorphic != null)
|
|
||||||
downPolymorphic.invoke(camera, angle);
|
|
||||||
}
|
|
||||||
catch (Exception e1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,328 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.PixelFormat;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
|
|
||||||
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 final class CameraManager {
|
|
||||||
|
|
||||||
private static final String TAG = CameraManager.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final int MIN_FRAME_WIDTH = 350;
|
|
||||||
private static final int MIN_FRAME_HEIGHT = 350;
|
|
||||||
private static final int MAX_FRAME_WIDTH = 700;
|
|
||||||
private static final int MAX_FRAME_HEIGHT
|
|
||||||
= 630;
|
|
||||||
|
|
||||||
private static CameraManager cameraManager;
|
|
||||||
|
|
||||||
static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT
|
|
||||||
|
|
||||||
static {
|
|
||||||
int sdkInt;
|
|
||||||
try {
|
|
||||||
sdkInt = Integer.parseInt(Build.VERSION.SDK);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
// Just to be safe
|
|
||||||
sdkInt = 10000;
|
|
||||||
}
|
|
||||||
SDK_INT = sdkInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
private final CameraConfigurationManager configManager;
|
|
||||||
private static Camera camera;
|
|
||||||
private Rect framingRect;
|
|
||||||
private Rect framingRectInPreview;
|
|
||||||
private boolean initialized;
|
|
||||||
private boolean previewing;
|
|
||||||
private final boolean useOneShotPreviewCallback;
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
/**
|
|
||||||
* Autofocus callbacks arrive here, and are dispatched to the Handler which requested them.
|
|
||||||
*/
|
|
||||||
private final AutoFocusCallback autoFocusCallback;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes this static object with the Context of the calling Activity.
|
|
||||||
*
|
|
||||||
* @param context The Activity which wants to use the camera.
|
|
||||||
*/
|
|
||||||
public static void init(Context context) {
|
|
||||||
if (cameraManager == null) {
|
|
||||||
cameraManager = new CameraManager(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the CameraManager singleton instance.
|
|
||||||
*
|
|
||||||
* @return A reference to the CameraManager singleton.
|
|
||||||
*/
|
|
||||||
public static CameraManager get() {
|
|
||||||
return cameraManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Camera getCamera() {
|
|
||||||
return camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CameraManager(Context context) {
|
|
||||||
|
|
||||||
this.context = context;
|
|
||||||
this.configManager = new CameraConfigurationManager(context);
|
|
||||||
|
|
||||||
// Camera.setOneShotPreviewCallback() has background race condition in Cupcake, so we use the older
|
|
||||||
// Camera.setPreviewCallback() on icon1.icon5 and earlier. For Donut and later, we need to use
|
|
||||||
// the more efficient one shot callback, as the older one can swamp the system and cause it
|
|
||||||
// to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK.
|
|
||||||
//useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE;
|
|
||||||
useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // icon3 = Cupcake
|
|
||||||
|
|
||||||
previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback);
|
|
||||||
autoFocusCallback = new AutoFocusCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 void openDriver(SurfaceHolder holder) throws IOException {
|
|
||||||
if (camera == null) {
|
|
||||||
camera = Camera.open();
|
|
||||||
if (camera == null) {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
camera.setPreviewDisplay(holder);
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = true;
|
|
||||||
configManager.initFromCameraParameters(camera);
|
|
||||||
}
|
|
||||||
configManager.setDesiredCameraParameters(camera);
|
|
||||||
|
|
||||||
|
|
||||||
FlashlightManager.enableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the camera driver if still in use.
|
|
||||||
*/
|
|
||||||
public void closeDriver() {
|
|
||||||
if (camera != null) {
|
|
||||||
FlashlightManager.disableFlashlight();
|
|
||||||
camera.release();
|
|
||||||
camera = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asks the camera hardware to begin drawing preview frames to the screen.
|
|
||||||
*/
|
|
||||||
public void startPreview() {
|
|
||||||
if (camera != null && !previewing) {
|
|
||||||
camera.startPreview();
|
|
||||||
previewing = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells the camera to stop drawing preview frames.
|
|
||||||
*/
|
|
||||||
public void stopPreview() {
|
|
||||||
if (camera != null && previewing) {
|
|
||||||
if (!useOneShotPreviewCallback) {
|
|
||||||
camera.setPreviewCallback(null);
|
|
||||||
}
|
|
||||||
camera.stopPreview();
|
|
||||||
previewCallback.setHandler(null, 0);
|
|
||||||
autoFocusCallback.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 void requestPreviewFrame(Handler handler, int message) {
|
|
||||||
if (camera != null && previewing) {
|
|
||||||
previewCallback.setHandler(handler, message);
|
|
||||||
if (useOneShotPreviewCallback) {
|
|
||||||
camera.setOneShotPreviewCallback(previewCallback);
|
|
||||||
} else {
|
|
||||||
camera.setPreviewCallback(previewCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asks the camera hardware to perform an autofocus.
|
|
||||||
*
|
|
||||||
* @param handler The Handler to notify when the autofocus completes.
|
|
||||||
* @param message The message to deliver.
|
|
||||||
*/
|
|
||||||
public void requestAutoFocus(Handler handler, int message) {
|
|
||||||
if (camera != null && previewing) {
|
|
||||||
autoFocusCallback.setHandler(handler, message);
|
|
||||||
//Log.d(TAG, "Requesting auto-focus callback");
|
|
||||||
camera.autoFocus(autoFocusCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the framing rect which the UI should draw to show the user where to place the
|
|
||||||
* barcode. This target helps with alignment as well as forces the user to hold the device
|
|
||||||
* far enough away to ensure the image will be in focus.
|
|
||||||
*
|
|
||||||
* @return The rectangle to draw on screen in window coordinates.
|
|
||||||
*/
|
|
||||||
public Rect getFramingRect() {
|
|
||||||
Point screenResolution = configManager.getScreenResolution();
|
|
||||||
if (framingRect == null) {
|
|
||||||
if (camera == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int width = screenResolution.x * 3 / 4;
|
|
||||||
if (width < MIN_FRAME_WIDTH) {
|
|
||||||
width = MIN_FRAME_WIDTH;
|
|
||||||
} else if (width > MAX_FRAME_WIDTH) {
|
|
||||||
width = MAX_FRAME_WIDTH;
|
|
||||||
}
|
|
||||||
int height = screenResolution.y * 3 / 4;
|
|
||||||
if (height < MIN_FRAME_HEIGHT) {
|
|
||||||
height = MIN_FRAME_HEIGHT;
|
|
||||||
} else if (height > MAX_FRAME_HEIGHT) {
|
|
||||||
height = MAX_FRAME_HEIGHT;
|
|
||||||
}
|
|
||||||
int leftOffset = (screenResolution.x - width) / 2;
|
|
||||||
int topOffset = (screenResolution.y - height) / 2;
|
|
||||||
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
|
|
||||||
Log.d(TAG, "Calculated framing rect: " + framingRect);
|
|
||||||
}
|
|
||||||
return framingRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
|
|
||||||
* not UI / screen.
|
|
||||||
*/
|
|
||||||
public Rect getFramingRectInPreview() {
|
|
||||||
if (framingRectInPreview == null) {
|
|
||||||
Rect rect = new Rect(getFramingRect());
|
|
||||||
Point cameraResolution = configManager.getCameraResolution();
|
|
||||||
Point screenResolution = configManager.getScreenResolution();
|
|
||||||
//modify here
|
|
||||||
// rect.left = rect.left * cameraResolution.x / screenResolution.x;
|
|
||||||
// rect.right = rect.right * cameraResolution.x / screenResolution.x;
|
|
||||||
// rect.top = rect.top * cameraResolution.y / screenResolution.y;
|
|
||||||
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
|
|
||||||
rect.left = rect.left * cameraResolution.y / screenResolution.x;
|
|
||||||
rect.right = rect.right * cameraResolution.y / screenResolution.x;
|
|
||||||
rect.top = rect.top * cameraResolution.x / screenResolution.y;
|
|
||||||
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
|
|
||||||
framingRectInPreview = rect;
|
|
||||||
}
|
|
||||||
return framingRectInPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the result points from still resolution coordinates to screen coordinates.
|
|
||||||
*
|
|
||||||
* @param points The points returned by the Reader subclass through Result.getResultPoints().
|
|
||||||
* @return An array of Points scaled to the size of the framing rect and offset appropriately
|
|
||||||
* so they can be drawn in screen coordinates.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public Point[] convertResultPoints(ResultPoint[] points) {
|
|
||||||
Rect frame = getFramingRectInPreview();
|
|
||||||
int count = points.length;
|
|
||||||
Point[] output = new Point[count];
|
|
||||||
for (int x = 0; x < count; x++) {
|
|
||||||
output[x] = new Point();
|
|
||||||
output[x].x = frame.left + (int) (points[x].getX() + 0.5f);
|
|
||||||
output[x].y = frame.top + (int) (points[x].getY() + 0.5f);
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 = getFramingRectInPreview();
|
|
||||||
int previewFormat = configManager.getPreviewFormat();
|
|
||||||
String previewFormatString = configManager.getPreviewFormatString();
|
|
||||||
switch (previewFormat) {
|
|
||||||
// This is the standard Android format which all devices are REQUIRED to support.
|
|
||||||
// In theory, it's the only one we should ever care about.
|
|
||||||
case PixelFormat.YCbCr_420_SP:
|
|
||||||
// This format has never been seen in the wild, but is compatible as we only care
|
|
||||||
// about the Y channel, so allow it.
|
|
||||||
case PixelFormat.YCbCr_422_SP:
|
|
||||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
|
||||||
rect.width(), rect.height());
|
|
||||||
default:
|
|
||||||
// The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
|
|
||||||
// Fortunately, it too has all the Y data up front, so we can read it.
|
|
||||||
if ("yuv420p".equals(previewFormatString)) {
|
|
||||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
|
||||||
rect.width(), rect.height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unsupported picture format: " +
|
|
||||||
previewFormat + '/' + previewFormatString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is used to activate the weak light on some camera phones (not flash)
|
|
||||||
* in order to illuminate surfaces for scanning. There is no official way to do this,
|
|
||||||
* but, classes which allow access to this function still exist on some devices.
|
|
||||||
* This therefore proceeds through background great deal of reflection.
|
|
||||||
*
|
|
||||||
* See <background href="http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/">
|
|
||||||
* http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/</background> and
|
|
||||||
* <background href="http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java">
|
|
||||||
* http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java</background>.
|
|
||||||
* Thanks to Ryan Alford for pointing out the availability of this class.
|
|
||||||
*/
|
|
||||||
final class FlashlightManager {
|
|
||||||
|
|
||||||
private static final String TAG = FlashlightManager.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final Object iHardwareService;
|
|
||||||
private static final Method setFlashEnabledMethod;
|
|
||||||
static {
|
|
||||||
iHardwareService = getHardwareService();
|
|
||||||
setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService);
|
|
||||||
if (iHardwareService == null) {
|
|
||||||
Log.v(TAG, "This device does supports control of background flashlight");
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "This device does not support control of background flashlight");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private FlashlightManager() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//FIXME
|
|
||||||
static void enableFlashlight() {
|
|
||||||
setFlashlight(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disableFlashlight() {
|
|
||||||
setFlashlight(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getHardwareService() {
|
|
||||||
Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager");
|
|
||||||
if (serviceManagerClass == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class);
|
|
||||||
if (getServiceMethod == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object hardwareService = invoke(getServiceMethod, null, "hardware");
|
|
||||||
if (hardwareService == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub");
|
|
||||||
if (iHardwareServiceStubClass == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class);
|
|
||||||
if (asInterfaceMethod == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return invoke(asInterfaceMethod, null, hardwareService);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method getSetFlashEnabledMethod(Object iHardwareService) {
|
|
||||||
if (iHardwareService == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Class<?> proxyClass = iHardwareService.getClass();
|
|
||||||
return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?> maybeForName(String name) {
|
|
||||||
try {
|
|
||||||
return Class.forName(name);
|
|
||||||
} catch (ClassNotFoundException cnfe) {
|
|
||||||
// OK
|
|
||||||
return null;
|
|
||||||
} catch (RuntimeException re) {
|
|
||||||
Log.w(TAG, "Unexpected error while finding class " + name, re);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method maybeGetMethod(Class<?> clazz, String name, Class<?>... argClasses) {
|
|
||||||
try {
|
|
||||||
return clazz.getMethod(name, argClasses);
|
|
||||||
} catch (NoSuchMethodException nsme) {
|
|
||||||
// OK
|
|
||||||
return null;
|
|
||||||
} catch (RuntimeException re) {
|
|
||||||
Log.w(TAG, "Unexpected error while finding method " + name, re);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object invoke(Method method, Object instance, Object... args) {
|
|
||||||
try {
|
|
||||||
return method.invoke(instance, args);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
Log.w(TAG, "Unexpected error while invoking " + method, e);
|
|
||||||
return null;
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
Log.w(TAG, "Unexpected error while invoking " + method, e.getCause());
|
|
||||||
return null;
|
|
||||||
} catch (RuntimeException re) {
|
|
||||||
Log.w(TAG, "Unexpected error while invoking " + method, re);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setFlashlight(boolean active) {
|
|
||||||
if (iHardwareService != null) {
|
|
||||||
invoke(setFlashEnabledMethod, iHardwareService, active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
import com.google.zxing.LuminanceSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This object extends LuminanceSource around an array of YUV data returned from the camera driver,
|
|
||||||
* with the option to crop to background rectangle within the full data. This can be used to exclude
|
|
||||||
* superfluous pixels around the perimeter and speed up decoding.
|
|
||||||
*
|
|
||||||
* It works for any pixel format where the Y channel is planar and appears first, including
|
|
||||||
* YCbCr_420_SP and YCbCr_422_SP.
|
|
||||||
*
|
|
||||||
* @author dswitkin@google.com (Daniel Switkin)
|
|
||||||
*/
|
|
||||||
public final class PlanarYUVLuminanceSource extends LuminanceSource {
|
|
||||||
private final byte[] yuvData;
|
|
||||||
private final int dataWidth;
|
|
||||||
private final int dataHeight;
|
|
||||||
private final int left;
|
|
||||||
private final int top;
|
|
||||||
|
|
||||||
public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top,
|
|
||||||
int width, int height) {
|
|
||||||
super(width, height);
|
|
||||||
|
|
||||||
if (left + width > dataWidth || top + height > dataHeight) {
|
|
||||||
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.yuvData = yuvData;
|
|
||||||
this.dataWidth = dataWidth;
|
|
||||||
this.dataHeight = dataHeight;
|
|
||||||
this.left = left;
|
|
||||||
this.top = top;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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];
|
|
||||||
}
|
|
||||||
int offset = (y + top) * dataWidth + left;
|
|
||||||
System.arraycopy(yuvData, offset, row, 0, width);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getMatrix() {
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
|
|
||||||
// If the caller asks for the entire underlying image, save the copy and give them the
|
|
||||||
// original data. The docs specifically warn that result.length must be ignored.
|
|
||||||
if (width == dataWidth && height == dataHeight) {
|
|
||||||
return yuvData;
|
|
||||||
}
|
|
||||||
|
|
||||||
int area = width * height;
|
|
||||||
byte[] matrix = new byte[area];
|
|
||||||
int inputOffset = top * dataWidth + left;
|
|
||||||
|
|
||||||
// If the width matches the full width of the underlying data, perform background single copy.
|
|
||||||
if (width == dataWidth) {
|
|
||||||
System.arraycopy(yuvData, inputOffset, matrix, 0, area);
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise copy one cropped row at background time.
|
|
||||||
byte[] yuv = yuvData;
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
int outputOffset = y * width;
|
|
||||||
System.arraycopy(yuv, inputOffset, matrix, outputOffset, width);
|
|
||||||
inputOffset += dataWidth;
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCropSupported() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDataWidth() {
|
|
||||||
return dataWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDataHeight() {
|
|
||||||
return dataHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap renderCroppedGreyscaleBitmap() {
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
int[] pixels = new int[width * height];
|
|
||||||
byte[] yuv = yuvData;
|
|
||||||
int inputOffset = top * dataWidth + left;
|
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
int outputOffset = y * width;
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
int grey = yuv[inputOffset + x] & 0xff;
|
|
||||||
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
|
|
||||||
}
|
|
||||||
inputOffset += dataWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.camera;
|
|
||||||
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
final class PreviewCallback implements Camera.PreviewCallback {
|
|
||||||
|
|
||||||
private static final String TAG = PreviewCallback.class.getSimpleName();
|
|
||||||
|
|
||||||
private final CameraConfigurationManager configManager;
|
|
||||||
private final boolean useOneShotPreviewCallback;
|
|
||||||
private Handler previewHandler;
|
|
||||||
private int previewMessage;
|
|
||||||
|
|
||||||
PreviewCallback(CameraConfigurationManager configManager, boolean useOneShotPreviewCallback) {
|
|
||||||
this.configManager = configManager;
|
|
||||||
this.useOneShotPreviewCallback = useOneShotPreviewCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHandler(Handler previewHandler, int previewMessage) {
|
|
||||||
this.previewHandler = previewHandler;
|
|
||||||
this.previewMessage = previewMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
|
||||||
Point cameraResolution = configManager.getCameraResolution();
|
|
||||||
if (!useOneShotPreviewCallback) {
|
|
||||||
camera.setPreviewCallback(null);
|
|
||||||
}
|
|
||||||
if (previewHandler != null) {
|
|
||||||
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
|
|
||||||
cameraResolution.y, data);
|
|
||||||
message.sendToTarget();
|
|
||||||
previewHandler = null;
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Got preview callback, but no handler for it");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
final class DecodeFormatManager {
|
|
||||||
|
|
||||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
|
||||||
|
|
||||||
static final Vector<BarcodeFormat> PRODUCT_FORMATS;
|
|
||||||
static final Vector<BarcodeFormat> ONE_D_FORMATS;
|
|
||||||
static final Vector<BarcodeFormat> QR_CODE_FORMATS;
|
|
||||||
static final Vector<BarcodeFormat> DATA_MATRIX_FORMATS;
|
|
||||||
static {
|
|
||||||
PRODUCT_FORMATS = new Vector<BarcodeFormat>(5);
|
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_A);
|
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_E);
|
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_13);
|
|
||||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_8);
|
|
||||||
ONE_D_FORMATS = new Vector<BarcodeFormat>(PRODUCT_FORMATS.size() + 4);
|
|
||||||
ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
|
|
||||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_39);
|
|
||||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_93);
|
|
||||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_128);
|
|
||||||
ONE_D_FORMATS.add(BarcodeFormat.ITF);
|
|
||||||
QR_CODE_FORMATS = new Vector<BarcodeFormat>(1);
|
|
||||||
QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE);
|
|
||||||
DATA_MATRIX_FORMATS = new Vector<BarcodeFormat>(1);
|
|
||||||
DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DecodeFormatManager() {}
|
|
||||||
|
|
||||||
static Vector<BarcodeFormat> parseDecodeFormats(Intent intent) {
|
|
||||||
List<String> scanFormats = null;
|
|
||||||
String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS);
|
|
||||||
if (scanFormatsString != null) {
|
|
||||||
scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
|
|
||||||
}
|
|
||||||
return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
|
|
||||||
List<String> formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS);
|
|
||||||
if (formats != null && formats.size() == 1 && formats.get(0) != null){
|
|
||||||
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
|
|
||||||
}
|
|
||||||
return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Vector<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
|
|
||||||
String decodeMode) {
|
|
||||||
if (scanFormats != null) {
|
|
||||||
Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
|
|
||||||
try {
|
|
||||||
for (String format : scanFormats) {
|
|
||||||
formats.add(BarcodeFormat.valueOf(format));
|
|
||||||
}
|
|
||||||
return formats;
|
|
||||||
} catch (IllegalArgumentException iae) {
|
|
||||||
// ignore it then
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (decodeMode != null) {
|
|
||||||
if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
|
|
||||||
return PRODUCT_FORMATS;
|
|
||||||
}
|
|
||||||
if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
|
|
||||||
return QR_CODE_FORMATS;
|
|
||||||
}
|
|
||||||
if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
|
|
||||||
return DATA_MATRIX_FORMATS;
|
|
||||||
}
|
|
||||||
if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
|
|
||||||
return ONE_D_FORMATS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.google.zxing.BinaryBitmap;
|
|
||||||
import com.google.zxing.DecodeHintType;
|
|
||||||
import com.google.zxing.MultiFormatReader;
|
|
||||||
import com.google.zxing.ReaderException;
|
|
||||||
import com.google.zxing.Result;
|
|
||||||
import com.google.zxing.common.HybridBinarizer;
|
|
||||||
import com.rehome.bhdxj.R;
|
|
||||||
import com.rehome.bhdxj.base.MipcaActivityCapture;
|
|
||||||
import com.rehome.bhdxj.zxing.camera.CameraManager;
|
|
||||||
import com.rehome.bhdxj.zxing.camera.PlanarYUVLuminanceSource;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
final class DecodeHandler extends Handler {
|
|
||||||
|
|
||||||
private static final String TAG = DecodeHandler.class.getSimpleName();
|
|
||||||
|
|
||||||
private final MipcaActivityCapture activity;
|
|
||||||
private final MultiFormatReader multiFormatReader;
|
|
||||||
|
|
||||||
DecodeHandler(MipcaActivityCapture activity, Hashtable<DecodeHintType, Object> hints) {
|
|
||||||
multiFormatReader = new MultiFormatReader();
|
|
||||||
multiFormatReader.setHints(hints);
|
|
||||||
this.activity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message message) {
|
|
||||||
if(message.what==R.id.decode){
|
|
||||||
decode((byte[]) message.obj, message.arg1, message.arg2);
|
|
||||||
}
|
|
||||||
if(message.what==R.id.quit){
|
|
||||||
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) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
Result rawResult = null;
|
|
||||||
|
|
||||||
//modify here
|
|
||||||
byte[] rotatedData = new byte[data.length];
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
for (int x = 0; x < width; x++)
|
|
||||||
rotatedData[x * height + height - y - 1] = data[x + y * width];
|
|
||||||
}
|
|
||||||
int tmp = width; // Here we are swapping, that's the difference to #11
|
|
||||||
width = height;
|
|
||||||
height = tmp;
|
|
||||||
|
|
||||||
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);
|
|
||||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
|
||||||
try {
|
|
||||||
rawResult = multiFormatReader.decodeWithState(bitmap);
|
|
||||||
} catch (ReaderException re) {
|
|
||||||
// continue
|
|
||||||
} finally {
|
|
||||||
multiFormatReader.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rawResult != null) {
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
|
|
||||||
Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
|
|
||||||
message.setData(bundle);
|
|
||||||
//Log.d(TAG, "Sending decode succeeded message...");
|
|
||||||
message.sendToTarget();
|
|
||||||
} else {
|
|
||||||
Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
|
|
||||||
message.sendToTarget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
|
||||||
import com.google.zxing.DecodeHintType;
|
|
||||||
import com.google.zxing.ResultPointCallback;
|
|
||||||
import com.rehome.bhdxj.base.MipcaActivityCapture;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
|
||||||
|
|
||||||
final class DecodeThread extends Thread {
|
|
||||||
public static final String BARCODE_BITMAP = "barcode_bitmap";
|
|
||||||
private final MipcaActivityCapture activity;
|
|
||||||
private final Hashtable<DecodeHintType, Object> hints;
|
|
||||||
private Handler handler;
|
|
||||||
private final CountDownLatch handlerInitLatch;
|
|
||||||
|
|
||||||
DecodeThread(MipcaActivityCapture activity,
|
|
||||||
Vector<BarcodeFormat> decodeFormats,
|
|
||||||
String characterSet,
|
|
||||||
ResultPointCallback resultPointCallback) {
|
|
||||||
|
|
||||||
this.activity = activity;
|
|
||||||
handlerInitLatch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
hints = new Hashtable<DecodeHintType, Object>(3);
|
|
||||||
|
|
||||||
if (decodeFormats == null || decodeFormats.isEmpty()) {
|
|
||||||
decodeFormats = new Vector<BarcodeFormat>();
|
|
||||||
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
|
|
||||||
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
|
|
||||||
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
|
|
||||||
}
|
|
||||||
|
|
||||||
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
|
|
||||||
|
|
||||||
if (characterSet != null) {
|
|
||||||
hints.put(DecodeHintType.CHARACTER_SET, characterSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple listener used to exit the app in background few cases.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class FinishListener
|
|
||||||
implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, Runnable {
|
|
||||||
|
|
||||||
private final Activity activityToFinish;
|
|
||||||
|
|
||||||
public FinishListener(Activity activityToFinish) {
|
|
||||||
this.activityToFinish = activityToFinish;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onCancel(DialogInterface dialogInterface) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
activityToFinish.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finishes an activity after background period of inactivity.
|
|
||||||
*/
|
|
||||||
public final class InactivityTimer {
|
|
||||||
|
|
||||||
private static final int INACTIVITY_DELAY_SECONDS = 5 * 60;
|
|
||||||
|
|
||||||
private final ScheduledExecutorService inactivityTimer =
|
|
||||||
Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
|
|
||||||
private final Activity activity;
|
|
||||||
private ScheduledFuture<?> inactivityFuture = null;
|
|
||||||
|
|
||||||
public InactivityTimer(Activity activity) {
|
|
||||||
this.activity = activity;
|
|
||||||
onActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onActivity() {
|
|
||||||
cancel();
|
|
||||||
inactivityFuture = inactivityTimer.schedule(new FinishListener(activity),
|
|
||||||
INACTIVITY_DELAY_SECONDS,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel() {
|
|
||||||
if (inactivityFuture != null) {
|
|
||||||
inactivityFuture.cancel(true);
|
|
||||||
inactivityFuture = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
cancel();
|
|
||||||
inactivityTimer.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class DaemonThreadFactory implements ThreadFactory {
|
|
||||||
public Thread newThread(Runnable runnable) {
|
|
||||||
Thread thread = new Thread(runnable);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.decoding;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides the constants to use when sending an Intent to Barcode Scanner.
|
|
||||||
* These strings are effectively API and cannot be changed.
|
|
||||||
*/
|
|
||||||
public final class Intents {
|
|
||||||
private Intents() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Scan {
|
|
||||||
/**
|
|
||||||
* Send this intent to open the Barcodes app in scanning mode, find background barcode, and return
|
|
||||||
* the results.
|
|
||||||
*/
|
|
||||||
public static final String ACTION = "com.google.zxing.client.android.SCAN";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, sending Scan.ACTION will decode all barcodes that we understand. However it
|
|
||||||
* may be useful to limit scanning to certain formats. Use Intent.putExtra(MODE, value) with
|
|
||||||
* one of the values below ({@link #PRODUCT_MODE}, {@link #ONE_D_MODE}, {@link #QR_CODE_MODE}).
|
|
||||||
* Optional.
|
|
||||||
*
|
|
||||||
* Setting this is effectively shorthnad for setting explicit formats with {@link #SCAN_FORMATS}.
|
|
||||||
* It is overridden by that setting.
|
|
||||||
*/
|
|
||||||
public static final String MODE = "SCAN_MODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comma-separated list of formats to scan for. The values must match the names of
|
|
||||||
* {@link com.google.zxing.BarcodeFormat}s, such as {@link com.google.zxing.BarcodeFormat#EAN_13}.
|
|
||||||
* Example: "EAN_13,EAN_8,QR_CODE"
|
|
||||||
*
|
|
||||||
* This overrides {@link #MODE}.
|
|
||||||
*/
|
|
||||||
public static final String SCAN_FORMATS = "SCAN_FORMATS";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see com.google.zxing.DecodeHintType#CHARACTER_SET
|
|
||||||
*/
|
|
||||||
public static final String CHARACTER_SET = "CHARACTER_SET";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get
|
|
||||||
* prices, reviews, etc. for products.
|
|
||||||
*/
|
|
||||||
public static final String PRODUCT_MODE = "PRODUCT_MODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode only 1D barcodes (currently UPC, EAN, Code 39, and Code 128).
|
|
||||||
*/
|
|
||||||
public static final String ONE_D_MODE = "ONE_D_MODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode only QR codes.
|
|
||||||
*/
|
|
||||||
public static final String QR_CODE_MODE = "QR_CODE_MODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode only Data Matrix codes.
|
|
||||||
*/
|
|
||||||
public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If background barcode is found, Barcodes returns RESULT_OK to onActivityResult() of the app which
|
|
||||||
* requested the scan via startSubActivity(). The barcodes contents can be retrieved with
|
|
||||||
* intent.getStringExtra(RESULT). If the user presses Back, the result code will be
|
|
||||||
* RESULT_CANCELED.
|
|
||||||
*/
|
|
||||||
public static final String RESULT = "SCAN_RESULT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call intent.getStringExtra(RESULT_FORMAT) to determine which barcode format was found.
|
|
||||||
* See Contents.Format for possible values.
|
|
||||||
*/
|
|
||||||
public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setting this to false will not save scanned codes in the history.
|
|
||||||
*/
|
|
||||||
public static final String SAVE_HISTORY = "SAVE_HISTORY";
|
|
||||||
|
|
||||||
private Scan() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Encode {
|
|
||||||
/**
|
|
||||||
* Send this intent to encode background piece of data as background QR code and display it full screen, so
|
|
||||||
* that another person can scan the barcode from your screen.
|
|
||||||
*/
|
|
||||||
public static final String ACTION = "com.google.zxing.client.android.ENCODE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The data to encode. Use Intent.putExtra(DATA, data) where data is either background String or background
|
|
||||||
* Bundle, depending on the type and format specified. Non-QR Code formats should
|
|
||||||
* just use background String here. For QR Code, see Contents for details.
|
|
||||||
*/
|
|
||||||
public static final String DATA = "ENCODE_DATA";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of data being supplied if the format is QR Code. Use
|
|
||||||
* Intent.putExtra(TYPE, type) with one of Contents.Type.
|
|
||||||
*/
|
|
||||||
public static final String TYPE = "ENCODE_TYPE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The barcode format to be displayed. If this isn't specified or is blank,
|
|
||||||
* it defaults to QR Code. Use Intent.putExtra(FORMAT, format), where
|
|
||||||
* format is one of Contents.Format.
|
|
||||||
*/
|
|
||||||
public static final String FORMAT = "ENCODE_FORMAT";
|
|
||||||
|
|
||||||
private Encode() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class SearchBookContents {
|
|
||||||
/**
|
|
||||||
* Use Google Book Search to search the contents of the book provided.
|
|
||||||
*/
|
|
||||||
public static final String ACTION = "com.google.zxing.client.android.SEARCH_BOOK_CONTENTS";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The book to search, identified by ISBN number.
|
|
||||||
*/
|
|
||||||
public static final String ISBN = "ISBN";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An optional field which is the text to search for.
|
|
||||||
*/
|
|
||||||
public static final String QUERY = "QUERY";
|
|
||||||
|
|
||||||
private SearchBookContents() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class WifiConnect {
|
|
||||||
/**
|
|
||||||
* Internal intent used to trigger connection to background wi-fi network.
|
|
||||||
*/
|
|
||||||
public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The network to connect to, all the configuration provided here.
|
|
||||||
*/
|
|
||||||
public static final String SSID = "SSID";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The network to connect to, all the configuration provided here.
|
|
||||||
*/
|
|
||||||
public static final String TYPE = "TYPE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The network to connect to, all the configuration provided here.
|
|
||||||
*/
|
|
||||||
public static final String PASSWORD = "PASSWORD";
|
|
||||||
|
|
||||||
private WifiConnect() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final class Share {
|
|
||||||
/**
|
|
||||||
* Give the user background choice of items to encode as background barcode, then render it as background QR Code and
|
|
||||||
* display onscreen for background friend to scan with their phone.
|
|
||||||
*/
|
|
||||||
public static final String ACTION = "com.google.zxing.client.android.SHARE";
|
|
||||||
|
|
||||||
private Share() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.rehome.bhdxj.zxing.view;
|
|
||||||
|
|
||||||
import com.google.zxing.ResultPoint;
|
|
||||||
import com.google.zxing.ResultPointCallback;
|
|
||||||
|
|
||||||
public final class ViewfinderResultPointCallback implements ResultPointCallback {
|
|
||||||
|
|
||||||
private final ViewfinderView viewfinderView;
|
|
||||||
|
|
||||||
public ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
|
|
||||||
this.viewfinderView = viewfinderView;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void foundPossibleResultPoint(ResultPoint point) {
|
|
||||||
viewfinderView.addPossibleResultPoint(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#00ffffff" />
|
||||||
|
|
||||||
|
<stroke
|
||||||
|
android:width="2dp"
|
||||||
|
android:color="#FF00FF00" />
|
||||||
|
<corners
|
||||||
|
android:bottomLeftRadius="1px"
|
||||||
|
android:bottomRightRadius="1px"
|
||||||
|
android:topLeftRadius="1px"
|
||||||
|
android:topRightRadius="1px" />
|
||||||
|
</shape>
|
||||||
@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<SurfaceView
|
|
||||||
android:id="@+id/preview_view"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_gravity="center"/>
|
|
||||||
|
|
||||||
<com.rehome.bhdxj.zxing.view.ViewfinderView
|
|
||||||
android:id="@+id/viewfinder_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/flashlightButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:text="打开闪光灯"
|
|
||||||
android:textColor="@color/white"/>
|
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".activity.QrCodeActivity">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/toolbarView"
|
||||||
|
layout="@layout/layout_base" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fr_camera"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.camera.view.PreviewView
|
||||||
|
android:id="@+id/previewView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/scan_bg"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<com.rehome.bhdxj.weight.ScanView
|
||||||
|
android:id="@+id/scanView"
|
||||||
|
android:layout_width="250dp"
|
||||||
|
android:layout_height="250dp"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/scan_text"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
Loading…
Reference in New Issue