作为一枚新手,进公司第一天产品就告诉我,华为手机扫码有问题,让我看看代码准备修复吧,我觉得这不是小问题吗?扫码这玩意我已经玩过了,没什么难度。可是我看了之后傻眼了,怎么会这样,用的是zbar来写的,华为手机,扫码界面模糊,除华为手机以外,别的手机清晰而且灵敏,查了半天没头绪,没办法,重做吧。。。。太多废话了,不说了,反正后面兜兜转转,还是重做了,还是用的zbar,封装的很好的一个库,由于需要开启闪光灯功能,所以把库中封装好的代码做了一些修改
看下主代码吧
package com.lg.scandemo.zbar;
import android.content.DialogInterface;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import com.lg.scandemo.R;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.PermissionListener;
import com.yanzhenjie.zbar.camera.ScanCallback;
import java.io.IOException;
import java.util.List;
/**
* Created by Administrator on 2017/7/31.
*/
public class ZBarScanActivity extends AppCompatActivity {
private CameraPreview mPreviewView;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME = 0.10f;
private boolean vibrate;
private ImageView ivLightControl;
private TextView tvLightStatus;
private boolean flag = false;
private CameraManager cameraManager;
private InactivityTimer inactivityTimer;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qr_scan);
initView();
mPreviewView = (CameraPreview) findViewById(R.id.capture_preview);
ImageView mScanLine = (ImageView) findViewById(R.id.capture_scan_line);
inactivityTimer = new InactivityTimer(this);
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
animation.setDuration(4500);
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.RESTART);
mScanLine.startAnimation(animation);
mPreviewView.setScanCallback(resultCallback);
cameraManager = mPreviewView.mCameraManager;
// startScanUnKnowPermission();
}
/**
* Accept scan result.
*/
private ScanCallback resultCallback = new ScanCallback() {
@Override
public void onScanResult(String result) {
stopScan();
inactivityTimer.onActivity();
// 播放扫描成功声音
playBeepSoundAndVibrate();
dispatch(result);
}
};
private void initView() {
findViewById(R.id.title_left_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ZBarScanActivity.this.finish();
}
});
ivLightControl = (ImageView) findViewById(R.id.mo_scanner_light);
tvLightStatus = (TextView) findViewById(R.id.light_status_tv);
ivLightControl.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// 闪光灯
if (!flag) { // 开启
flag = true;
ivLightControl.setImageResource(R.drawable.scan_open);
tvLightStatus.setText("关灯");
cameraManager.openLight();
} else { // 关闭
flag = false;
ivLightControl.setImageResource(R.drawable.scan_close);
tvLightStatus.setText("开灯");
cameraManager.offLight();
}
}
});
}
private void dispatch(String result) {
flag = false;
cameraManager.offLight();
ivLightControl.setImageResource(R.drawable.scan_close);
tvLightStatus.setText("开灯");
AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setTitle("扫描结果");
ad.setIcon(R.mipmap.ic_launcher);
ad.setMessage(result);
ad.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 这样做是为了演示如果onPause可以使用该方法重新进入扫描
startScanUnKnowPermission();
}
});
ad.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.mo_scanner_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 = 200L;
/**
* 播放扫描结束声音
*/
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 MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(0);
}
};
@Override
protected void onResume() {
super.onResume();
inactivityTimer.onResume();
startScanUnKnowPermission();
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
}
@Override
public void onPause() {
// Must be called here, otherwise the camera should not be released properly.
stopScan();
inactivityTimer.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
/**
* Do not have permission to request for permission and start scanning.
*/
private void startScanUnKnowPermission() {
AndPermission.with(this)
.permission(android.Manifest.permission.CAMERA)
.callback(new PermissionListener() {
@Override
public void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {
startScanWithPermission();
}
@Override
public void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {
AndPermission.defaultSettingDialog(ZBarScanActivity.this).show();
}
})
.start();
}
/**
* There is a camera when the direct scan.
*/
private void startScanWithPermission() {
if (!mPreviewView.start()) {
new AlertDialog.Builder(this)
.setTitle(R.string.camera_failure)
.setMessage(R.string.camera_hint)
.setCancelable(false)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.show();
}
}
/**
* Stop scan.
*/
private void stopScan() {
mPreviewView.stop();
}
}
主要配置是build.gradle中dependencies中的这些
// zbar的封装
compile 'com.yanzhenjie.zbar:zbar:1.0.0'
// 相机的封装
compile 'com.yanzhenjie.zbar:camera:1.0.0'
// 6.0权限的封装,该项目中相机权限
compile 'com.yanzhenjie:permission:1.0.7'
另外不要忘记AndroidMainfest中配置权限哦
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
其实主要是为自己以后开发做准备,暂时先这样写吧
Demo下载地址:http://download.csdn.net/detail/alwaysgoalong/9917622