1. 相機使用流程
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZlBnaukDMwAjNmRjNhNjMmZjYzAjZ0QTN0QmNmVmY3kDO5UmZfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpeg)
圖1.jpg
2. SurfaceView
/**
* Android 5.0 使用Camera2 照相
* 使用SurfaceView顯示
* 主要步驟:
* 1. 獲得攝像頭管理器CameraManager mCameraManager,mCameraManager.openCamera()來打開攝像頭
* 2. 指定要打開的攝像頭,并建立openCamera()所需要的CameraDevice.StateCallback stateCallback
* 3. 在CameraDevice.StateCallback stateCallback中調用takePreview(),這個方法中,使用CaptureRequest.Builder建立預覽需要的CameraRequest,并初始化了CameraCaptureSession,最後調用了setRepeatingRequest(previewRequest, null, childHandler)進行了預覽
* 4. 點選拍照按鈕,調用takePicture(),這個方法内,最終調用了capture(mCaptureRequest, null, childHandler)
* 5. 在new ImageReader.OnImageAvailableListener(){}回調方法中,将拍照拿到的圖檔進行展示
*/
public class CameraSurfaceFragment extends Fragment {
/**照相機裝置請求碼*/
private static final int REQUEST_CAMERA_CODE = 0x100;
/**拍照*/
private Button mBtnTake;
/**顯示拍照好的圖檔*/
private ImageView mIvShow;
/**預覽視窗*/
private SurfaceView mSurfaceView;
/**預覽視窗Holder*/
private SurfaceHolder mSurfaceHolder;
/**子線程Handler*/
private Handler mChildHandler;
/**主線程Handler*/
private Handler mMainHandler;
/**照相機ID,辨別前置,後置*/
private String mCameraId;
/**圖檔讀取器*/
private ImageReader mImageReader;
/**攝像頭管理者*/
private CameraManager mCameraManager;
/**照相機裝置*/
private CameraDevice mCameraDevice;
/**照相會話*/
private CameraCaptureSession mCameraCaptureSession;
/**方向清單*/
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
/**
* 攝像頭狀态監聽
*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 打開攝像頭
mCameraDevice = camera;
// 開啟預覽
takePreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 關閉攝像頭
if (null != mCameraDevice) {
// 關閉攝像頭
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 攝像頭異常
Toast.makeText(getContext(), "攝像頭開啟失敗", Toast.LENGTH_SHORT).show();
}
};
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_camera_surface, container, false);
initView(root);
initListener();
return root;
}
/**
* 初始化View
*/
private void initView(View view) {
// 綁定View
mIvShow = view.findViewById(R.id.iv_show);
mBtnTake = view.findViewById(R.id.btn_take);
mSurfaceView = view.findViewById(R.id.sv_camera);
// 擷取Holder
mSurfaceHolder = mSurfaceView.getHolder();
// 設定螢幕常量
mSurfaceHolder.setKeepScreenOn(true);
// 設定SurfaceView回調
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceView 建立
initCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// SurfaceView 改變
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// SurfaceView 銷毀
// 銷毀照相機裝置
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
});
}
/**
* 初始化監聽器
*/
private void initListener() {
mBtnTake.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
/**
* 初始化照相機
*/
private void initCamera() {
// 建立Handler線程并啟動
HandlerThread handlerThread = new HandlerThread("Camera");
handlerThread.start();
// 建立子線程Handler
mChildHandler = new Handler(handlerThread.getLooper());
// 建立主線程Handler
mMainHandler = new Handler(Looper.getMainLooper());
// 設定後置攝像頭ID
mCameraId = String.valueOf(CameraCharacteristics.LENS_FACING_FRONT);
// 建立圖檔讀取器
mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG, 1);
// 圖檔讀取器設定圖檔可用監聽
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
showImage(reader);
}
}, mMainHandler);
// 擷取攝像頭管理
mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
// 打開攝像頭
try {
if (ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// 申請權限
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);
} else {
// 打開攝像頭
mCameraManager.openCamera(mCameraId, mStateCallback, mMainHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CAMERA_CODE == requestCode) {
// 權限允許
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, mStateCallback, mMainHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
// 權限拒絕
Toast.makeText(getContext(), "無權限", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 圖檔可用後,讀取并顯示圖檔
* @param reader 圖檔讀取器
*/
private void showImage(ImageReader reader) {
// 拿到圖檔資料
Image image = reader.acquireNextImage();
// 擷取位元組緩沖
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
// 建立與緩沖區相同的位元組數組
byte[] bytes = new byte[buffer.remaining()];
// 将資料讀取位元組數組
buffer.get(bytes);
// 建立圖檔
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
// 顯示圖檔
if (null != bitmap) {
mIvShow.setImageBitmap(bitmap);
}
}
/**
* 預覽
*/
private void takePreview() {
try {
// 建立預覽需要的CaptureRequest.Builder
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作為Builder的目标
builder.addTarget(mSurfaceHolder.getSurface());
// 建立CameraCaptureSession,該對象負責管理處理預覽請求和拍照請求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
// 檢測裝置是否為空
if (null == mCameraDevice) return;
// 配置
// 當攝像頭已經準備好時,開始顯示預覽
mCameraCaptureSession = session;
try {
// 自動對焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 打開閃光燈
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 顯示預覽
CaptureRequest request = builder.build();
// 會話設定重複請求
mCameraCaptureSession.setRepeatingRequest(request, null, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(getContext(), "配置失敗", Toast.LENGTH_SHORT).show();
}
}, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 拍照
*/
private void takePicture() {
// 判斷裝置是否為空
if (null == mCameraDevice) return;
// 建立拍照需要的CaptureRequest.Builder
final CaptureRequest.Builder builder;
try {
// 建立拍照請求
builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 将imageReader的surface作為CaptureRequest.Builder的木白哦
builder.addTarget(mImageReader.getSurface());
// 自動對焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 自動曝光
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 擷取手機方向
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
// 根據裝置方向計算設定照片的方向
builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
// 拍照
CaptureRequest request = builder.build();
// 拍照會話執行拍照
mCameraCaptureSession.capture(request, null, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
3. TextureView
/**
* Camera2 與 Texture使用
*/
public class CameraTextureFragment extends Fragment {
/**相機權限請求辨別*/
private static final int REQUEST_CAMERA_CODE = 0x100;
/**預覽*/
private TextureView mTextureView;
/**拍照按鈕*/
private Button mBtnTake;
/**圖檔*/
private ImageView mImageView;
/**照相機ID,辨別前置後置*/
private String mCameraId;
/**相機尺寸*/
private Size mCaptureSize;
/**圖像讀取者*/
private ImageReader mImageReader;
/**圖像主線程Handler*/
private Handler mCameraHandler;
/**相機裝置*/
private CameraDevice mCameraDevice;
/**預覽大小*/
private Size mPreviewSize;
/**相機請求*/
private CaptureRequest.Builder mCameraCaptureBuilder;
/**相機拍照捕獲會話*/
private CameraCaptureSession mCameraCaptureSession;
/**相機管理者*/
private CameraManager mCameraManager;
/**相機裝置狀态回調*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 打開
mCameraDevice = camera;
// 開始預覽
takePreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 斷開連接配接
camera.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 異常
camera.close();
mCameraDevice = null;
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_camera_texture, container, false);
initView(root);
initListener();
return root;
}
/**
* 初始化View
*/
private void initView(View view) {
// 初始化View
mImageView = view.findViewById(R.id.iv_show);
mTextureView = view.findViewById(R.id.tv_camera);
mBtnTake = view.findViewById(R.id.btn_take);
}
@Override
public void onResume() {
super.onResume();
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
// SurfaceTexture可用
// 設定相機參數并打開相機
setUpCamera(width, height);
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// SurfaceTexture大小改變
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
// SurfaceTexture 銷毀
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// SurfaceTexture 更新
}
});
}
/**
* 打開相機
*/
private void openCamera() {
// 擷取照相機管理者
mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);
return;
}
// 打開相機
mCameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CAMERA_CODE == requestCode) {
// 權限允許
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
// 權限拒絕
Toast.makeText(getContext(), "無權限", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 設定相機參數
* @param width 寬度
* @param height 高度
*/
private void setUpCamera(int width, int height) {
// 建立Handler
mCameraHandler = new Handler(Looper.getMainLooper());
// 擷取攝像頭的管理者
CameraManager cameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
try {
// 周遊所有攝像頭
for (String cameraId : cameraManager.getCameraIdList()) {
// 相機特性
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
// 擷取攝像頭是前置還是後置
Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
// 此處預設打開後置攝像頭
if (null != facing && CameraCharacteristics.LENS_FACING_FRONT == facing) continue;
// 擷取StreamConfigurationMap,管理攝像頭支援的所有輸出格式和尺寸
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
// 根據TextureView的尺寸設定預覽尺寸
mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
// 擷取相機支援的最大拍照尺寸
mCaptureSize = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getHeight() * rhs.getWidth());
}
});
// 此處ImageReader用于拍照所需
setupImageReader();
// 為攝像頭指派
mCameraId = cameraId;
break;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 設定ImageReader
*/
private void setupImageReader() {
// 2代表ImageReader中最多可以擷取兩幀圖像流
mImageReader = ImageReader.newInstance(mCaptureSize.getWidth(), mCaptureSize.getHeight(), ImageFormat.JPEG, 1);
// 設定圖像可用監聽
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
// 擷取圖檔
final Image image = reader.acquireNextImage();
// 送出任務,儲存圖檔
mCameraHandler.post(new ImageSaver(image));
// 更新UI
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// 擷取位元組緩沖區
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
// 建立數組之前調用此方法,恢複預設設定
buffer.rewind();
// 建立與緩沖區内容大小相同的數組
byte[] bytes = new byte[buffer.remaining()];
// 從緩沖區存入位元組數組,讀取完成之後position在末尾
buffer.get(bytes);
// 擷取Bitmap圖像
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
// 顯示
if (null != bitmap) {
mImageView.setImageBitmap(bitmap);
}
}
});
}
}, mCameraHandler);
}
/**
* 選擇SizeMap中大于并且最接近width和height的size
* @param sizeMap 可選的尺寸
* @param width 寬
* @param height 高
* @return 最接近width和height的size
*/
private Size getOptimalSize(Size[] sizeMap, int width, int height) {
// 建立清單
List<Size> sizeList = new ArrayList<>();
// 周遊
for (Size option : sizeMap) {
// 判斷寬度是否大于高度
if (width > height) {
if (option.getWidth() > width && option.getHeight() > height) {
sizeList.add(option);
}
} else {
if (option.getWidth() > height && option.getHeight() > width) {
sizeList.add(option);
}
}
}
// 判斷存儲Size的清單是否有資料
if (sizeList.size() > 0) {
return Collections.min(sizeList, new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() * rhs.getHeight());
}
});
}
return sizeMap[0];
}
/**
* 設定監聽
*/
private void initListener() {
mBtnTake.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
/**
* 預覽
*/
private void takePreview(){
// 擷取SurfaceTexture
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
// 設定預設的緩沖大小
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// 建立Surface
Surface previewSurface = new Surface(surfaceTexture);
try {
// 建立預覽請求
mCameraCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将previewSurface添加到預覽請求中
mCameraCaptureBuilder.addTarget(previewSurface);
// 建立會話
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
// 配置
CaptureRequest captureRequest = mCameraCaptureBuilder.build();
// 設置session
mCameraCaptureSession = session;
// 設定重複預覽請求
mCameraCaptureSession.setRepeatingRequest(captureRequest, null, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 配置失敗
}
}, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 拍照
*/
private void takePicture() {
try {
// 設定觸發
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mCameraCaptureBuilder.addTarget(mImageReader.getSurface());
// 拍照
mCameraCaptureSession.capture(mCameraCaptureBuilder.build(), null, mCameraHandler);
} catch (CameraAccessException e) {
Toast.makeText(getActivity(), "異常", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
/**
* 儲存圖檔任務
*/
private class ImageSaver implements Runnable {
/**圖像*/
private Image mImage;
ImageSaver(Image image) {
this.mImage = image;
}
@Override
public void run() {
// 擷取位元組緩沖區
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
// 建立數組之前調用此方法,恢複預設設定--重要
buffer.rewind();
// 建立與位元組緩沖區大小相同的位元組數組
byte[] data = new byte[buffer.remaining()];
// 将資料讀取位元組數組
buffer.get(data);
// 擷取緩存路徑
String path = getActivity().getExternalCacheDir().getPath();
// 擷取時間戳
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
// 檔案名
String fileName = path + "/IMG_" + timeStamp + ".jpg";
// 建立檔案輸出流
FileOutputStream fos = null;
try {
// 初始化檔案輸出流
fos = new FileOutputStream(fileName);
// 将資料寫入檔案
fos.write(data, 0, data.length);
// 重新整理緩沖區
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
4. 多功能相機
- 切換攝像頭
/**
* 後置攝像頭
*/
private static final int CAMERA_FRONT = CameraCharacteristics.LENS_FACING_FRONT;
/**
* 前置攝像頭
*/
private static final int CAMERA_BACK = CameraCharacteristics.LENS_FACING_BACK;
/**
* 照相機ID,辨別前置後置
*/
private String mCameraId;
/**
* 切換前後攝像頭
*/
private void switchCamera() {
if (String.valueOf(CAMERA_FRONT).equals(mCameraId)) {
// 後置
mCameraId = String.valueOf(CAMERA_BACK);
} else if (String.valueOf(CAMERA_BACK).equals(mCameraId)) {
// 前置
mCameraId = String.valueOf(CAMERA_FRONT);
}
closeCamera();
reOpenCamera();
}
/**
* 重新打開攝像頭
*/
private void reOpenCamera() {
if (mTextureView.isAvailable()) {
openCamera();
} else {
setTextureListener();
}
}
/**
* 關閉攝像頭
*/
private void closeCamera() {
if (null != mCameraCaptureSession) {
mCameraCaptureSession.close();
mCameraCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mImageReader) {
mImageReader.close();
mImageReader = null;
}
}
- 延時拍攝
/**
* 無延時
*/
private static final int DELAY_ZERO = 0;
/**
* 延時3秒
*/
private static final int DELAY_THREE = 3;
/**
* 延時10秒
*/
private static final int DELAY_TEN = 10;
/**
* 延時拍攝
*/
private void delayTake() {
switch (mDelayTime) {
case DELAY_ZERO:
mDelayTime = DELAY_THREE;
break;
case DELAY_THREE:
mDelayTime = DELAY_TEN;
break;
case DELAY_TEN:
mDelayTime = DELAY_ZERO;
break;
}
mBtnDelay.setText("延時" + mDelayTime + "秒");
if (mDelayTime == DELAY_ZERO) {
takePicture();
} else {
// 定時器
new CountDownTimer(mDelayTime * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mBtnDelay.setText(String.valueOf(millisUntilFinished/1000) + "秒");
}
@Override
public void onFinish() {
mBtnDelay.setText("延時" + mDelayTime + "秒");
takePicture();
}
}.start();
}
}
- 切換閃光
/**
* 閃光辨別--自動開啟
*/
private static final int FLASH_ZERO = 0;
/**
* 閃光辨別--總是開啟
*/
private static final int FLASH_ONE = 1;
/**
* 閃光辨別--關閉
*/
private static final int FLASH_TWO = 2;
/**
* 切換閃光模式
*/
private void switchFlash() {
switch(mFlashMode) {
case FLASH_ZERO:
mFlashMode = FLASH_ONE;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
break;
case FLASH_ONE:
mFlashMode = FLASH_TWO;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
break;
case FLASH_TWO:
mFlashMode = FLASH_ZERO;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
// 必須設定
mCameraCaptureBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
break;
}
try {
mCameraCaptureSession.setRepeatingRequest(mCameraCaptureBuilder.build(), null, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}