最近项目扫描药品的ZXing,产品要加一个打开和关闭闪光灯的功能(灯光暗的时候可以满足用户扫码的需求),最后我会贴上我的代码
注意点:
问题一:在ZXing的CaptureActivity中,我们不能再创建Camera对象,因为系统就只有一个Camera对象,并且ZXing的源码中已经帮我们创建好了,使用我们这里不能再创建
*不然抛出,Fail to connect to camera service 异常
*看源码ZXing源码:
//已经帮我们创建好了Camera
public void openDriver(SurfaceHolder holder) throws IOException {
if (camera == null) {
camera = Camera.open(); //源码就创建好了camear
if (camera == null) {
throw new IOException();
}
camera.setPreviewDisplay(holder);
if (!initialized) {
initialized = true;
configManager.initFromCameraParameters(camera);
}
configManager.setDesiredCameraParameters(camera);
// SharedPreferences prefs =
// PreferenceManager.getDefaultSharedPreferences(context);
// if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false))
// {
// FlashlightManager.enableFlashlight();
// }
FlashlightManager.enableFlashlight();
}
}
*解决办法:
我们在ZXing的CameraManager中写一个方法获取到camare对象(给CaptureActivity获取这个相机对象)
/**
* 获取相机的方法
* @return camera
*/
public static Camera getCamera(){
return camera;
}
问题二:关闭闪光灯的时候抛出 at android.hardware.Camera.setOneShorPreviewCallback(Camera.java…)异常,这个问题的原因是:ZXing源码中已经帮我们做了销毁了
*看代码
public static void stopPreview() {
if (camera != null && previewing) {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
camera.stopPreview();
previewCallback.setHandler(null, 0);
autoFocusCallback.setHandler(null, 0);
previewing = false;
}
}
*解决方式:我没在CaptureActivity的surfaceDestroyed()方法中,调用CameraManager类中的stopPreview();释放资源(ZXing源码里面就帮我们做了,我们只需要调用下即可)
/**
* 这里释放资源
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
if (camera != null) {
CameraManager.stopPreview();
}
}
问题分析完了,这里我们就可以开始打开和关闭闪光灯的逻辑了,看代码(必须把我前面分析的问题处理完,在开始需求逻辑的处理,不然会报错)
//初始化view,并且设置点击事件开启和关闭闪光灯
private void initFindView() {
tv_open_light = (TextView) findViewById(R.id.tv_open_light);
tv_open_light.setOnClickListener(openListener);
}
/**
* 开灯
*/
private OnClickListener openListener = new OnClickListener() {
@Override
public void onClick(View v) {
//获取到ZXing相机管理器创建的camera
camera = CameraManager.getCamera();
parameter = camera.getParameters();
// TODO 开灯
if (isOpen) {
tv_open_light.setText("关灯");
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameter);
isOpen = false;
} else { // 关灯
tv_open_light.setText("开灯");
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameter);
isOpen = true;
}
}
};