ctor public CameraAccessException(int, java.lang.String, java.lang.Throwable);
ctor public CameraAccessException(int, java.lang.Throwable);
method public final int getReason();
- field public static final int CAMERA_DISABLED = 3; // 0x3
- field public static final int CAMERA_DISCONNECTED = 4; // 0x4
- field public static final int CAMERA_IN_USE = 1; // 0x1
- field public static final int MAX_CAMERAS_IN_USE = 2; // 0x2
+ field public static final int CAMERA_DISABLED = 1; // 0x1
+ field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+ field public static final int CAMERA_ERROR = 3; // 0x3
}
public abstract interface CameraDevice implements java.lang.AutoCloseable {
method public abstract void capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void captureBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
- method public abstract void close() throws java.lang.Exception;
+ method public abstract void close();
method public abstract void configureOutputs(java.util.List<android.view.Surface>) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void flush() throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
method public abstract android.hardware.camera2.CameraProperties getProperties() throws android.hardware.camera2.CameraAccessException;
- method public abstract void setDeviceListener(android.hardware.camera2.CameraDevice.CameraDeviceListener, android.os.Handler);
method public abstract void setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
}
- public static abstract class CameraDevice.CameraDeviceListener {
- ctor public CameraDevice.CameraDeviceListener();
- method public void onCameraDisconnected(android.hardware.camera2.CameraDevice);
- method public void onCameraError(android.hardware.camera2.CameraDevice, int);
- method public void onCameraIdle(android.hardware.camera2.CameraDevice);
- field public static final int ERROR_CAMERA_DEVICE = 1; // 0x1
- field public static final int ERROR_CAMERA_SERVICE = 2; // 0x2
- }
-
public static abstract class CameraDevice.CaptureListener {
ctor public CameraDevice.CaptureListener();
method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long);
}
+ public static abstract class CameraDevice.StateListener {
+ ctor public CameraDevice.StateListener();
+ method public void onActive(android.hardware.camera2.CameraDevice);
+ method public void onBusy(android.hardware.camera2.CameraDevice);
+ method public void onClosed(android.hardware.camera2.CameraDevice);
+ method public abstract void onDisconnected(android.hardware.camera2.CameraDevice);
+ method public abstract void onError(android.hardware.camera2.CameraDevice, int);
+ method public void onIdle(android.hardware.camera2.CameraDevice);
+ method public abstract void onOpened(android.hardware.camera2.CameraDevice);
+ method public void onUnconfigured(android.hardware.camera2.CameraDevice);
+ field public static final int ERROR_CAMERA_DEVICE = 4; // 0x4
+ field public static final int ERROR_CAMERA_DISABLED = 3; // 0x3
+ field public static final int ERROR_CAMERA_IN_USE = 1; // 0x1
+ field public static final int ERROR_CAMERA_SERVICE = 5; // 0x5
+ field public static final int ERROR_MAX_CAMERAS_IN_USE = 2; // 0x2
+ }
+
public final class CameraManager {
method public void addAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener, android.os.Handler);
method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
method public android.hardware.camera2.CameraProperties getCameraProperties(java.lang.String) throws android.hardware.camera2.CameraAccessException;
- method public android.hardware.camera2.CameraDevice openCamera(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+ method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public void removeAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener);
}
*
* @return the static properties of the camera
*
- * @throws CameraAccessException if the camera device is no longer connected
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera device has been closed
*
* @see CameraManager#getCameraProperties
*/
*
* <p>To reach an idle state without cancelling any submitted captures, first
* stop any repeating request/burst with {@link #stopRepeating}, and then
- * wait for the {@link CameraDeviceListener#onCameraIdle} callback to be
+ * wait for the {@link StateListener#onIdle} callback to be
* called. To idle as fast as possible, use {@link #flush} and wait for the
* idle callback.</p>
*
* <p>Using larger resolution outputs, or more outputs, can result in slower
* output rate from the device.</p>
*
+ * <p>Configuring the outputs with an empty or null list will transition
+ * the camera into an {@link StateListener#onUnconfigured unconfigured state}.
+ * </p>
+ *
+ * <p>Calling configureOutputs with the same arguments as the last call to
+ * configureOutputs has no effect.</p>
+ *
* @param outputs The new set of Surfaces that should be made available as
* targets for captured image data.
*
* @throws IllegalArgumentException if the set of output Surfaces do not
* meet the requirements
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device is not idle, or has
- * encountered a fatal error
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera device is not idle, or
+ * if the camera device has been closed
*
- * @see CameraDeviceListener#onCameraIdle
+ * @see StateListener#onIdle
* @see #stopRepeating
* @see #flush
*/
*
* @throws IllegalArgumentException if the templateType is not in the list
* of supported templates.
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera device has been closed
*
* @see #TEMPLATE_PREVIEW
* @see #TEMPLATE_RECORD
* {@code null} to use the current thread's {@link android.os.Looper
* looper}.
*
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is currently busy or unconfigured,
+ * or the camera device has been closed.
* @throws IllegalArgumentException If the request targets Surfaces not
* currently configured as outputs. Or if the handler is null, the listener
* is not null, and the calling thread has no looper.
* {@code null} to use the current thread's {@link android.os.Looper
* looper}.
*
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is currently busy or unconfigured,
+ * or the camera device has been closed.
* @throws IllegalArgumentException If the requests target Surfaces not
* currently configured as outputs. Or if the handler is null, the listener
* is not null, and the calling thread has no looper.
* {@code null} to use the current thread's {@link android.os.Looper
* looper}.
*
- * @throws CameraAccessException if the camera device is no longer
- * connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is currently busy or unconfigured,
+ * or the camera device has been closed.
* @throws IllegalArgumentException If the requests reference Surfaces not
* currently configured as outputs. Or if the handler is null, the listener
* is not null, and the calling thread has no looper.
* {@code null} to use the current thread's {@link android.os.Looper
* looper}.
*
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is currently busy or unconfigured,
+ * or the camera device has been closed.
* @throws IllegalArgumentException If the requests reference Surfaces not
* currently configured as outputs. Or if the handler is null, the listener
* is not null, and the calling thread has no looper.
* <p>Any currently in-flight captures will still complete, as will any
* burst that is mid-capture. To ensure that the device has finished
* processing all of its capture requests and is in idle state, wait for the
- * {@link CameraDeviceListener#onCameraIdle} callback after calling this
+ * {@link StateListener#onIdle} callback after calling this
* method..</p>
*
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed or the
- * device has encountered a fatal error.
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is currently busy or unconfigured,
+ * or the camera device has been closed.
*
* @see #setRepeatingRequest
* @see #setRepeatingBurst
- * @see CameraDeviceListener#onCameraIdle
- *
- * @throws CameraAccessException if the camera device is no longer connected
- * @throws IllegalStateException if the camera device has been closed, the
- * device has encountered a fatal error, or if there is an active repeating
- * request or burst.
+ * @see StateListener#onIdle
*/
public void stopRepeating() throws CameraAccessException;
* {@link CaptureListener}.</p>
*
* <p>If the camera device is idle when the listener is set, then the
- * {@link CameraDeviceListener#onCameraIdle} method will be immediately called,
+ * {@link StateListener#onIdle} method will be immediately called,
* even if the device has never been active before.
* </p>
*
*
* @throws IllegalArgumentException if handler is null, the listener is
* not null, and the calling thread has no looper
+ *
+ * @hide
*/
- public void setDeviceListener(CameraDeviceListener listener, Handler handler);
+ public void setDeviceListener(StateListener listener, Handler handler);
/**
* Flush all captures currently pending and in-progress as fast as
* configurations, or for cancelling long in-progress requests (such as a
* multi-second capture).</p>
*
- * @throws CameraAccessException if the camera device is no longer connected
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error
+ * @throws IllegalStateException if the camera is not idle/active,
+ * or the camera device has been closed.
+ *
* @see #setRepeatingRequest
* @see #setRepeatingBurst
* @see #configureOutputs
* Close the connection to this camera device. After this call, all calls to
* the camera device interface will throw a {@link IllegalStateException},
* except for calls to close().
- * @throws Exception
*/
@Override
- public void close() throws Exception;
+ public void close();
// TODO: We should decide on the behavior of in-flight requests should be on close.
/**
*
* @see #setDeviceListener
*/
- public static abstract class CameraDeviceListener {
+ public static abstract class StateListener {
+ /**
+ * An error code that can be reported by {@link #onError}
+ * indicating that the camera device is in use already.
+ *
+ * <p>
+ * This error can be produced when opening the camera fails.
+ * </p>
+ *
+ * @see #onError
+ */
+ public static final int ERROR_CAMERA_IN_USE = 1;
/**
- * An error code that can be reported by {@link #onCameraError}
+ * An error code that can be reported by {@link #onError}
+ * indicating that the camera device could not be opened
+ * because there are too many other open camera devices.
+ *
+ * <p>
+ * The system-wide limit for number of open cameras has been reached,
+ * and more camera devices cannot be opened until previous instances are
+ * closed.
+ * </p>
+ *
+ * <p>
+ * This error can be produced when opening the camera fails.
+ * </p>
+ *
+ * @see #onError
+ */
+ public static final int ERROR_MAX_CAMERAS_IN_USE = 2;
+
+ /**
+ * An error code that can be reported by {@link #onError}
+ * indicating that the camera device could not be opened due to a device
+ * policy.
+ *
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean)
+ * @see #onError
+ */
+ public static final int ERROR_CAMERA_DISABLED = 3;
+
+ /**
+ * An error code that can be reported by {@link #onError}
* indicating that the camera device has encountered a fatal error.
*
* <p>The camera device needs to be re-opened to be used again.</p>
*
- * @see #onCameraDeviceError
+ * @see #onError
*/
- public static final int ERROR_CAMERA_DEVICE = 1;
+ public static final int ERROR_CAMERA_DEVICE = 4;
/**
- * An error code that can be reported by {@link #onCameraError}
+ * An error code that can be reported by {@link #onError}
* indicating that the camera service has encountered a fatal error.
*
* <p>The Android device may need to be shut down and restarted to restore
* camera function, or there may be a persistent hardware problem.</p>
*
- * @see #onCameraDeviceError
+ * <p>An attempt at recovery <i>may</i> be possible by closing the
+ * CameraDevice and the CameraManager, and trying to acquire all resources
+ * again from scratch.</p>
+ *
+ * @see #onError
+ */
+ public static final int ERROR_CAMERA_SERVICE = 5;
+
+ /**
+ * The method called when a camera device has finished opening.
+ *
+ * <p>An opened camera will immediately afterwards transition into
+ * {@link #onUnconfigured}.</p>
+ *
+ * @param camera the camera device that has become opened
+ */
+ public abstract void onOpened(CameraDevice camera); // Must implement
+
+ /**
+ * The method called when a camera device has no outputs configured.
+ *
+ * <p>An unconfigured camera device needs to be configured with
+ * {@link CameraDevice#configureOutputs} before being able to
+ * submit any capture request.</p>
+ *
+ * <p>This state may be entered by a newly opened camera or by
+ * calling {@link CameraDevice#configureOutputs} with a null/empty
+ * list of Surfaces when idle.</p>
+ *
+ * <p>Any attempts to submit a capture request while in this state
+ * will result in an {@link IllegalStateException} being thrown.</p>
+ *
+ * <p>The default implementation of this method does nothing.</p>
+ *
+ * @param camera the camera device has that become unconfigured
+ */
+ public void onUnconfigured(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device begins processing
+ * {@link CaptureRequest capture requests}.
+ *
+ * <p>A camera may not be re-configured while in this state. The camera
+ * will transition to the idle state once all pending captures have
+ * completed. If a repeating request is set, the camera will remain active
+ * until it is cleared and the remaining requests finish processing. To
+ * transition to the idle state as quickly as possible, call {@link #flush()},
+ * which will idle the camera device as quickly as possible, likely canceling
+ * most in-progress captures.</p>
+ *
+ * <p>All calls except for {@link CameraDevice#configureOutputs} are
+ * legal while in this state.
+ * </p>
+ *
+ * <p>The default implementation of this method does nothing.</p>
+ *
+ * @param camera the camera device that has become active
+ *
+ * @see CameraDevice#capture
+ * @see CameraDevice#captureBurst
+ * @see CameraDevice#setRepeatingBurst
+ * @see CameraDevice#setRepeatingRequest
+ */
+ public void onActive(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device is busy.
+ *
+ * <p>A camera becomes busy while it's outputs are being configured
+ * (after a call to {@link CameraDevice#configureOutputs} or while it's
+ * being flushed (after a call to {@link CameraDevice#flush}.</p>
+ *
+ * <p>Once the on-going operations are complete, the camera will automatically
+ * transition into {@link #onIdle} if there is at least one configured output,
+ * or {@link #onUnconfigured} otherwise.</p>
+ *
+ * <p>Any attempts to manipulate the camera while its is busy
+ * will result in an {@link IllegalStateException} being thrown.</p>
+ *
+ * <p>Only the following methods are valid to call while in this state:
+ * <ul>
+ * <li>{@link CameraDevice#getId}</li>
+ * <li>{@link CameraDevice#createCaptureRequest}</li>
+ * <li>{@link CameraDevice#close}</li>
+ * </ul>
+ * </p>
+ *
+ * <p>The default implementation of this method does nothing.</p>
+ *
+ * @param camera the camera device that has become busy
+ *
+ * @see CameraDevice#configureOutputs
+ * @see CameraDevice#flush
+ */
+ public void onBusy(CameraDevice camera) {
+ // Default empty implementation
+ }
+
+ /**
+ * The method called when a camera device has been closed with
+ * {@link CameraDevice#close}.
+ *
+ * <p>Any attempt to call methods on this CameraDevice in the
+ * future will throw a {@link IllegalStateException}.</p>
+ *
+ * <p>The default implementation of this method does nothing.</p>
+ *
+ * @param camera the camera device that has become closed
*/
- public static final int ERROR_CAMERA_SERVICE = 2;
+ public void onClosed(CameraDevice camera) {
+ // Default empty implementation
+ }
/**
* The method called when a camera device has finished processing all
* submitted capture requests and has reached an idle state.
*
- * <p>An idle camera device can have its outputs changed by calling
- * {@link CameraDevice#configureOutputs}.</p>
+ * <p>An idle camera device can have its outputs changed by calling {@link
+ * CameraDevice#configureOutputs}, which will transition it into the busy state.</p>
*
- * <p>To idle and reconfigure outputs without cancelling any submitted
+ * <p>To idle and reconfigure outputs without canceling any submitted
* capture requests, the application needs to clear its repeating
* request/burst, if set, with {@link CameraDevice#stopRepeating}, and
* then wait for this callback to be called before calling {@link
*
* <p>To idle and reconfigure a camera device as fast as possible, the
* {@link CameraDevice#flush} method can be used, which will discard all
- * pending and in-progess capture requests. Once the {@link
+ * pending and in-progress capture requests. Once the {@link
* CameraDevice#flush} method is called, the application must wait for
* this callback to fire before calling {@link
* CameraDevice#configureOutputs}.</p>
* @see CameraDevice#stopRepeating
* @see CameraDevice#flush
*/
- public void onCameraIdle(CameraDevice camera) {
+ public void onIdle(CameraDevice camera) {
// Default empty implementation
}
* The method called when a camera device is no longer available for
* use.
*
+ * <p>This callback may be called instead of {@link #onOpened}
+ * if opening the camera fails.</p>
+ *
* <p>Any attempt to call methods on this CameraDevice will throw a
* {@link CameraAccessException}. The disconnection could be due to a
* change in security policy or permissions; the physical disconnection
* <p>The default implementation logs a notice to the system log
* about the disconnection.</p>
*
+ * <p>You should clean up the camera with {@link CameraDevice#close} after
+ * this happens, as it is not recoverable until opening the camera again
+ * after it becomes {@link CameraManager.AvailabilityListener#onCameraAvailable available}.
+ * </p>
+ *
* @param camera the device that has been disconnected
*/
- public void onCameraDisconnected(CameraDevice camera) {
- Log.i("CameraListener",
- String.format("Camera device %s disconnected", camera.getId()));
- }
+ public abstract void onDisconnected(CameraDevice camera); // Must implement
/**
* The method called when a camera device has encountered a serious error.
*
+ * <p>This callback may be called instead of {@link #onOpened}
+ * if opening the camera fails.</p>
+ *
* <p>This indicates a failure of the camera device or camera service in
* some way. Any attempt to call methods on this CameraDevice in the
- * future will throw a {@link java.lang.IllegalStateException}.</p>
+ * future will throw a {@link CameraAccessException} with the
+ * {@link CameraAccessException#CAMERA_ERROR CAMERA_ERROR} reason.
+ * </p>
*
* <p>There may still be capture completion or camera stream listeners
* that will be called after this error is received.</p>
*
- * <p>The default implementation logs an error to the system log about
- * the camera failure.</p>
+ * <p>You should clean up the camera with {@link CameraDevice#close} after
+ * this happens. Further attempts at recovery are error-code specific.</p>
*
* @param camera The device reporting the error
* @param error The error code, one of the
*
* @see #ERROR_CAMERA_DEVICE
* @see #ERROR_CAMERA_SERVICE
+ * @see #ERROR_CAMERA_DISABLED
+ * @see #ERROR_CAMERA_IN_USE
*/
- public void onCameraError(CameraDevice camera, int error) {
- Log.e("CameraListener",
- String.format("Camera device %s has encountered an error: %d",
- camera.getId(), error));
- }
+ public abstract void onError(CameraDevice camera, int error); // Must implement
}
}
private final ICameraService mCameraService;
private ArrayList<String> mDeviceIdList;
- private ArrayMap<AvailabilityListener, Handler> mListenerMap =
+ private final ArrayMap<AvailabilityListener, Handler> mListenerMap =
new ArrayMap<AvailabilityListener, Handler>();
private final Context mContext;
* @see #getCameraIdList
* @see android.app.admin.DevicePolicyManager#setCameraDisabled
*/
- public CameraDevice openCamera(String cameraId) throws CameraAccessException {
-
+ private CameraDevice openCamera(String cameraId) throws CameraAccessException {
try {
synchronized (mLock) {
}
/**
+ * Open a connection to a camera with the given ID.
+ *
+ * <p>Use {@link #getCameraIdList} to get the list of available camera
+ * devices. Note that even if an id is listed, open may fail if the device
+ * is disconnected between the calls to {@link #getCameraIdList} and
+ * {@link #openCamera}.</p>
+ *
+ * <p>If the camera successfully opens after this function call returns,
+ * {@link CameraDevice.StateListener#onOpened} will be invoked with the
+ * newly opened {@link CameraDevice} in the unconfigured state.</p>
+ *
+ * <p>If the camera becomes disconnected during initialization
+ * after this function call returns,
+ * {@link CameraDevice.StateListener#onDisconnected} with a
+ * {@link CameraDevice} in the disconnected state (and
+ * {@link CameraDevice.StateListener#onOpened} will be skipped).</p>
+ *
+ * <p>If the camera fails to initialize after this function call returns,
+ * {@link CameraDevice.StateListener#onError} will be invoked with a
+ * {@link CameraDevice} in the error state (and
+ * {@link CameraDevice.StateListener#onOpened} will be skipped).</p>
+ *
+ * @param cameraId
+ * The unique identifier of the camera device to open
+ * @param listener
+ * The listener which is invoked once the camera is opened
+ * @param handler
+ * The handler on which the listener should be invoked, or
+ * {@code null} to use the current thread's {@link android.os.Looper looper}.
+ *
+ * @throws CameraAccessException if the camera is disabled by device policy,
+ * or the camera has become or was disconnected.
+ *
+ * @throws IllegalArgumentException if cameraId or the listener was null,
+ * or the cameraId does not match any currently or previously available
+ * camera device.
+ *
+ * @throws SecurityException if the application does not have permission to
+ * access the camera
+ *
+ * @see #getCameraIdList
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+ */
+ public void openCamera(String cameraId, final CameraDevice.StateListener listener,
+ Handler handler)
+ throws CameraAccessException {
+
+ if (cameraId == null) {
+ throw new IllegalArgumentException("cameraId was null");
+ } else if (listener == null) {
+ throw new IllegalArgumentException("listener was null");
+ } else if (handler == null) {
+ if (Looper.myLooper() != null) {
+ handler = new Handler();
+ } else {
+ throw new IllegalArgumentException(
+ "Looper doesn't exist in the calling thread");
+ }
+ }
+
+ final CameraDevice camera = openCamera(cameraId);
+ camera.setDeviceListener(listener, handler);
+
+ // TODO: make truly async in the camera service
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onOpened(camera);
+ }
+ });
+ }
+
+ /**
* Interface for listening to camera devices becoming available or
* unavailable.
*
*
* <p>If an application had an active CameraDevice instance for the
* now-disconnected camera, that application will receive a
- * {@link CameraDevice.CameraDeviceListener#onCameraDisconnected disconnection error}.</p>
+ * {@link CameraDevice.StateListener#onDisconnected disconnection error}.</p>
*
* <p>The default implementation of this method does nothing.</p>
*
if (isAvailable(status)) {
handler.post(
new Runnable() {
+ @Override
public void run() {
listener.onCameraAvailable(id);
}
} else {
handler.post(
new Runnable() {
+ @Override
public void run() {
listener.onCameraUnavailable(id);
}