diff --git a/demo/src/main/java/com/google/android/cameraview/demo/MainActivity.java b/demo/src/main/java/com/google/android/cameraview/demo/MainActivity.java index 99119475..7c0d3210 100644 --- a/demo/src/main/java/com/google/android/cameraview/demo/MainActivity.java +++ b/demo/src/main/java/com/google/android/cameraview/demo/MainActivity.java @@ -247,6 +247,13 @@ public void onCameraClosed(CameraView cameraView) { Log.d(TAG, "onCameraClosed"); } + @Override + public void onCameraNotAvailable(CameraView cameraView) { + Log.d(TAG, "onCameraNotAvailable"); + Toast.makeText(cameraView.getContext(), R.string.camera_not_available, + Toast.LENGTH_LONG).show(); + } + @Override public void onPictureTaken(CameraView cameraView, final byte[] data) { Log.d(TAG, "onPictureTaken " + data.length); diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml index 76225995..5b62f479 100644 --- a/demo/src/main/res/values/strings.xml +++ b/demo/src/main/res/values/strings.xml @@ -22,4 +22,5 @@ Flash auto Flash off Flash on + There are no cameras available. diff --git a/library/src/main/api14/com/google/android/cameraview/Camera1.java b/library/src/main/api14/com/google/android/cameraview/Camera1.java index 1830c185..0eccc1bd 100644 --- a/library/src/main/api14/com/google/android/cameraview/Camera1.java +++ b/library/src/main/api14/com/google/android/cameraview/Camera1.java @@ -87,7 +87,10 @@ public void onSurfaceChanged() { @Override boolean start() { chooseCamera(); - openCamera(); + if (!openCamera()) { + return false; + } + if (mPreview.isReady()) { setUpPreview(); } @@ -285,11 +288,27 @@ private void chooseCamera() { mCameraId = INVALID_CAMERA_ID; } - private void openCamera() { + private boolean openCamera() { if (mCamera != null) { releaseCamera(); } - mCamera = Camera.open(mCameraId); + + mCamera = null; + if (mCameraId == INVALID_CAMERA_ID) { + mCallback.onCameraNotAvailable(); + return false; + } + + try { + mCamera = Camera.open(mCameraId); + } + catch(RuntimeException ex) { + mCamera = null; + mCallback.onCameraNotAvailable(); + return false; + } + + assert(mCamera != null); mCameraParameters = mCamera.getParameters(); // Supported preview sizes mPreviewSizes.clear(); @@ -308,6 +327,7 @@ private void openCamera() { adjustCameraParameters(); mCamera.setDisplayOrientation(calcCameraRotation(mDisplayOrientation)); mCallback.onCameraOpened(); + return true; } private AspectRatio chooseAspectRatio() { diff --git a/library/src/main/api21/com/google/android/cameraview/Camera2.java b/library/src/main/api21/com/google/android/cameraview/Camera2.java index 4835f89e..34dd7329 100644 --- a/library/src/main/api21/com/google/android/cameraview/Camera2.java +++ b/library/src/main/api21/com/google/android/cameraview/Camera2.java @@ -357,8 +357,12 @@ private boolean chooseCameraIdByFacing() { int internalFacing = INTERNAL_FACINGS.get(mFacing); final String[] ids = mCameraManager.getCameraIdList(); if (ids.length == 0) { // No camera - throw new RuntimeException("No camera available."); + mCameraId = null; + Log.e(TAG, "No camera devices present."); + mCallback.onCameraNotAvailable(); + return false; } + for (String id : ids) { CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(id); Integer level = characteristics.get( @@ -458,9 +462,13 @@ private void prepareImageReader() { *

The result will be processed in {@link #mCameraDeviceCallback}.

*/ private void startOpeningCamera() { + if (mCameraId == null) { + return; + } + try { mCameraManager.openCamera(mCameraId, mCameraDeviceCallback, null); - } catch (CameraAccessException e) { + } catch (SecurityException|CameraAccessException e) { throw new RuntimeException("Failed to open camera: " + mCameraId, e); } } diff --git a/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java b/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java index 31dab0c4..49575381 100644 --- a/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java +++ b/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java @@ -75,6 +75,8 @@ interface Callback { void onCameraClosed(); + void onCameraNotAvailable(); + void onPictureTaken(byte[] data); } diff --git a/library/src/main/java/com/google/android/cameraview/CameraView.java b/library/src/main/java/com/google/android/cameraview/CameraView.java index 04826d84..7719ce40 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -442,6 +442,13 @@ public void onCameraClosed() { } } + @Override + public void onCameraNotAvailable() { + for (Callback callback : mCallbacks) { + callback.onCameraNotAvailable(CameraView.this); + } + } + @Override public void onPictureTaken(byte[] data) { for (Callback callback : mCallbacks) { @@ -527,6 +534,14 @@ public void onCameraOpened(CameraView cameraView) { public void onCameraClosed(CameraView cameraView) { } + /** + * Called when there is no camera to open + * + * @param cameraView The associated {@link CameraView}. + */ + public void onCameraNotAvailable(CameraView cameraView) { + } + /** * Called when a picture is taken. *