Heim  >  Artikel  >  Java  >  Das Android-Entwicklungsframework passt die QR-Code-Scan-Schnittstelle von ZXing an und löst das Problem der Sucherdehnung

Das Android-Entwicklungsframework passt die QR-Code-Scan-Schnittstelle von ZXing an und löst das Problem der Sucherdehnung

高洛峰
高洛峰Original
2017-01-13 10:41:232482Durchsuche

Lassen Sie mich Ihnen zuerst das Rendering zeigen:

Das Android-Entwicklungsframework passt die QR-Code-Scan-Schnittstelle von ZXing an und löst das Problem der Sucherdehnung

Der gescannte Inhalt ist der folgende. Der QR-Code wird mit der zxing-Bibliothek generiert

Das Android-Entwicklungsframework passt die QR-Code-Scan-Schnittstelle von ZXing an und löst das Problem der Sucherdehnung

Da ich mehrere Klassen geändert habe, habe ich fast vergessen, was letztes Jahr passiert ist, daher kann ich nur den Code dieser Klasse hochladen. Die Hauptsache ist, diese CaptureActivity.java zu ändern

package com.zxing.activity;
import java.io.IOException;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.Vibrator;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.Toast;
import com.ericssonlabs.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.zxing.camera.CameraManager;
import com.zxing.decoding.CaptureActivityHandler;
import com.zxing.decoding.CaptureActivityHandler.DecodeCallback;
import com.zxing.decoding.InactivityTimer;
import com.zxing.view.ViewfinderView;
/**
* Initial the camera
* @author Ryan.Tang
* @modifier Lemon
* @use extends CaptureActivity并且在setContentView方法后调用init方法
*/
public abstract class CaptureActivity extends Activity implements Callback, DecodeCallback {
// private static final String TAG = "CaptureActivity";
protected Activity context;
protected SurfaceView surfaceView;
protected ViewfinderView viewfinderView;
/**初始化,必须在setContentView之后
* @param context
* @param viewfinderView
*/
protected void init(Activity context, SurfaceView surfaceView, ViewfinderView viewfinderView) {
this.context = context;
this.surfaceView = surfaceView;
this.viewfinderView = viewfinderView;
CameraManager.init(getApplication());
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
}
private CaptureActivityHandler handler;
private boolean hasSurface;
private Vector<BarcodeFormat> decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME = .f;
private boolean vibrate;
@Override
protected void onResume() {
super.onResume();
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
decodeFormats = null;
characterSet = null;
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
}
@Override
protected void onPause() {
super.onPause();
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
CameraManager.get().closeDriver();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
public static final String RESULT_QRCODE_STRING = "RESULT_QRCODE_STRING";
/**
* Handler scan result
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
String resultString = result.getText();
//FIXME
if (resultString.equals("")) {
Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
}
setResult(RESULT_OK, new Intent().putExtra(RESULT_QRCODE_STRING, resultString));
finish();
}
private void initCamera(SurfaceHolder surfaceHolder) {
try {
CameraManager.get().openDriver(surfaceHolder);
} catch (IOException ioe) {
return;
} catch (RuntimeException e) {
return;
}
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats,
characterSet, viewfinderView, this);
}
}
@Override
public void drawViewfinder() {
viewfinderView.drawViewfinder(); 
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
public Handler getHandler() {
return handler;
}
private void initBeepSound() {
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it
// too loud,
// so we now play on the music stream.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnCompletionListener(beepListener);
AssetFileDescriptor file = getResources().openRawResourceFd(
R.raw.beep);
try {
mediaPlayer.setDataSource(file.getFileDescriptor(),
file.getStartOffset(), file.getLength());
file.close();
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
} catch (IOException e) {
mediaPlayer = null;
}
}
}
private static final long VIBRATE_DURATION = L;
private void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
/**
* When the beep has finished playing, rewind to queue up another one.
*/
private final OnCompletionListener beepListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo();
}
};
}

Verwendung: Erstellen Sie eine neue Aktivität, die CaptureActivity erbt und die Init-Methode nach der setContentView-Methode aufruft.
Beispiel:

CameraScanActivity.java

package zuo.biao.activity;
import zuo.biao.R;
import zuo.biao.library.interfaces.OnBottomDragListener;
import zuo.biao.util.ActivityUtil;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import com.zxing.activity.CaptureActivity;
import com.zxing.camera.CameraManager;
import com.zxing.view.ViewfinderView;
/**扫描二维码Activity
* @author Lemon
* @use 参考zuo.biao.library.ModelActivity
*/
public class CameraScanActivity extends CaptureActivity implements Callback, OnClickListener, OnBottomDragListener {
public static final String TAG = "CameraScanActivity";
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/**启动这个Activity的Intent
* @param context
* @param title
* @return
*/
public static Intent createIntent(Context context) {
return new Intent(context, CameraScanActivity.class);
}
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_scan_activity);
init(this, (SurfaceView) findViewById(R.id.svCameraScan), (ViewfinderView) findViewById(R.id.vfvCameraScan));
//功能归类分区方法,必须调用<<<<<<<<<<
initView();
initData();
initListener();
//功能归类分区方法,必须调用>>>>>>>>>>
}
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initView() {//必须调用
}
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initData() {//必须调用
}
//data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//listener事件监听区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initListener() {//必须调用
findViewById(R.id.tvCameraScanReturn).setOnClickListener(this);
findViewById(R.id.ivCameraScanReturn).setOnClickListener(this);
findViewById(R.id.ivCameraScanLight).setOnClickListener(this);
findViewById(R.id.ivCameraScanMyQRCode).setOnClickListener(this);
}
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@Override
public void onDragBottom(boolean rightToLeft) {
if (rightToLeft) {
return;
}
finish();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tvCameraScanReturn:
case R.id.ivCameraScanReturn:
onDragBottom(false);
break;
case R.id.ivCameraScanLight:
switchLight(! isOpen);
break;
case R.id.ivCameraScanMyQRCode:
//
break;
default:
break;
}
}
private boolean isOpen = false;
/**打开或关闭闪关灯
* @param open
*/
private void switchLight(boolean open) {
if (open == isOpen) {
return;
}
isOpen = CameraManager.get().switchLight(open);
}
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//listener事件监听区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}

CameraScanActivity-Layoutdatei camera_scan_activity.xml

<?xml version="." encoding="utf-"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/activity_page" >
<SurfaceView
android:id="@+id/svCameraScan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<!-- 必须在最底层,且不能指定宽高,否则扫描读取很难实现 -->
<com.zxing.view.ViewfinderView
android:id="@+id/vfvCameraScan"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
style="@style/ll_vertical_match_match"
android:baselineAligned="false" >
<RelativeLayout
style="@style/topbar_bg"
android:background="@color/white_alpha" >
<TextView
android:id="@+id/tvCameraScanReturn"
style="@style/topbar_left_btn"
android:text=" " />
<TextView
style="@style/topbar_title"
android:layout_centerHorizontal="true"
android:text="扫一扫" />
</RelativeLayout>
<LinearLayout
style="@style/ll_vertical_match_match"
android:layout_gravity="center_horizontal"
android:layout_weight="" >
<TextView
style="@style/text_middle_white"
android:layout_margin="dp"
android:text="@string/camera_scan_remind" />
</LinearLayout>
<LinearLayout
style="@style/ll_horizontal_match_wrap"
android:layout_gravity="bottom"
android:background="@color/white_alpha"
android:gravity="center" >
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanReturn"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/back_black_light" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="返回" />
</LinearLayout>
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanLight"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/flash_light" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="开灯/关灯" />
</LinearLayout>
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanMyQRCode"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/qrcode" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="我的名片" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>

Layoutdatei, da einige der ZBLibrary verwendet werden Stil, Farbe usw. Wenn nur dieses Layout vorhanden ist, treten einige Fehler auf. Erstellen Sie einfach selbst eine neue Layoutdatei und fügen Sie ViewfinderView in die äußerste Layoutdatei ein. Nach dem Herunterladen des unten angehängten Quellcodes wird es natürlich kein Problem geben.

Denken Sie übrigens daran, diese Berechtigungen in AndroidManifest.xml hinzuzufügen:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

Angehängter Quellcode (einschließlich Verwendung)

Das Android-Entwicklungsframework passt die QR-Code-Scan-Schnittstelle von ZXing an und löst das Problem der Sucherdehnung

GitHub-Quellcode https://github.com/TommyLemon/Android-ZBLibrary

Open Source chinesischer Quellcode http://git.oschina.net/Lemon19950301/Android-ZBLibrary

Das ist es für alle, die die ZXing-QR-Code-Scanoberfläche des Android-Entwicklungsframeworks anpassen und das Problem der Dehnung des Suchers lösen. Ich hoffe, Sie können ihn mit Geduld lesen. Wenn Sie Fragen haben, können Sie mich gerne kontaktieren. Der Herausgeber wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung der PHP-Chinese-Website!

Weitere verwandte Artikel zum Anpassen der ZXing-QR-Code-Scan-Schnittstelle des Android-Entwicklungsframeworks und zur Lösung des Problems der Streckung des Suchers finden Sie auf der chinesischen PHP-Website!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn