先说一下我的思考:
如果我要做一个 闪光灯的话,为了以后的方便,我要提取一个工具类,所以我自定义了一个 FlashLightUtils, 在里面进行处理 闪光灯的而所有处理。 包括Camera 的初始化,但是这个时候我遇到了:
无法链接 camera 服务,这让我蛋疼,我想了半天也没有想到为什么?
出现这样的问题的原因是:系统只有一个Camera对象,我再重新声明一个Camera对象的话,当然会报错,这是我犯错误比较严重的地方,果然还是应该先细读一下Zxing的源码啊!
you will see thsi line code:
theCamera = new OpenCameraManager().build().open();
public synchronized void openDriver(SurfaceHolder holder) throws IOException { Camera theCamera = camera; if (theCamera == null) { theCamera = new OpenCameraManager().build().open(); if (theCamera == null) { throw new IOException(); } camera = theCamera; } theCamera.setPreviewDisplay(holder); if (!initialized) { initialized = true; configManager.initFromCameraParameters(theCamera); if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) { setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight); requestedFramingRectWidth = 0; requestedFramingRectHeight = 0; } } Camera.Parameters parameters = theCamera.getParameters(); String parametersFlattened = parameters == null ? null : parameters .flatten(); // Save these, temporarily try { configManager.setDesiredCameraParameters(theCamera, false); } catch (RuntimeException re) { // Driver failed Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters"); Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened); // Reset: if (parametersFlattened != null) { parameters = theCamera.getParameters(); parameters.unflatten(parametersFlattened); try { theCamera.setParameters(parameters); configManager.setDesiredCameraParameters(theCamera, true); } catch (RuntimeException re2) { // Well, darn. Give up Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration"); } } } }
我在自己的Activity中又初始化了一次 Camera
Camara mCamera = Camera.open();
所以导致了,
ailed to connect to camera service
解决方法:因为Zxing扫描启动的时候已经初始化了一个Camera对象了,所以没有必要再重新声明一个对象。
注意:
这里很蛋疼的,以为一开的时候调用的时候,CameraManager 里面的Camera 老师为null,我找了好长时间也没有找到,后来不知怎么的就好了。我也是醉了,只是现在还没找到原因!
权限的问题: 我就不说了,你们搜一下就好了:
<uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.FLASHLIGHT"/> <uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus" /><uses-feature android:name="android.hardware.camera.flash" />
在就是当你阅读官网的文档的时候:
public static Camera open (int cameraId)
Caution: On some devices, this method may take a long time to complete. It is best to call this method from a worker thread (possibly using AsyncTask) to avoid blocking the main application UI thread.
建议用异步任务来实现,但是我个人比较喜欢Handler.下面是我的实现方式:
1 第一步 在Camera 里面方法抽取:
/////////////////////////// flashLight///////////////////////////////////////
public void startLight(boolean flag){
if(flag){
openLight();
}else{
offLight();
}
}
public void openLight(){
if (camera != null) {
parameter = camera.getParameters();
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameter);
camera.startPreview();
}
}
public void offLight(){
if (camera != null) {
parameter = camera.getParameters();
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameter);
}
}
public void closeCarema(){
if(camera != null){
camera.release();
camera = null;
}
}
2 第二部:你可以参考:
private Boolean FLASH_LIGHT_FLAG = false; private static final int CAMERA_FLAG_CLOSE = 0;private static final int CAMERA_FLAG_OPEN = 1;private static final int CAMERA_FLAG_INIT_CAMERA = 2;
protected Handler mHandler = new Handler(){ @TargetApi(Build.VERSION_CODES.GINGERBREAD) @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == CAMERA_FLAG_OPEN){ initCamareView(); }else if(msg.what == CAMERA_FLAG_CLOSE){ mCameraManager.closeCarema(); } } };
private void initCamareView() { FLASH_LIGHT_FLAG = !FLASH_LIGHT_FLAG; mCameraManager.startLight(FLASH_LIGHT_FLAG); if(FLASH_LIGHT_FLAG){ mTitleBar.setRightFirstIcon(R.drawable.flash_light_press); }else{ mTitleBar.setRightFirstIcon(R.drawable.flash_light); } }onClicklistenrsend message:@Overridepublic void onClickRightOne(View view) { super.onClickRightOne(view); mHandler.sendEmptyMessage(CAMERA_FLAG_OPEN);}
我的建议:
既然自己的花费了好长的时间整理这个东西,那就不应该让自己未来在花费这么长的时间来整理,所以应该把自己今天的收获记录下来,这样不要在同一个坑里面 跌倒两次。
显然,我们添加的这个东西不是只是使用一次。所以,我们应该抽取一个抽象类
顶层: CaptureActivity
二级: BaseQRCodeActivity
三级: BaseQRCodeWithFlashLightActivity
四级: 你自定的实现的类
当你需要 待FlashLight 的时候,你就extends BaseQRCodeWithFlashLightActivity
随心所欲
这就是面向对象的好处。很多时候,我们用着面向对象的语言,写着面向过程的程序,我也是醉了!
附录:
No comments:
Post a Comment