camera2 api to android marshmallow

Tutorial that describes how to upgrade the android camera2 api to android marshmallow. For this android tutorial we need camera & write storage permissions.

The android camera2 api application requires in theory three permissions to function, read external storage access for the recyclerview gallery, camera permission to access the camera2 services and write external storage permission for saving the captured images to external storage.

But because with write external external storage already providing by default the read external storage permission, we will just be setting up two android marshmallow runtime permissions for this tutorial, camera & write external storage.

This tutorial will describe the steps required to provide the write external storage & camera services using the new android marshmallow runtime permissions.

Get Code

The code is now on github you can get it from here

https://github.com/mobapptuts/recyclerview_image_gallery.git Tag camera2-marshmallow

or else run this command

git clone –branch camera2-marshmallow https://github.com/mobapptuts/recyclerview_image_gallery.git

Code Samples

Change SDK version & add appcompat v7 library support

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.nigelhenshaw.camera2apiapp"
        minSdkVersion 21
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:recyclerview-v7:21.0.+'
    compile 'com.android.support:appcompat-v7:23.1.1'
}

Add activity members for the camera & write external storage request results

private static final int REQUEST_WRITE_STORAGE_RESULT = 1;
    private static final int REQUEST_CAMERA_RESULT = 2;

Inside the activity’s onCreate method add the runtime request for write external storage

The write external storage permission will support both the reading of images for the recyclerview gallery & the saving captured images to external storage

 mRecyclerView.setLayoutManager(layoutManager);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
                    PackageManager.PERMISSION_GRANTED) {
                RecyclerView.Adapter imageAdapter = new ImageAdapter(sortFilesToLatest(mGalleryFolder), this);
                mRecyclerView.setAdapter(imageAdapter);
            } else {
                if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    Toast.makeText(this,
                            "We need write storage permission to start the gallery and save images",
                            Toast.LENGTH_SHORT).show();
                }
                requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_WRITE_STORAGE_RESULT);
            }
        } else {
            RecyclerView.Adapter imageAdapter = new ImageAdapter(sortFilesToLatest(mGalleryFolder), this);
            mRecyclerView.setAdapter(imageAdapter);
        }

Inside the openCamera method add the runtime permission request for camera

 private void openCamera() {
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
                        PackageManager.PERMISSION_GRANTED) {
                    cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
                } else {
                    if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
                        Toast.makeText(this,
                                "No permission to use the camera services", Toast.LENGTH_SHORT).show();
                    }
                    requestPermissions(new String[] {Manifest.permission.CAMERA},
                            REQUEST_CAMERA_RESULT);
                }
            } else {
                cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
            }

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

Implement the request permission results callback

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch(requestCode) {
            case REQUEST_CAMERA_RESULT:
                if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this,
                            "Cannot run application because camera service permissions have not been granted",
                            Toast.LENGTH_SHORT).show();
                }
                break;
            case REQUEST_WRITE_STORAGE_RESULT:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    RecyclerView.Adapter imageAdapter = new ImageAdapter(sortFilesToLatest(mGalleryFolder), this);
                    mRecyclerView.setAdapter(imageAdapter);
                } else {
                    Toast.makeText(this,
                            "Don't have permission to start the gallery or save images",
                            Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

Add the lock focus support

private CameraCaptureSession.CaptureCallback mSessionCaptureCallback
            = new CameraCaptureSession.CaptureCallback() {

        private void process(CaptureResult result) {
            switch(mState) {
                case STATE_PREVIEW:
                    // Do nothing
                    break;
                case STATE__WAIT_LOCK:
                    Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                    if(afState == CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED ||
                            afState == CaptureRequest.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
                        /*
                        unLockFocus();
                        Toast.makeText(getApplicationContext(), "Focus Lock Successful", Toast.LENGTH_SHORT).show();
                        */
                        mState = STATE__PICTURE_CAPTURED;
                        captureStillImage();
                    }
                    break;
            }
        }
About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>