2016年10月8日 星期六

How to use camera with Android and Android Studio

Ref : http://blog.rhesoft.com/2015/04/02/tutorial-how-to-use-camera-with-android-and-android-studio/


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:










沒有留言:

張貼留言