简单的手电筒程序(基于Camera类实现)

控制手机闪关灯按照思路大概有下面三种方法

1.  使用camera类控制闪光灯方法setFlashMode 进行操作

2.  通过JNI控制现有驱动节点(使用与三星手机,其他手机不确认)

3.  重新编写驱动代码,提供通用的控制节点,供上层应用调用实现

Flash OnFlash Off
上图为效果图(后来才发现原来灯泡和手电筒是不一样的东西,囧), 使用ToggleButton类型button显得生动一点。

下面是“Read The Fucking Source Code”

package com.saberhao.bulb;


import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class BulbSwitch extends Activity {
	
	ToggleButton tb;
	private Camera mCameraDevices;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_bulb_switch);
		if(mCameraDevices == null)  
			//获取camera实例
            mCameraDevices = Camera.open();
		mCameraDevices.startPreview();
		tb = (ToggleButton)findViewById(R.id.BulbButton);
		tb.setOnCheckedChangeListener
        (
        		//listen to the button
	           new OnCheckedChangeListener()
	           {
					@Override
					public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
					{
						setBulbState(isChecked);
					}
	           }
          ); 
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if(mCameraDevices == null) 
			return; 
		// release the camera class
		mCameraDevices.stopPreview();
		mCameraDevices.release(); 
		mCameraDevices = null; 	
	}

	protected void setBulbState(boolean isChecked) {
		// TODO Auto-generated method stub  
    	ImageView iv=(ImageView)findViewById(R.id.ImageView);
		iv.setImageResource((isChecked)?R.drawable.bulb_on:R.drawable.bulb_off);
		Parameters mParameters = mCameraDevices.getParameters();
		if(isChecked)
			// flash on
			mParameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
		else
			// flash off
			mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
		mCameraDevices.setParameters(mParameters);
		ToggleButton tb=(ToggleButton)findViewById(R.id.BulbButton);        
		tb.setChecked(isChecked);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.bulb_switch, menu);
		return true;
	}
}

源代码 请点击这里下载


代码逻辑很简单,就是通过调用camera的方法setFlashMode来进行开关flash,但是过程中发现有 FC, log如下



重现路径是:第一次打开应用,操作正常,如果按back key退出,再进入,就会有FC,如果是在内存管理中直接删除,在进入,就没问题

通过上面分析 ,问题就非常明显了,没有完全退出导致了问题的发生,故又重写onDestroy的方法解决问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android Camera2 API中实现手动对焦需要以下步骤: 1. 获取CameraManager实例,使用该实例获取可用的相机设备列表。 2. 获取要使用的相机设备的CameraDevice实例。 3. 创建一个CaptureRequest.Builder对象,并将其与相机设备关联。 4. 设置手动对焦模式和对焦区域。 5. 构建CaptureRequest对象。 6. 启动相机预览。 7. 实现一个触摸事件监听器,在用户触摸屏幕时获取焦点坐标,并设置对焦区域。 8. 在触摸事件监听器中调用CaptureRequest.Builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)触发对焦操作。 9. 实现一个CameraCaptureSession.CaptureCallback回调函数,在对焦完成后更新预览界面。 下面是一个简单实现示例: ```java private void setupCamera() { // 获取相机管理器实例 CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { // 获取可用的相机设备列表 String[] cameraIds = cameraManager.getCameraIdList(); for (String cameraId : cameraIds) { // 获取相机设备实例 CameraDevice cameraDevice = cameraManager.openCamera(cameraId, mStateCallback, mBackgroundHandler); // 创建一个CaptureRequest.Builder对象,并将其与相机设备关联 mPreviewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); // 设置手动对焦模式和对焦区域 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{new MeteringRectangle(focusRect, 1000)}); // 构建CaptureRequest对象 mPreviewRequest = mPreviewRequestBuilder.build(); // 启动相机预览 cameraDevice.createCaptureSession(Arrays.asList(mSurface), mSessionCallback, mBackgroundHandler); } } catch (CameraAccessException e) { e.printStackTrace(); } } private void startPreview() { try { // 设置自动对焦模式 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); // 启动预览 mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private void setFocusArea(float x, float y) { // 计算对焦区域 Rect focusRect = calculateFocusRect(x, y); // 设置对焦区域 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{new MeteringRectangle(focusRect, 1000)}); // 触发对焦操作 mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); try { // 更新预览界面 mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { super.onCaptureCompleted(session, request, result); // 对焦完成后更新预览界面 if (request.get(CaptureRequest.CONTROL_AF_TRIGGER) != null && request.get(CaptureRequest.CONTROL_AF_TRIGGER) == CameraMetadata.CONTROL_AF_TRIGGER_START) { mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); try { mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } } }; private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { mCameraDevice = camera; startPreview(); } @Override public void onDisconnected(@NonNull CameraDevice camera) { mCameraDevice.close(); mCameraDevice = null; } @Override public void onError(@NonNull CameraDevice camera, int error) { mCameraDevice.close(); mCameraDevice = null; } }; private CameraCaptureSession.StateCallback mSessionCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { mCaptureSession = session; try { mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { session.close(); mCaptureSession = null; } }; ``` 在以上代码中,calculateFocusRect()方法用于计算对焦区域,可以根据需要自行实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值