【发布时间】:2014-06-03 02:20:43
【问题描述】:
我想在我的 android 应用程序中实现独立扫描器。我在我的项目中使用 zxing 的 core.jar 库。
我需要从相机预览中解码条形码。但我不知道如何实现它。因为没有官方文档。
你能给我一个简单的例子吗? 1.初始化相机并获得预览。 2.从预览中解码条形码。
或
有没有示例项目可以做到这一点?
【问题讨论】:
我想在我的 android 应用程序中实现独立扫描器。我在我的项目中使用 zxing 的 core.jar 库。
我需要从相机预览中解码条形码。但我不知道如何实现它。因为没有官方文档。
你能给我一个简单的例子吗? 1.初始化相机并获得预览。 2.从预览中解码条形码。
或
有没有示例项目可以做到这一点?
【问题讨论】:
看看我的简单实现: https://github.com/piobab/code-scanner
我使用 ZBar 库,但如果您愿意,您可以将 ZBarScannerView.java 实现更改为 ZXingScannerView(其余代码都可以):
public class ZXingScannerView extends ScannerView {
public interface ResultHandler {
public void handleResult(Result result);
}
private MultiFormatReader mMultiFormatReader;
private ResultHandler mResultHandler;
public ZXingScannerView(Context context) {
super(context);
setupScanner(null);
}
public ZXingScannerView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
setupScanner(null);
}
/**
* Specify recognized codes types.
* @param codeTypes list of codes types from ZXing library
*/
public void setCodeTypes(List<com.google.zxing.BarcodeFormat> codeTypes) {
setupScanner(codeTypes);
}
private void setupScanner(List<com.google.zxing.BarcodeFormat> symbols) {
Map<DecodeHintType,Object> hints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);
// Add specific formats
hints.put(DecodeHintType.POSSIBLE_FORMATS, symbols);
mMultiFormatReader = new MultiFormatReader();
mMultiFormatReader.setHints(hints);
}
/**
* Register callback in order to receive data from scanner.
* @param resultHandler
*/
public void setResultHandler(ResultHandler resultHandler) {
mResultHandler = resultHandler;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
int width = size.width;
int height = size.height;
Result rawResult = null;
PlanarYUVLuminanceSource source = buildLuminanceSource(data, width, height);
if(source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = mMultiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
} catch (NullPointerException npe) {
} catch (ArrayIndexOutOfBoundsException aoe) {
} finally {
mMultiFormatReader.reset();
}
}
if (rawResult != null) {
stopCamera();
if(mResultHandler != null) {
mResultHandler.handleResult(rawResult);
}
} else {
camera.setOneShotPreviewCallback(this);
}
}
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview(width, height);
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
PlanarYUVLuminanceSource source = null;
try {
source = new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
} catch(Exception e) {
}
return source;
}
}
如果您使用 gradle,请将“com.google.zxing:core:2.2”添加到您的依赖项中。
【讨论】:
您可以使用 Zxing 库,这些步骤假设您使用的是 Android studio
1- 转到https://github.com/zxing/zxing 并获取最新代码。
2-解压zip文件,并将android文件夹作为模块导入
3-在为导入模块生成的build.gradle中,更改
apply plugin: 'com.android.application'
到
apply plugin: 'com.android.library'
4- 在同一文件中从以下部分中删除第二行:
defaultConfig {
applicationId "com.google.zxing.client.android"
5- 到http://repo1.maven.org/maven2/com/google/zxing/ 下载最新的“android-core”和“android-integration”jars 并添加到android模块的libs文件夹中
6- 从你的模块添加依赖到 android 模块
7- 新建你的模块可以使用 ZXing 作为库并调用它的 CaptureActivity ,这里很简单,使用以下 XML 和 Java 代码创建一个新活动
Java 代码:
package bestteam.barcode;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.zxing.client.android.CaptureActivity;
import com.google.zxing.client.android.Intents;
public class MainActivity extends Activity implements View.OnClickListener, android.content.DialogInterface.OnClickListener {
private TextView tvScanResults;
private TextView tvStatus;
private Button btnScan;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandleClick hc = new HandleClick();
tvScanResults = (TextView) findViewById(R.id.tvResult);
tvStatus = (TextView) findViewById(R.id.tvStatus);
btnScan = (Button) findViewById(R.id.butOther);
btnScan.setOnClickListener(this);
findViewById(R.id.butOther).setOnClickListener(hc);
}
private class HandleClick implements View.OnClickListener {
public void onClick(View arg0) {
Intent intent = new Intent(getApplicationContext(), CaptureActivity.class);
intent.putExtra("SCAN_FORMATS", "QR_CODE,EAN_13,EAN_8,RSS_14,UPC_A,UPC_E,CODE_39,CODE_93,CODE_128,ITF,CODABAR,DATA_MATRIX");
intent.setAction(Intents.Scan.ACTION);
startActivityForResult(intent, 0);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
// Handle successful scan
String contents = intent.getStringExtra(Intents.Scan.RESULT);
String formatName = intent.getStringExtra(Intents.Scan.RESULT_FORMAT);
tvStatus.setText(formatName);
tvScanResults.setText(contents + "\n\n" + formatName);
} else if (resultCode == Activity.RESULT_CANCELED) {
tvStatus.setText("Press a button to start a scan.");
tvScanResults.setText("Scan cancelled.");
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
XML 代码:
<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="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/butOther"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.18"
android:text="Scan"
android:textSize="18sp" />
</LinearLayout>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tvStatus"
android:text="Press a button to start a scan."
android:gravity="center"
android:textSize="18sp" />
<TextView
android:id="@+id/tvResult"
android:layout_width="346dp"
android:layout_height="394dp"
android:background="@android:color/white"
android:gravity="center"
android:text="Ready"
android:textColor="@android:color/black"
android:textSize="18sp" />
</LinearLayout>
【讨论】: