最近又要做Android的扫码功能,之前做过这一功能,使用的是Google官方推荐的ZXing,直接集成开发的,比较繁琐。这次使用了一个扫码的开源框架(BGAQRCode-Android),该框架集成了ZXing和ZBar,简单易用。ZXing是基于C++实现的,ZBar是基于C的,所以ZBar扫码比ZXing快,这点在实际使用中体验很明显。在开发中,我遇到了一个问题,就是使用该框架的ZXing扫条形码时,多次扫同一条形码,发现有时识别到的文本不正确,而且出现的频率还挺高的,使用ZBar就没有该问题,知道原因的同学欢迎留言交流一下。
下面是我使用该框架的步骤:
第一,添加依赖
implementation'cn.bingoogolapple:bga-qrcode-zxing:1.3.7'
implementation'cn.bingoogolapple:bga-qrcode-zbar:1.3.7'
第二,添加ZBarView控件到布局文件
<cn.bingoogolapple.qrcode.zbar.ZBarView
android:id="@+id/zbarview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:qrcv_animTime="1000"
app:qrcv_borderColor="@android:color/white"
app:qrcv_borderSize="1dp"
app:qrcv_cornerColor="@android:color/holo_green_light"
app:qrcv_cornerLength="20dp"
app:qrcv_cornerSize="3dp"
app:qrcv_isShowDefaultScanLineDrawable="true"
app:qrcv_maskColor="#64000000"
app:qrcv_rectWidth="280dp"
app:qrcv_barcodeRectHeight="180dp"
app:qrcv_scanLineColor="@android:color/holo_green_light"
app:qrcv_topOffset="90dp"
app:qrcv_barCodeTipText="将条形码放入框内,自动扫描"
app:qrcv_isTipTextBelowRect="true"
app:qrcv_tipTextColor="@android:color/white"
app:qrcv_tipTextMargin="15dp"
app:qrcv_tipTextSize="18dp"
app:qrcv_isBarcode="true"/>
第三,Activity实现QRCodeView.Delegate接口,实现方法onScanQRCodeSuccess,onStart,onStop,onDestroy
public class ScanCodeActivityextends AppCompatActivity implements QRCodeView.Delegate {
static final StringSCAN_RESULT ="scan_result";
private QRCodeViewmQRCodeView;
private AppCompatActivityactivity;
private MediaPlayermediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME =0.10f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity =this;
setContentView(R.layout.activity_scan_code);
mQRCodeView = (ZBarView) findViewById(R.id.zbarview);
mQRCodeView.changeToScanBarcodeStyle(); //扫条形码
mQRCodeView.setDelegate(this);
}
@Override
protected void onResume() {
super.onResume();
playBeep =true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep =false;
}
initBeepSound();
}
@Override
protected void onStart() {
super.onStart();
mQRCodeView.startCamera();
//强制手机摄像头镜头朝向前边
//mQRCodeView.startCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
mQRCodeView.showScanRect(); //显示扫描方框
mQRCodeView.startSpot();
}
@Override
protected void onStop() {
mQRCodeView.stopCamera();
super.onStop();
}
@Override
protected void onDestroy() {
mQRCodeView.onDestroy();
super.onDestroy();
}
@Override
public void onScanQRCodeSuccess(String result) {
if (playBeep &&mediaPlayer !=null) {
mediaPlayer.start();
}
Intent returnIntent =new Intent();
returnIntent.putExtra(SCAN_RESULT, result);
setResult(RESULT_OK, returnIntent);
finish();
}
@Override
public void onCameraAmbientBrightnessChanged(boolean isDark) {
}
@Override
public void onScanQRCodeOpenCameraError() {
Toast.makeText(activity, "打开相机错误!", Toast.LENGTH_SHORT).show();
}
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 final MediaPlayer.OnCompletionListenerbeepListener =new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(0);
}
};
第四,添加权限,Android6.0之后需要手动申请权限