1. 程式人生 > >Android 手電筒(最強適配版)

Android 手電筒(最強適配版)

網上很多手電筒的程式碼,然後整理了下

使用:不停的呼叫onAndoff就能開和關手電筒

           isopen是開關狀態,比如你可以用他來判斷手電是否開啟。

           可以看到使用了單例模式和執行緒同步,原因是你只有一個燈泡。

           那邊看程式碼,邊看註釋吧

public class Flash {

	private static Flash mFlash;
	private static Camera mCamera = null;
	private static Camera.Parameters mCameraParameters;

	private static String previousFlashMode = null;
	private static boolean isOpen = false;

	private Flash() {
	}

	public static Flash getInstance() {
		if (mFlash == null) {
			mFlash = new Flash();
		}
		return mFlash;
	}

	public synchronized void open(Context context) {

		if (context.getPackageManager().hasSystemFeature(
				PackageManager.FEATURE_CAMERA_FLASH)) {//這裡的判斷證實是沒有用的,不能用來判斷手機是否有燈泡,已經加了我就再沒刪
			try {
				mCamera = Camera.open();
				mCamera.setPreviewTexture(new SurfaceTexture(0));//這一句話很重要,不加的話在nexus 5上燈泡不亮
			} catch (Exception e) {
				close();
				String mString = context.getApplicationContext().getResources()
						.getString(R.string.device_unable);
				Toast.makeText(context.getApplicationContext(), mString,
						Toast.LENGTH_LONG).show();
				
				//這裡是打不開的情況,比如別人正在使用的燈泡,打不開用一個close關一次,下次就能打開了。
			}
		} else {
			Toast.makeText(context,
					context.getString(R.string.device_cannot_find),
					Toast.LENGTH_LONG).show();
			return;
		}
		if (mCamera != null) {
			mCameraParameters = mCamera.getParameters();
			previousFlashMode = mCameraParameters.getFlashMode();
		}
		if (previousFlashMode == null) {
			// could be null if no flash, i.e. emulator
			previousFlashMode = Camera.Parameters.FLASH_MODE_OFF;
		}
	}

	public synchronized void close() {//關燈,就是用完之後清除一下camera物件,不然會影響其他裝置的正常使用
		if (mCamera != null) {
			mCameraParameters.setFlashMode(previousFlashMode);
			mCamera.setParameters(mCameraParameters);
			mCamera.release();
			mCamera = null;
			isOpen = false;
		}
	}

	public synchronized void onAndOff(Context context) {//開\關都在這裡調

		try {
			if (isOpen) {
				off();
			} else if (!isOpen) {
				on(context);
			}
			// send broadcast for widget
			
			//調完之後可以通知介面更新
		} catch (RuntimeException e) {
			Toast.makeText(context, R.string.device_unavailable,
					Toast.LENGTH_SHORT).show();

		}

	}

	public synchronized void on(Context context) {
		if (mCamera == null) {
			open(context);
		}
		if (mCamera != null) {
			mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
			mCamera.setParameters(mCameraParameters);
			mCamera.startPreview();
			isOpen = true;
		}

	}

	public synchronized void off() {
		if (mCamera != null) {
			mCamera.stopPreview();
			mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
			mCamera.setParameters(mCameraParameters);
			isOpen = false;
		}
		close();

	}

	public boolean isOpen() {
		return isOpen;
	}

	public void setOpen(boolean isOpen) {
		Flash.isOpen = isOpen;
	}

}