下面列出了android.util.AndroidException#android.hardware.camera2.CameraCharacteristics 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@RequiresApi(21)
public static int getLowestSupportedHardwareLevel(@NonNull Context context) {
@SuppressLint("RestrictedApi") CameraManager cameraManager = CameraManagerCompat.from(context).unwrap();
try {
int supported = maxHardwareLevel();
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer hwLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (hwLevel == null || hwLevel == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}
supported = smallerHardwareLevel(supported, hwLevel);
}
return supported;
} catch (CameraAccessException e) {
Log.w(TAG, "Failed to enumerate cameras", e);
return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}
}
@TargetApi(21)
public static Size[] querySupportResolution(Context context, int index) {
CameraManager manager =
(CameraManager)context.getSystemService(CAMERA_SERVICE);
try {
CameraCharacteristics chars
= manager.getCameraCharacteristics(index+"");
StreamConfigurationMap configurationMap = chars.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
return configurationMap.getOutputSizes(ImageFormat.YUV_420_888);
} catch(CameraAccessException e){
e.printStackTrace();
}
return null;
}
@Override
protected List<PreviewSize> getSupportedSize() {
try {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(
getCurrentCameraId());
StreamConfigurationMap map =
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
return Collections.singletonList(new PreviewSize(mPreviewWidth, mPreviewHeight));
}
Size[] supportedSize = map.getOutputSizes(SurfaceTexture.class);
if (supportedSize == null || supportedSize.length == 0) {
return Collections.singletonList(new PreviewSize(mPreviewWidth, mPreviewHeight));
}
List<PreviewSize> results = new ArrayList<>();
for (Size size : supportedSize) {
results.add(new PreviewSize(size.getWidth(), size.getHeight()));
}
return results;
} catch (CameraAccessException e) {
throw new CameraAccessError();
}
}
private String getCameraId() {
if (mCameraId == null) {
try {
String[] ids = mCameraManager.getCameraIdList();
for (String id : ids) {
CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);
Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
if (flashAvailable != null && flashAvailable && lensFacing != null &&
lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
mCameraId = id;
}
}
if (DEBUG) Log.d(TAG, "getCameraId: " + mCameraId);
} catch (Exception e) {
e.printStackTrace();
mTorchStatus = TORCH_STATUS_ERROR;
broadcastStatus();
stopSelf();
}
}
return mCameraId;
}
private Range<Integer> selectCameraFpsRange(String camId, final int fps) throws CameraAccessException {
for (String id : cameraManager.getCameraIdList()) {
if (id.equals(camId)) {
CameraCharacteristics info = cameraManager.getCameraCharacteristics(id);
List<Range<Integer>> fpsLst = new ArrayList<>();
Collections.addAll(fpsLst,
info.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES));
/* sort list by error from desired fps *
* Android seems to do a better job at color correction/avoid 'dark frames' issue by
* selecting camera settings with the smallest lower bound on allowed frame rate
* range. */
return Collections.min(fpsLst, new Comparator<Range<Integer>>() {
@Override
public int compare(Range<Integer> lhs, Range<Integer> rhs) {
return calcError(lhs) - calcError(rhs);
}
private int calcError(Range<Integer> val) {
return val.getLower() + Math.abs(val.getUpper() - fps);
}
});
}
}
return null;
}
/**
* カメラID に対応したカメラデバイスがサポートしている写真サイズのリストを取得します.
*
* @param cameraManager カメラマネージャ
* @param cameraId カメラID
* @return サポートしている写真サイズのリスト
*/
@NonNull
static List<Size> getSupportedPictureSizes(final CameraManager cameraManager, final String cameraId) {
List<Size> pictureSizes = new ArrayList<>();
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if(map != null) {
pictureSizes = Arrays.asList(map.getOutputSizes(ImageFormat.JPEG));
Collections.sort(pictureSizes, SizeComparator);
}
} catch (CameraAccessException e) {
// ignore.
}
return pictureSizes;
}
/**
* カメラID に対応したカメラデバイスがサポートしているプレビューサイズのリストを取得します.
*
* @param cameraManager カメラマネージャ
* @param cameraId カメラID
* @return サポートしているプレビューサイズのリスト
*/
@NonNull
static List<Size> getSupportedPreviewSizes(final CameraManager cameraManager, final String cameraId) {
List<Size> previewSizes = new ArrayList<>();
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map != null) {
previewSizes = Arrays.asList(map.getOutputSizes(SurfaceTexture.class));
Collections.sort(previewSizes, SizeComparator);
}
} catch (CameraAccessException e) {
// ignore.
}
return previewSizes;
}
private void findCameraFacing(int direction) throws CameraAccessException {
for (String camId : mCamManager.getCameraIdList()) {
CameraCharacteristics characteristics = mCamManager.getCameraCharacteristics(camId);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == direction) {
mCameraId = camId;
Integer orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
if (orientation != null) {
mCameraOrientation = orientation;
}
Log.v(TAG, "found " + (direction == CameraCharacteristics.LENS_FACING_FRONT ? "front" : "back")
+ "-facing camera with id " + camId + " and orientation " + mCameraOrientation);
}
}
}
@SuppressLint("MissingPermission")
public void openCameraId(Integer cameraId) {
this.cameraId = cameraId;
if (prepared) {
HandlerThread cameraHandlerThread = new HandlerThread(TAG + " Id = " + cameraId);
cameraHandlerThread.start();
cameraHandler = new Handler(cameraHandlerThread.getLooper());
try {
cameraManager.openCamera(cameraId.toString(), this, cameraHandler);
CameraCharacteristics cameraCharacteristics =
cameraManager.getCameraCharacteristics(Integer.toString(cameraId));
running = true;
isFrontCamera =
(LENS_FACING_FRONT == cameraCharacteristics.get(CameraCharacteristics.LENS_FACING));
if (cameraCallbacks != null) {
cameraCallbacks.onCameraChanged(isFrontCamera);
}
} catch (CameraAccessException | SecurityException e) {
Log.e(TAG, "Error", e);
}
} else {
Log.e(TAG, "Camera2ApiManager need be prepared, Camera2ApiManager not enabled");
}
}
private LensShadingMap getLensShadingMap() {
float[] lsmArray = getBase(CaptureResult.STATISTICS_LENS_SHADING_MAP);
Size s = get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE);
// Do not warn if lsmArray is null while s is not. This is valid.
if (lsmArray == null) {
return null;
}
if (s == null) {
Log.w(TAG, "getLensShadingMap - Lens shading map size was null.");
return null;
}
LensShadingMap map = new LensShadingMap(lsmArray, s.getHeight(), s.getWidth());
return map;
}
private <T> Integer getMaxRegions(Key<T> key) {
final int AE = 0;
final int AWB = 1;
final int AF = 2;
// The order of the elements is: (AE, AWB, AF)
int[] maxRegions = getBase(CameraCharacteristics.CONTROL_MAX_REGIONS);
if (maxRegions == null) {
return null;
}
if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AE)) {
return maxRegions[AE];
} else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB)) {
return maxRegions[AWB];
} else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AF)) {
return maxRegions[AF];
} else {
throw new AssertionError("Invalid key " + key);
}
}
private int getRotation() {
int displayRotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
switch (displayRotation) {
case Surface.ROTATION_0:
displayRotation = 90;
break;
case Surface.ROTATION_90:
displayRotation = 0;
break;
case Surface.ROTATION_180:
displayRotation = 270;
break;
case Surface.ROTATION_270:
displayRotation = 180;
break;
}
int sensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
mDisplayRotate = (displayRotation + sensorOrientation + 270) % 360;
return mDisplayRotate;
}
/**
* Updates the internal state of auto-focus to {@link #mAutoFocus}.
*/
void updateAutoFocus() {
if (mAutoFocus) {
int[] modes = mCameraCharacteristics.get(
CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
// Auto focus is not supported
if (modes == null || modes.length == 0 ||
(modes.length == 1 && modes[0] == CameraCharacteristics.CONTROL_AF_MODE_OFF)) {
mAutoFocus = false;
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_OFF);
} else {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
}
} else {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_OFF);
}
}
private boolean setAvailableFormats(int[] value) {
int[] availableFormat = value;
if (value == null) {
// Let setBase() to handle the null value case.
return false;
}
int[] newValues = new int[availableFormat.length];
for (int i = 0; i < availableFormat.length; i++) {
newValues[i] = availableFormat[i];
if (availableFormat[i] == ImageFormat.JPEG) {
newValues[i] = NATIVE_JPEG_FORMAT;
}
}
setBase(CameraCharacteristics.SCALER_AVAILABLE_FORMATS, newValues);
return true;
}
private static String getLevel(Integer level) {
if (level == null) {
return UNKNOWN;
}
switch (level) {
case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY:
return "LEGACY";
case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3:
return "LEVEL_3";
case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL:
return "EXTERNAL";
case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL:
return "FULL";
case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED:
return "LIMITED";
default:
return UNKNOWN + "-" + level;
}
}
private String getCameraId() {
try {
String[] ids = mCameraManager.getCameraIdList();
for (String id : ids) {
CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);
Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
Integer facingDirection = c.get(CameraCharacteristics.LENS_FACING);
if (flashAvailable != null
&& flashAvailable
&& facingDirection != null
&& facingDirection == CameraCharacteristics.LENS_FACING_BACK) {
return id;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* Updates the internal state of auto-focus to {@link #mAutoFocus}.
*/
void updateAutoFocus() {
if (mAutoFocus) {
int[] modes = mCameraCharacteristics.get(
CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
// Auto focus is not supported
if (modes == null || modes.length == 0 ||
(modes.length == 1 && modes[0] == CameraCharacteristics.CONTROL_AF_MODE_OFF)) {
mAutoFocus = false;
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_OFF);
} else {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
}
} else {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_OFF);
}
}
public boolean isCamera2Native() {
try {
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return false;
}
manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
mCameraId = manager.getCameraIdList()[mFacing];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId);
//CHECK CAMERA HARDWARE LEVEL. IF CAMERA2 IS NOT NATIVELY SUPPORTED, GO BACK TO CAMERA1
Integer deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
return deviceLevel != null && (deviceLevel != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY);
} catch (CameraAccessException ex) {
return false;
} catch (NullPointerException e) {
return false;
} catch (ArrayIndexOutOfBoundsException ez) {
return false;
}
}
/**
* Returns the ID of the first camera facing the given direction.
*/
private String findFirstCameraIdFacing(int facing)
{
try
{
String[] cameraIds = mCameraManager.getCameraIdList();
for (String cameraId : cameraIds)
{
CameraCharacteristics characteristics = mCameraManager
.getCameraCharacteristics(cameraId);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing)
{
return cameraId;
}
}
} catch (CameraAccessException ex)
{
Log.w(TAG, "Unable to get camera ID", ex);
}
return null;
}
@Override
public int getOrientation(final int cameraId) {
try {
String[] cameraIds = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
} catch (CameraAccessException e) {
// TODO handle
return 0;
}
}
private static boolean isFrontFacing(Activity activity, String cameraId)
{
try {
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
return facing == CameraCharacteristics.LENS_FACING_FRONT;
} catch (android.hardware.camera2.CameraAccessException e) {
Log.e(TAG, "CameraAccessException");
throw new UnsupportedOperationException("CameraAccessException");
}
}
private void chooseFocusMode(CaptureRequest.Builder captureRequestBuilder) {
final int[] availableFocusModes =
cameraCharacteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
for (int mode : availableFocusModes) {
if (mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO) {
captureRequestBuilder.set(
CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
Logging.d(TAG, "Using continuous video auto-focus.");
return;
}
}
Logging.d(TAG, "Auto-focus is not available.");
}
private boolean isHardwareLevelSupported(
CameraCharacteristics characteristics, int requiredLevel) {
int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return requiredLevel == deviceLevel;
}
// deviceLevel is not LEGACY, can use numerical sort
return requiredLevel <= deviceLevel;
}
private String chooseCamera() {
final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (final String cameraId : manager.getCameraIdList()) {
final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// We don't use a front facing camera in this sample.
final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
continue;
}
final StreamConfigurationMap map =
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
continue;
}
// Fallback to camera1 API for internal cameras that don't have full support.
// This should help with legacy situations where using the camera2 API causes
// distorted or otherwise broken previews.
useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)
|| isHardwareLevelSupported(characteristics,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
Log.i(TAG, "Camera API lv2?: " + useCamera2API);
return cameraId;
}
} catch (CameraAccessException e) {
Log.e(TAG, "Not allowed to access camera: " + e);
}
return null;
}
/**
* 指定された facing に対応するカメラIDを取得します.
* <p>
* facing に対応したカメラが発見できない場合には null を返却します。
* </p>
* @param cameraManager カメラマネージャ
* @param facing カメラの向き
* @return カメラID
* @throws CameraAccessException カメラの操作に失敗した場合に発生
*/
private static String getCameraId(final CameraManager cameraManager, final int facing) throws CameraAccessException {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer supportFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (supportFacing != null && supportFacing == facing) {
return cameraId;
}
}
return null;
}
CameraImplV2(Activity context, TextureView prevView, boolean cameraFallback) throws CameraException {
super(context, prevView);
mCamManager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
if (mCamManager == null) {
throw new CameraException(mActivity.getString(R.string.couldNotObtainCameraService));
}
try {
findCameraFacing(CameraCharacteristics.LENS_FACING_FRONT);
if (mCameraId == null && cameraFallback) {
findCameraFacing(CameraCharacteristics.LENS_FACING_BACK);
}
} catch (CameraAccessException e) {
throw new CameraException(e);
}
if (mCameraId == null) {
if (cameraFallback) {
throw new CameraException(mActivity.getString(R.string.cameraMissing));
} else {
throw new CameraException(mActivity.getString(R.string.frontCameraMissing));
}
}
mPreviewThread = new HandlerThread("previewThread");
mPreviewThread.start();
mPreviewHandler = new Handler(mPreviewThread.getLooper());
}
/**
* 指定されたカメラIDの向きを取得します.
*
* @param cameraManager カメラマネージャ
* @param id カメラID
* @return 向き
* @throws CameraAccessException カメラの操作に失敗した場合に発生
*/
public static int getFacing(final CameraManager cameraManager, final String id) throws CameraAccessException {
for (String cameraId : cameraManager.getCameraIdList()) {
if (cameraId.equals(id)) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null) {
return facing;
}
}
}
return -1;
}
protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera,
CameraCharacteristics characteristics, CameraLooper cameraInit,
CameraCallbackThread cameraCallbacks) {
mLegacyDevice = legacyCamera;
mConfiguring = false;
mSurfaces = new SparseArray<Surface>();
mCameraCharacteristics = characteristics;
mCameraInit = cameraInit;
mCameraCallbacks = cameraCallbacks;
mSurfaceIdCounter = 0;
}
/**
* Create a new legacy request; the parameters are copied.
*
* @param characteristics immutable static camera characteristics for this camera
* @param captureRequest immutable user-defined capture request
* @param previewSize immutable internal preview size used for {@link Camera#setPreviewSurface}
* @param parameters the initial camera1 parameter state; (copied) can be mutated
*/
public LegacyRequest(CameraCharacteristics characteristics, CaptureRequest captureRequest,
Size previewSize, Camera.Parameters parameters) {
this.characteristics = checkNotNull(characteristics, "characteristics must not be null");
this.captureRequest = checkNotNull(captureRequest, "captureRequest must not be null");
this.previewSize = checkNotNull(previewSize, "previewSize must not be null");
checkNotNull(parameters, "parameters must not be null");
this.parameters = Camera.getParametersCopy(parameters);
}
private String chooseCamera() {
final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (final String cameraId : manager.getCameraIdList()) {
final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// We don't use a front facing camera in this sample.
final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
continue;
}
final StreamConfigurationMap map =
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
continue;
}
useCamera2API = isHardwareLevelSupported(characteristics,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
LOGGER.i("Camera API lv2?: %s", useCamera2API);
return cameraId;
}
} catch (CameraAccessException e) {
LOGGER.e(e, "Not allowed to access camera");
}
return null;
}