gpt4 book ai didi

java - zxing Activity 扫描嵌入的二维码

转载 作者:太空宇宙 更新时间:2023-11-03 12:06:40 26 4
gpt4 key购买 nike

在这里我期望 zxing-core 有一些可以从其他应用程序启动的 Activity ,这就是它们集成的方式,而无需启动一些第 3 方应用程序来扫描二维码

我尝试添加

compile 'com.google.zxing:core:3.1.0'
compile 'com.google.zxing:android-integration:3.1.0'

build.gradle 文件,我可以看到这些 jar 已导入,但是我没有看到此类存在于 jar 中

com.google.zxing.client.android.CaptureActivity

在侧 jar 中

$ unzip -l ./modules-2/files-2.1/com.google.zxing/core/3.1.0/908e18674f895e3e1fa8f4a954b8c637a23d2801/core-3.1.0.jar | grep -i 'activity'

我没有看到核心模块的类部分 Here

我做错了什么?

Suppressed: java.lang.ClassNotFoundException: com.google.zxing.client.android.CaptureActivity
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)

我正在使用这种方法:

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("com.google.zxing.client.android.SCAN.SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);

只是为了确保:我的期望是当用户想要使用嵌入式扫描仪而不是将扫描委托(delegate)给其他应用程序时,该 Activity 是用例库的一部分

最佳答案

这是一个很长的答案,因此请仔细阅读以确保您不会遗漏任何内容。

您可以在我的 Github Repo 上看到一个示例项目

好的,首先您必须将核心 zxing 库 jar 添加到项目目录中的 libs 文件夹中。您还必须为 zxing 类创建一个包。见下文

foo.bar.yourpackagename.zxing
foo.bar.yourpackagename.zxing.view

在第一个包 foo.bar.yourpackagename.zxing 中添加以下类


CameraManager.java

import android.app.Activity;
import android.graphics.Rect;
import android.hardware.Camera;
import android.util.Log;
import android.view.Surface;
import com.google.zxing.PlanarYUVLuminanceSource;

/**
* Camera manager
*/
public class CameraManager {
/**
* Fraction of bounds size in view
*/
private static final double BOUNDS_FRACTION = 0.6;
/**
* Fraction of height of bounds in view
*/
private static final double VERTICAL_HEIGHT_FRACTION = 0.3;

/**
* Camera instance
*/
private Camera camera;
/**
* Id of camera instance
*/
private int cameraId;
/**
* Current orientation of camera
* Possible values : 0, 90, 180, 270
*/
private int orientation;

public CameraManager() {
this.camera = getCameraInstance();
}

/**
* Getter for camera
*
* @return camera instance, if it has been initialized
*/
public Camera getCamera() {
return camera;
}

/**
* Starts preview of camera, if it has been initialized
*/
public synchronized void startPreview() {
if (camera != null) {
camera.startPreview();
}
}

/**
* Stops preview of camera, if it has been initialized
*/
public synchronized void stopPreview() {
if (camera != null) {
camera.stopPreview();
}
}

/**
* Release camera, if it has been initialized
*/
public synchronized void release() {
if (camera != null) {
camera.release();
camera = null;
}
}

/**
* @return if camera has been initialized<br/>( <code>camera != null</code> )
*/
public synchronized boolean hasCamera() {
return camera != null;
}

/**
* @return bounding rect for ui
*/
public final synchronized Rect getBoundingRectUi(int uiWidth, int uiHeight) {
double heightFraction = BOUNDS_FRACTION;
double widthFraction = BOUNDS_FRACTION;
if (orientation == 90 || orientation == 270) {
heightFraction = VERTICAL_HEIGHT_FRACTION;
}

Log.d("CameraManager", "dimsUI[" + uiWidth + ", " + uiHeight + "]");

int height = (int) (uiHeight * heightFraction);
int width = (int) (uiWidth * widthFraction);
int left = (int) (uiWidth * ((1 - widthFraction) / 2));
int top = (int) (uiHeight * ((1 - heightFraction) / 2));
int right = left + width;
int bottom = top + height;

return new Rect(left, top, right, bottom);
}

/**
* @return bounding rect for camera
*/
public final synchronized Rect getBoundingRect() {
if (camera != null) {
Camera.Size previewSize = camera.getParameters().getPreviewSize();
int previewHeight = previewSize.height;
int previewWidth = previewSize.width;

double heightFraction = BOUNDS_FRACTION;
double widthFraction = BOUNDS_FRACTION;
if (orientation == 90 || orientation == 270) {
widthFraction = VERTICAL_HEIGHT_FRACTION;
}
Log.d("CameraManager", "dimsPrev[" + previewWidth + ", " + previewHeight + "]");

int height = (int) (previewHeight * heightFraction);
int width = (int) (previewWidth * widthFraction);
int left = (int) (previewWidth * ((1 - widthFraction) / 2));
int top = (int) (previewHeight * ((1 - heightFraction) / 2));
int right = left + width;
int bottom = top + height;

return new Rect(left, top, right, bottom);
}
return null;
}

/**
* executes <br/> <code>camera.setOneShotPreviewCallback(callback)</code> if <br/>
* <code>camera != null</code>
* @param callback callback to provide
*/
public synchronized void requestNextFrame(Camera.PreviewCallback callback) {
if (camera != null) {
camera.setOneShotPreviewCallback(callback);
}
}

/**
* 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 synchronized PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height, Rect boundingRect) {
switch (orientation) {
case 0:
//data = flip(data);
break;
case 90:
rotate90(data, width, height);
return new PlanarYUVLuminanceSource(data, height, width, boundingRect.top, boundingRect.left,
boundingRect.height(), boundingRect.width(), false);

case 180:
break;
case 270:
rotate90(data, width, height);
break;
}

return new PlanarYUVLuminanceSource(data, width, height, boundingRect.left, boundingRect.top,
boundingRect.width(), boundingRect.height(), false);
}

/**
* Rotates image data
* @param data raw image data
* @param width width of image
* @param height height of image
*/
public void rotate90(byte[] data, int width, int height) {
int length = height * width;
int lengthDec = length - 1;
int i = 0;
do {
int k = (i * height) % lengthDec;
while (k > i) k = (height * k) % lengthDec;
if (k != i) swap(data, k, i);
} while (++i <= (length - 2));
}

/**
* Sets camera display orientation depending on current activity orientation
* @param activity activity, which holds camera preview
*/
public void setCameraDisplayOrientation(Activity activity) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}

int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
orientation = result;
camera.setDisplayOrientation(result);
}


/**
* A safe way to get an instance of the Camera object.
*/
private Camera getCameraInstance() {
Camera c = null;
try {
cameraId = 0;
c = Camera.open(); // attempt to get a Camera instance
Camera.Parameters p = c.getParameters();
p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
c.setParameters(p);
} catch (Exception e) {
Log.e(CameraManager.class.getSimpleName(), "Camera error", e);
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}

/**
* Swaps two elements in array
* @param data array
* @param k first element to swap
* @param i second element to swap
*/
private static void swap(byte[] data, int k, int i) {
byte temp = data[k];
data[k] = data[i];
data[i] = temp;
}
}

CaptureHandler.java

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

/**
*/
public class CaptureHandler extends Handler {
public static final String DECODED_DATA = "decoded_data";
private CameraManager cameraManager;
private Context context;
private OnDecodedCallback callback;

public CaptureHandler(CameraManager cameraManager, Context context, OnDecodedCallback callback) {
this.cameraManager = cameraManager;
this.context = context;
this.callback = callback;
}

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case R.id.decoded:
String data = msg.getData().getString(DECODED_DATA);
Toast.makeText(context, data, Toast.LENGTH_LONG).show();
if (callback != null){
callback.onDecoded(data);
}
break;
case R.id.decode_failed:
//getting new frame
cameraManager.requestNextFrame(new PreviewCallback(this, cameraManager));
break;
}
}

public static interface OnDecodedCallback {
void onDecoded(String decodedData);
}
}

PreviewCallback.java

import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.google.zxing.*;
import com.google.zxing.common.HybridBinarizer;
import foo.bar.yourpackagename.R;

/**
* Camera preview callback
*/
public class PreviewCallback implements Camera.PreviewCallback {
private static final String TAG = PreviewCallback.class.getSimpleName();
/**
* Xzing multi format reader
*/
private final MultiFormatReader multiFormatReader = new MultiFormatReader();
/**
* Handler to send messages
*
* @see CaptureHandler
*/
private Handler handler;
/**
* Camera manager
*/
private CameraManager cameraManager;

public PreviewCallback(Handler handler, CameraManager cameraManager) {
this.handler = handler;
this.cameraManager = cameraManager;
}

@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
try {
Camera.Size previewSize = camera.getParameters().getPreviewSize();
new DecodeAsyncTask(previewSize.width, previewSize.height).execute(bytes);
} catch (Exception e) {
//Random errors from zxing
}
}

/**
* Asynchronous task for decoding and finding barcode
*/
private class DecodeAsyncTask extends AsyncTask<byte[], Void, Result> {
/**
* Width of image
*/
private int width;
/**
* Height of image
*/
private int height;

/**
* @param width Width of image
* @param height Height of image
*/
private DecodeAsyncTask(int width, int height) {
this.width = width;
this.height = height;
}

@Override
protected void onPostExecute(Result result) {
if (result != null) {
Log.i(TAG, "Decode success.");
if (handler != null) {
Message message = Message.obtain(handler, R.id.decoded);
Bundle bundle = new Bundle();
bundle.putString(CaptureHandler.DECODED_DATA, result.toString());
message.setData(bundle);
message.sendToTarget();
}
} else {
Log.i(TAG, "Decode fail.");
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_failed);
message.sendToTarget();
}
}
}

@Override
protected Result doInBackground(byte[]... datas) {
if (!cameraManager.hasCamera()) {
return null;
}
Result rawResult = null;
final PlanarYUVLuminanceSource source =
cameraManager.buildLuminanceSource(datas[0], width,
height, cameraManager.getBoundingRect());
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (Exception re) {
Log.e(TAG, "ERROR", re);
} finally {
multiFormatReader.reset();
}
}

return rawResult;
}
}
}

然后将这三个类添加到 foo.bar.yourpackagename.zxing 包后,您必须将以下类添加到 foo.bar.yourpackagename.zxing.view


BoundingView.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import foo.bar.yourpackagename.zxing.CameraManager;

/**
* View for displaying bounds for active camera region
*/
public class BoundingView extends View {
/**
* Camera manager
*/
private CameraManager cameraManager;

public BoundingView(Context context) {
super(context);
}

public BoundingView(Context context, AttributeSet attrs) {
super(context, attrs);
}

/**
* Sets camera manger
* @param cameraManager
*/
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (cameraManager != null) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#00000000"));

// Rect boundingRect = cameraManager.getBoundingRectUi(canvas.getWidth(), canvas.getHeight());
Rect boundingRect = cameraManager.getBoundingRect();
canvas.drawRect(boundingRect, paint);

paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#44FF0000"));
paint.setStrokeWidth(5);
int incY = (canvas.getHeight() - boundingRect.height())/2;
int incX = (canvas.getWidth() - boundingRect.width())/2;

int y = (boundingRect.height()/2) + incY;
int x = boundingRect.width() + incX;
canvas.drawLine(incX, y, x, y, paint);
canvas.drawRect(new Rect(incX, boundingRect.top, x, boundingRect.bottom), paint);
}
}
}

CameraPreviewView.java

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import foo.bar.yourpackagename.zxing.CameraManager;

import java.io.IOException;

/**
* Camera preview view. Shows camera preview data
*/
public class CameraPreviewView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = CameraPreviewView.class.getSimpleName();

/**
* Surface holder for camera preview data
*/
private SurfaceHolder surfaceHolder;
/**
* Camera manager
*/
private CameraManager cameraManager;

public CameraPreviewView(Context context) {
super(context);

surfaceHolder = getHolder();
surfaceHolder.addCallback(this);

// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public CameraPreviewView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);

surfaceHolder = getHolder();
surfaceHolder.addCallback(this);

// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

/**
* Setter for camera manager
* @param cameraManager camera manager to set
*/
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
cameraManager.setCameraDisplayOrientation((Activity) getContext());
cameraManager.getCamera().setPreviewDisplay(holder);
cameraManager.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// empty. Taking care of releasing the Camera preview in activity.
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.

if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}

// stop preview before making changes
try {
cameraManager.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}

// set preview size and make any resize, rotate or
// reformatting changes here

// start preview with new settings
try {
cameraManager.setCameraDisplayOrientation((Activity) getContext());
cameraManager.getCamera().setPreviewDisplay(surfaceHolder);
cameraManager.startPreview();

} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}

完成后,您可以开始实现 Activity请注意,某些类(class)要求您为某些州创建 ID,例如

R.id.decode_failed

您需要在应用程序的资源文件夹中创建这些 ID。接下来我们可以开始实现 Activity


CaptureActivity.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

import foo.bar.yourpackagename.R;
import foo.bar.yourpackagename.zxing.CameraManager;
import foo.bar.yourpackagename.zxing.CaptureHandler;
import foo.bar.yourpackagename.zxing.PreviewCallback;
import foo.bar.yourpackagename.zxing.view.BoundingView;
import foo.bar.yourpackagename.zxing.view.CameraPreviewView;

/**
* Capture activity (camera barcode activity)
*/
public class CaptureActivity extends Activity {
public static String PUBLIC_STATIC_STRING_IDENTIFIER;

/**
* Camera preview view
*/
private CameraPreviewView cameraPreview;
/**
* Camera manager
*/
private CameraManager cameraManager;

/**
* Capture handler
*/
private Handler captureHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(getContentView());

initializeCamera();
initializeCameraPreview();
initializeBoundingView();
}

private View getContentView() {
RelativeLayout contentView = new RelativeLayout(this);
contentView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
contentView.addView(getBoundingView());
contentView.addView(getCameraPreviewView());

return contentView;
}

private CameraPreviewView getCameraPreviewView() {
//This is the camera SurfaceView
CameraPreviewView camPreview = new CameraPreviewView(this);
camPreview.setId(R.id.camera_preview);
camPreview.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

return camPreview;
}

private BoundingView getBoundingView() {
//Displays the bounding content
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);

BoundingView boundingView = new BoundingView(this);
boundingView.setId(R.id.bounding_view);
boundingView.setLayoutParams(params);

return boundingView;
}

private void initializeCamera() {
// Create an instance of Camera
cameraManager = new CameraManager();
captureHandler = new CaptureHandler(cameraManager, this, new OnDecoded());

//requesting next frame for decoding
cameraManager.requestNextFrame(new PreviewCallback(captureHandler, cameraManager));
}

private void initializeCameraPreview() {
// Create our Preview view and set it as the content of our activity.
cameraPreview = (CameraPreviewView) findViewById(R.id.camera_preview);
cameraPreview.setCameraManager(cameraManager);
}

private void initializeBoundingView() {
//Set the cameraManager to the bounding view
((BoundingView) findViewById(R.id.bounding_view)).setCameraManager(cameraManager);
}

@Override
protected void onPause() {
super.onPause();

//We don't want the cameraManager to take up unneeded
//resources so we release it from memory onPause
cameraManager.release();
}

/**
* This handles the decoded content from the Zxing framework. As
* soon as the framework has completed the decoding process the CaptureHandler
* will pass it back via this listener for you to handle it further.
*
*/
private class OnDecoded implements CaptureHandler.OnDecodedCallback {
@Override
public void onDecoded(String decodedData) {
Intent resultIntent = new Intent();
resultIntent.putExtra(PUBLIC_STATIC_STRING_IDENTIFIER, decodedData);
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
}
}

要开始 Activity ,您只需调用

startActivity(new Intent(this, CaptureActivity.class));

另外记得添加以下权限

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />

还有你的Activity

<activity
android:name=".CaptureActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="com.google.zxing.client.android.SCAN" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

list !

如果您正确地实现了所有这些类,那么您应该能够开始扫描条形码。

关于java - zxing Activity 扫描嵌入的二维码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28293391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com