Tutorial for using Androids API 5.0 Camera package

This is a tutorial on implementing the use of the camera with the new Android 5.0 (Lollipop) API.  You will notice from the Android developer’s site that the previous API has been deprecated.  A Few things to make sure are done before starting.

In the Android Manifest file, you will need to make sure to allow permissions for the app to sue the device’s camera. Below is the bit of code which is implemented within the <manifest> tag:

<uses-permission android:name=”android.permission.CAMERA” />

The next part of this tutorial will show you what you will need to do to build the UI for the camera.  Within the “/res/layout” directory, you will need an xml file to define the views or User Interface of the application.  Below is a brief tutorial on how to get started.

You will create a layout file. This file will be the file containing a frame layout with the context linking to the java file storing the code for the camera functionality.

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:tools=”http://schemas.android.com/tools”
android:id=”@+id/container”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”#000″
tools:context=”com.example.android.camera2basic.CameraActivity”/>

The following code is the above referenced class that is needed to build a fragment manager in order to create the fragment within the app.

public class CameraActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
if (null == savedInstanceState) {
getFragmentManager().beginTransaction()
.replace(R.id.container, Camera2BasicFragment.newInstance())
.commit();
}
}

}

This next part is the largest part of coding for that app.  Below I will target the methods and variables used as key code parts for implementing the new camera2 package for android.  It should be understood that for tutorial purposes, there is a large amount of general code that is needed for all android projects. I will break down the needed parts strictly for the camera.

 

 

 

Imports:

You will need to import some packages into your source code so that you will have access to the classes and methods in order to use the camera functionality.

import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;

These are some core packages you will need. There are others that are not required but are useful if you want the most out of your development.

Next you will want to start by creating a a public class that extends the fragment class.

public class Camera2BasicFragment extends Fragment implements View.OnClickListener {

Within this class you will need to implement the following code that previews the camera lends upon the camera device being opened.

@Override

public void onOpened(CameraDevice cameraDevice) {

// This method is called when the camera is opened.  We start camera preview here.

mCameraOpenCloseLock.release();

mCameraDevice = cameraDevice;

createCameraPreviewSession();

}

 

This next bit of code closes the preview upon the camera closing.

@Override

public void onDisconnected(CameraDevice cameraDevice) {

mCameraOpenCloseLock.release();

cameraDevice.close();

mCameraDevice = null;

}

 

To have errors reported you will need the following bit.

@Override

public void onError(CameraDevice cameraDevice, int error) {

mCameraOpenCloseLock.release();

cameraDevice.close();

mCameraDevice = null;

Activity activity = getActivity();

if (null != activity) {

activity.finish();

}

}

Next you will need to create a view to display your camera on the screen.  The following will demonstrate how to do so.

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_camera2_basic, container, false);

}

 

At this time we will want to fill the view by calling an openCamera method of which we will make a call to a service and make use of the camera hardware. Below is how to do so.

private void openCamera(int width, int height) {

setUpCameraOutputs(width, height);

configureTransform(width, height);

Activity activity = getActivity();

CameraManager manager = CameraManager)activity.getSystemService(Context.CAMERA_SERVICE);

try {

if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {

throw new RuntimeException(“Time out waiting to lock camera opening.”);

}

manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);

} catch (CameraAccessException e) {

e.printStackTrace();

} catch (InterruptedException e) {

throw new RuntimeException(“Interrupted while trying to lock camera opening.”, e);

}

}

 

To finalize this tutorial, I will quickly run down the needed methods to capture and image and close the camera.

 

This is how to take a picture which will lock focus and ready a still image to make use of later.

private void captureStillPicture() {

try {

final Activity activity = getActivity();

if (null == activity || null == mCameraDevice) {

return;

}

// This is the CaptureRequest.Builder that we use to take a picture.

final CaptureRequest.Builder captureBuilder =

mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

captureBuilder.addTarget(mImageReader.getSurface());

 

// Use the same AE and AF modes as the preview.

captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,

CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,

CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

 

// Orientation

int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

 

CameraCaptureSession.CaptureCallback CaptureCallback

= new CameraCaptureSession.CaptureCallback() {

 

@Override

public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,

TotalCaptureResult result) {

Toast.makeText(getActivity(), “Saved: ” + mFile, Toast.LENGTH_SHORT).show();

unlockFocus();

}

};

 

mCaptureSession.stopRepeating();

mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

 

After capturing the image, you may build the portion of your code to do as you please. Many other apps use the camera and do different thing. For example snap chat captures an image and sends to another user. Tinder is an app that can take a picture, store it on the device and allow other users to view and interact with your account using the image as a profile picture.

 

Finally, here we close the camera.

private void closeCamera() {

try {

mCameraOpenCloseLock.acquire();

if (null != mCaptureSession) {

mCaptureSession.close();

mCaptureSession = null;

}

if (null != mCameraDevice) {

mCameraDevice.close();

mCameraDevice = null;

}

if (null != mImageReader) {

mImageReader.close();

mImageReader = null;

}

} catch (InterruptedException e) {

throw new RuntimeException(“Interrupted while trying to lock camera closing.”, e);

} finally {

mCameraOpenCloseLock.release();

}}