天天看點

Android之掃描二維碼&開啟閃光燈

在本人開發的Android項目中先加入了掃描二維碼功能(google的zxing)

然後又有需求要在掃描二維碼的同時,可以打開閃光燈……

如此一個身心健康的年輕程式員慢慢的走向了死亡…………開個玩笑

上篇文章就是先寫了個開啟閃光燈的操作

不過當內建到項目中的時候就Game Over了

不過不着急,程式員是幹嘛的?不就是挑戰錯誤嘛

先看看錯誤資訊

08-06 17:34:29.257: E/AndroidRuntime(24294): FATAL EXCEPTION: main
08-06 17:34:29.257: E/AndroidRuntime(24294): java.lang.IllegalStateException: Could not execute method of the activity
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.view.View$1.onClick(View.java:2154)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.view.View.performClick(View.java:2538)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.view.View$PerformClick.run(View.java:9152)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.os.Handler.handleCallback(Handler.java:587)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.os.Looper.loop(Looper.java:130)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.app.ActivityThread.main(ActivityThread.java:3691)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at java.lang.reflect.Method.invokeNative(Native Method)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at java.lang.reflect.Method.invoke(Method.java:507)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at dalvik.system.NativeStart.main(Native Method)
08-06 17:34:29.257: E/AndroidRuntime(24294): Caused by: java.lang.reflect.InvocationTargetException
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at java.lang.reflect.Method.invokeNative(Native Method)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at java.lang.reflect.Method.invoke(Method.java:507)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.view.View$1.onClick(View.java:2149)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	... 11 more
08-06 17:34:29.257: E/AndroidRuntime(24294): Caused by: java.lang.RuntimeException: Fail to connect to camera service
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.hardware.Camera.native_setup(Native Method)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.hardware.Camera.<init>(Camera.java:300)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at android.hardware.Camera.open(Camera.java:275)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	at com.android.francis.application.MainActivity.mainHandler(MainActivity.java:69)
08-06 17:34:29.257: E/AndroidRuntime(24294): 	... 14 more
           

通過提示資訊,結合實際現象,進行分析,不難了解到錯誤的原因:

掃描二維碼已經開啟了相機操作,然後開啟閃光燈又執行個體化了一個Camera對象

手機隻有一個Camera,是以我們自己就不能通過Camera camera = Camera.open();方法獲得Camera對象了。

檢視zxing程式代碼,有一個CameraManagement類,Camera的執行個體化與操作都在這個Management類中,是以在該類中提供擷取Camera對象的方法:

public Camera getCamera() {
		return camera;
	}
           

然後再看掃描二維碼的Activity中的方法:

private Camera camera;
	private void turnHandler() {
		if (camera == null) {
//			camera = Camera.open();
			camera = CameraManager.get().getCamera();
		}
		camera.startPreview();
		Parameters parameters = camera.getParameters();
//		判斷閃光燈目前狀态
		if (Parameters.FLASH_MODE_OFF.equals(parameters.getFlashMode())) {
			turnOn(parameters);
		} else if (Parameters.FLASH_MODE_TORCH.equals(parameters.getFlashMode())) {
			turnOff(parameters);
		}
	}

	private void turnOn(Parameters parameters) {
		parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
		camera.setParameters(parameters);
		turnOnOff.setText("關閉閃光燈");
	}

	private void turnOff(Parameters parameters) {
		parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
		camera.setParameters(parameters);
//		camera.release();
//		camera = null;
		turnOnOff.setText("開啟閃光燈");
	}
           

如此,開啟閃光燈的操作是成功了,不過關閉閃光燈的操作還是有問題……

我們需要修改surfaceDestroyed()方法:

public void surfaceDestroyed(SurfaceHolder holder) {
		hasSurface = false;
		CameraManager.get().stopPreview();
	}
           

如此,在二維碼掃描Activity中添加開啟/關閉閃光燈操作就完成了

該方法在eoe上已經與作者給出詳細介紹了

http://www.eoeandroid.com/thread-235785-1-1.html