想问一下,如何在应用中同时控制闪光灯和启动相机预览?

如何在应用中同时控制闪光灯和启动相机预览?
比如我在开发一个相机应用,需要在开启相机预览前,根据环境光线决定是否打开闪光灯。这个咋实现啊?有代码么?

阅读 794
avatarAI BotBETA

要在应用中同时控制闪光灯并启动相机预览,你可以使用 Android 的 Camera2 API。以下是一个简要的实现步骤和示例代码片段:

步骤

  1. 权限处理:确保你的应用有访问相机和闪光灯的权限。
  2. 打开相机:使用 Camera2 API 打开相机并启动预览。
  3. 检测环境光线:可以使用 SensorManager 来获取光线传感器数据,或者使用相机预览帧来估算光线。
  4. 控制闪光灯:根据光线数据决定是否打开闪光灯。

示例代码

1. 权限处理

在你的 AndroidManifest.xml 中添加权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

在运行时请求权限(Android 6.0 及以上):

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.FLASHLIGHT) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.CAMERA, Manifest.permission.FLASHLIGHT},
            MY_PERMISSIONS_REQUEST_CAMERA_FLASHLIGHT);
}

2. 打开相机并启动预览

使用 Camera2 API 打开相机并设置预览:

private CameraDevice cameraDevice;
private CameraCaptureSession captureSession;
private CaptureRequest.Builder captureRequestBuilder;
private HandlerThread backgroundThread;
private Handler backgroundHandler;

private void openCamera() {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
        String cameraId = manager.getCameraIdList()[0];
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
        StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        assert map != null;
        Size largest = Collections.max(
                Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),
                new CompareSizesByArea()
        );
        ImageReader reader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.YUV_420_888, 2);
        List<Surface> outputSurfaces = new ArrayList<>(2);
        outputSurfaces.add(reader.getSurface());
        Surface previewSurface = new Surface(textureView.getSurfaceTexture());
        outputSurfaces.add(previewSurface);
        final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        captureBuilder.addTarget(previewSurface);
        captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
        
        // Initialize other settings such as flash mode here
        // captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
        
        manager.openCamera(cameraId, stateCallback, backgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice camera) {
        cameraDevice = camera;
        createCameraPreviewSession();
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice camera) {
        cameraDevice.close();
    }

    @Override
    public void onError(@NonNull CameraDevice camera, int error) {
        cameraDevice.close();
        cameraDevice = null;
    }
};

private void createCameraPreviewSession() {
    try {
        SurfaceTexture texture = textureView.getSurfaceTexture();
        assert texture != null;
        texture.setDefaultBufferSize(1920, 1080);
        Surface surface = new Surface(texture);
        captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        captureRequestBuilder.addTarget(surface);
        cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {
                if (cameraDevice == null) {
                    return;
                }
                captureSession = session;
                try {
1 个回答

同学,首先你需要检查设备是否支持闪光灯并获取当前的手电筒模式。
再根据需要,设置闪光灯模式,并随后初始化相机并创建预览输出。

例如下面的代码:

import { camera } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';

async function setupCameraAndFlash(cameraManager, surfaceId) {
  try {
    // 检查是否支持手电筒
    if (cameraManager.isTorchSupported()) {
      // 设定为自动模式或根据需要设置为开或关
      cameraManager.setTorchMode(camera.TorchMode.AUTO);
    }

    // 获取相机并打开
    let cameraInput = await cameraManager.createCameraInput(camera.CameraPosition.BACK, camera.CameraType.DEFAULT);
    await cameraInput.open();

    // 创建预览输出
    let previewOutput = await cameraManager.createPreviewOutput(surfaceId);

    console.info('Camera setup with flash and preview is ready.');
  } catch (error) {
    console.error(`Setup failed, error code: ${error.code}, message: ${error.message}`);
  }
}

你试试~!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题