FileDocCategorySizeDatePackage
CameraTooActivity.javaAPI DocAndroid 5.1 API18591Thu Mar 12 22:22:42 GMT 2015com.example.android.camera2.cameratoo

CameraTooActivity

public class CameraTooActivity extends android.app.Activity
A basic demonstration of how to write a point-and-shoot camera app against the new android.hardware.camera2 API.

Fields Summary
static final String
CAPTURE_FILENAME_PREFIX
Output files will be saved as /sdcard/Pictures/cameratoo*.jpg
static final String
TAG
Tag to distinguish log prints.
android.os.HandlerThread
mBackgroundThread
An additional thread for running tasks that shouldn't block the UI.
android.os.Handler
mBackgroundHandler
Handler for running tasks in the background.
android.os.Handler
mForegroundHandler
Handler for running tasks on the UI thread.
android.view.SurfaceView
mSurfaceView
View for displaying the camera preview.
android.media.ImageReader
mCaptureBuffer
Used to retrieve the captured image when the user takes a snapshot.
android.hardware.camera2.CameraManager
mCameraManager
Handle to the Android camera services.
android.hardware.camera2.CameraDevice
mCamera
The specific camera device that we're using.
android.hardware.camera2.CameraCaptureSession
mCaptureSession
Our image capture session.
final SurfaceHolder.Callback
mSurfaceHolderCallback
Callbacks invoked upon state changes in our {@code SurfaceView}.
final CameraDevice.StateCallback
mCameraStateCallback
Calledbacks invoked upon state changes in our {@code CameraDevice}.

These are run on {@code mBackgroundThread}.

final CameraCaptureSession.StateCallback
mCaptureSessionListener
Callbacks invoked upon state changes in our {@code CameraCaptureSession}.

These are run on {@code mBackgroundThread}.

final ImageReader.OnImageAvailableListener
mImageCaptureListener
Callback invoked when we've received a JPEG image from the camera.
Constructors Summary
Methods Summary
static android.util.SizechooseBigEnoughSize(android.util.Size[] choices, int width, int height)
Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose width and height are at least as large as the respective requested values.

param
choices The list of sizes that the camera supports for the intended output class
param
width The minimum desired width
param
height The minimum desired height
return
The optimal {@code Size}, or an arbitrary one if none were big enough


                                                                              
            
        // Collect the supported resolutions that are at least as big as the preview Surface
        List<Size> bigEnough = new ArrayList<Size>();
        for (Size option : choices) {
            if (option.getWidth() >= width && option.getHeight() >= height) {
                bigEnough.add(option);
            }
        }

        // Pick the smallest of those, assuming we found any
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else {
            Log.e(TAG, "Couldn't find any suitable preview size");
            return choices[0];
        }
    
public voidonClickOnSurfaceView(android.view.View v)
Called when the user clicks on our {@code SurfaceView}, which has ID {@code mainSurfaceView} as defined in the {@code mainactivity.xml} layout file.

Captures a full-resolution image and saves it to permanent storage.

        if (mCaptureSession != null) {
            try {
                CaptureRequest.Builder requester =
                        mCamera.createCaptureRequest(mCamera.TEMPLATE_STILL_CAPTURE);
                requester.addTarget(mCaptureBuffer.getSurface());
                try {
                    // This handler can be null because we aren't actually attaching any callback
                    mCaptureSession.capture(requester.build(), /*listener*/null, /*handler*/null);
                } catch (CameraAccessException ex) {
                    Log.e(TAG, "Failed to file actual capture request", ex);
                }
            } catch (CameraAccessException ex) {
                Log.e(TAG, "Failed to build actual capture request", ex);
            }
        } else {
            Log.e(TAG, "User attempted to perform a capture outside our session");
        }

        // Control flow continues in mImageCaptureListener.onImageAvailable()
    
protected voidonPause()
Called when our {@code Activity} loses focus.

Tears everything back down.

        super.onPause();

        try {
            // Ensure SurfaceHolderCallback#surfaceChanged() will run again if the user returns
            mSurfaceView.getHolder().setFixedSize(/*width*/0, /*height*/0);

            // Cancel any stale preview jobs
            if (mCaptureSession != null) {
                mCaptureSession.close();
                mCaptureSession = null;
            }
        } finally {
            if (mCamera != null) {
                mCamera.close();
                mCamera = null;
            }
        }

        // Finish processing posted messages, then join on the handling thread
        mBackgroundThread.quitSafely();
        try {
            mBackgroundThread.join();
        } catch (InterruptedException ex) {
            Log.e(TAG, "Background worker thread was interrupted while joined", ex);
        }

        // Close the ImageReader now that the background thread has stopped
        if (mCaptureBuffer != null) mCaptureBuffer.close();
    
protected voidonResume()
Called when our {@code Activity} gains focus.

Starts initializing the camera.

        super.onResume();

        // Start a background thread to manage camera requests
        mBackgroundThread = new HandlerThread("background");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
        mForegroundHandler = new Handler(getMainLooper());

        mCameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);

        // Inflate the SurfaceView, set it as the main layout, and attach a listener
        View layout = getLayoutInflater().inflate(R.layout.mainactivity, null);
        mSurfaceView = (SurfaceView) layout.findViewById(R.id.mainSurfaceView);
        mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);
        setContentView(mSurfaceView);

        // Control flow continues in mSurfaceHolderCallback.surfaceChanged()