2016-11-10 83 views
0

我想用camera2 api制作一个简单的flashlite应用程序。 我使用下面的代码:Android camera2 api openCamera error

public class FlashLightUtilForL { 
private CameraCaptureSession mSession; 
private CaptureRequest.Builder mBuilder; 
private CameraDevice mCameraDevice; 
private CameraManager mCameraManager; 

public FlashLightUtilForL(Context context) { 
    try { 
     mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 
     //here to judge if flash is available 
     CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics("0"); 
     boolean flashAvailable = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); 
     if (flashAvailable) { 
      mCameraManager.openCamera("0", new MyCameraDeviceStateCallback(), null); 
     } else { 
      //todo: throw Exception 
     } 
     //mCameraManager.openCamera("0", new MyCameraDeviceStateCallback(), null); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

class MyCameraDeviceStateCallback extends CameraDevice.StateCallback { 

    @Override 
    public void onOpened(CameraDevice camera) { 
     mCameraDevice = camera; 
     //get builder 
     try { 
      mBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL); 
      //flash on, default is on 
      mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO); 
      mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); 
      List<Surface> list = new ArrayList<Surface>(); 
      SurfaceTexture mSurfaceTexture = new SurfaceTexture(1); 
      Size size = getSmallestSize(mCameraDevice.getId()); 
      mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight()); 
      Surface mSurface = new Surface(mSurfaceTexture); 
      list.add(mSurface); 
      mBuilder.addTarget(mSurface); 
      camera.createCaptureSession(list, new MyCameraCaptureSessionStateCallback(), null); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onDisconnected(CameraDevice camera) { 

    } 

    @Override 
    public void onError(CameraDevice camera, int error) { 

    } 
} 

private Size getSmallestSize(String cameraId) throws CameraAccessException { 
    Size[] outputSizes = mCameraManager.getCameraCharacteristics(cameraId) 
      .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) 
      .getOutputSizes(SurfaceTexture.class); 
    if (outputSizes == null || outputSizes.length == 0) { 
     throw new IllegalStateException(
       "Camera " + cameraId + "doesn't support any outputSize."); 
    } 
    Size chosen = outputSizes[0]; 
    for (Size s : outputSizes) { 
     if (chosen.getWidth() >= s.getWidth() && chosen.getHeight() >= s.getHeight()) { 
      chosen = s; 
     } 
    } 
    return chosen; 
} 

/** 
* session callback 
*/ 
class MyCameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback { 

    @Override 
    public void onConfigured(CameraCaptureSession session) { 
     mSession = session; 
     try { 
      mSession.setRepeatingRequest(mBuilder.build(), null, null); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onConfigureFailed(CameraCaptureSession session) { 

    } 
} 

public void turnOnFlashLight() { 
    try { 
     mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); 
     mSession.setRepeatingRequest(mBuilder.build(), null, null); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void turnOffFlashLight() { 
    try { 
     mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF); 
     mSession.setRepeatingRequest(mBuilder.build(), null, null); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private void close() { 
    if (mCameraDevice == null || mSession == null) { 
     return; 
    } 
    mSession.close(); 
    mCameraDevice.close(); 
    mCameraDevice = null; 
    mSession = null; 
} 
} 

这里是我如何使用这个类从我的主要活动:

FlashLightUtilForL util = new FlashLightUtilForL(getApplicationContext()); 
util.turnOnFlashLight(); 

但不起任何作用。我发现打开相机时出现错误,但没有提示此错误是由什么引起的。这里是日志:

这是连续印刷三次:

11-10 15:27:32.881 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value manual 
11-10 15:27:32.881 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value fullscan 
11-10 15:27:32.881 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value nashville 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value hefe 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value valencia 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value xproll 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value lofi 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value sierra 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value walden 
11-10 15:27:32.882 11801-11801/com.flashlight W/ArrayUtils: Ignoring invalid value normal 

再一次:

11-10 15:27:32.909 11801-11801/com.flashlight I/CameraManager: Using legacy camera HAL. 
11-10 15:27:32.911 11801-12695/com.flashlight W/Camera: An error occurred while connecting to camera: 0 

我甚至不能找到与在camera2此特定错误什么。什么会导致这个问题? 该设备是Redmi Note 2与5.0.2,相机有手电筒,并且我在清单中添加了相机权限。

回答

0

我怀疑你的问题是从CameraDevice.TEMPLATE_MANUAL。并非所有设备都支持这一点另外,当设备使用旧版支持时,我认为这并不适用。尝试切换到CameraDevice.TEMPLATE_PREVIEW

此外,不要忘记当你不喜欢时发布SufaceTexture

+0

onOpened方法永远不会被调用,它不能是'CameraDevice.TEMPLATE_MANUAL'或'SufaceTexture'。 –