[Tutorial] How to use camera with Android and Android Studio

Welcome!

It’s a really short and simple tutorial, I’m just going to show you how to use camera with Android Studio.

I’m creating this tutorial because it’ll be a requirement for some new posts about image processing with Android.

I - About Android Tutorials

I’ll be creating a big number of Android tutorials, showing you how to use nice libraries, UI, tips, and more.

I’ll be using Android Studio and Gradle in all tutorials.

If you need some help with any Android lib or feature, feel free to comment here and if possible, I can write a new tutorial about it :)

Source Codes:

Get updates Follow @aron-bordin
Star it: Star
Contribute: Fork
Download: Download

II - Creating a new project

Open your Android Studio and create a new blank activity application.

The first step is to add the android permissions and required features.

Add these lines to your AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

Inside your style.xml, just edit the line to remove the ActionBar, if you prefer(this is removed just to have a full-screen camera):

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

Create this basic activity_main.xml:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/camera_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imgClose"
        android:layout_gravity="right|top"
        android:background="@android:drawable/ic_menu_close_clear_cancel"
        android:padding="20dp"/>

</FrameLayout>

Here we have a simple FrameLayout.

The camera_view will display the camera data, that we’ll use later with OpenGL and some algorithms to process it.

And the ImageButton will be used to close the application.

III - Camera code

The first step is to create a SurfaceView. It’ll receive camera data and display it inside the FrameLayout.

Create a new file, CameraView.java in the same folder that your MainActivity.java is.

First, just extend the SurfaceView and implements the SurfaceHolder.Callback.

You’ll have something like this code:

public class CameraView extends SurfaceView implements SurfaceHolder.Callback{

    public CameraView(Context context, Camera camera){
        super(context);
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {

    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

    }
}

Add these two private variables:

private SurfaceHolder mHolder;
private Camera mCamera;

And then just update your CameraView constructor with:

    public CameraView(Context context, Camera camera){
        super(context);

        mCamera = camera;
        mCamera.setDisplayOrientation(90);
        //get the holder and set this class as the callback, so we can get camera data here
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
    }

Now, override these methods, I commented everything to help you:

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        try{
            //when the surface is created, we can set the camera to draw images in this surfaceholder
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
        //before changing the application orientation, you need to stop the preview, rotate and then start it again
        if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
            return;

        try{
            mCamera.stopPreview();
        } catch (Exception e){
            //this will happen when you are trying the camera if it's not running
        }

        //now, recreate the camera preview
        try{
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        //our app has only one screen, so we'll destroy the camera in the surface
        //if you are unsing with more screens, please move this code your activity
        mCamera.stopPreview();
        mCamera.release();
    }

III - Camera Activity

Now, inside you MainActivity.java, add these variables:

private Camera mCamera = null;
private CameraView mCameraView = null;

No, override the method bellow, I commented to help you to understand it:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try{
            mCamera = Camera.open();//you can use open(int) to use different cameras
        } catch (Exception e){
            Log.d("ERROR", "Failed to get camera: " + e.getMessage());
        }

        if(mCamera != null) {
            mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
            FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
            camera_view.addView(mCameraView);//add the SurfaceView to the layout
        }

        //btn to close the application
        ImageButton imgClose = (ImageButton)findViewById(R.id.imgClose);
        imgClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.exit(0);
            }
        });
    }

Now, you can run your app and you’ll see something like this:

That’s it. This post is really basic, but I’m going to write more on how to use QR, OpenGL and some image processing algorithm, and I prefer to have the necessary background here.

Aron Bordin

Aron Bordin

Aron Bordin
Computer Science Student and AI researcher. Always coding something fun :)

[Tutorial] Developing Android Background Services

### Welcome!In this post, I'll show you how to develop background services on Android Studio. We'll see two type of services: `Service` a...… Continue reading