Android mediastore action image capture

In this episode of the android camera2 api we respond to an android mediastore action image capture intent for applications that want image capture.

Get Code

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

https://github.com/mobapptuts/recyclerview_image_gallery.git Tag camera2-action-image-capture

or else run this command

git clone –branch camera2-action-image-capture https://github.com/mobapptuts/recyclerview_image_gallery.git

Code Samples

We change the applicationId to something more applicable to the camera2 api app

build.gradle

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

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

Change the label and add an intent filter for media action image capture

strings.xml

<resources>
    <string name="app_name">Camera API APP</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="nigelhenshaw.com.cameraintenttutorial" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera2.full" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".CamaraIntentActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.media.action.IMAGE_CAPTURE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name=".SingleImageActivity" />
    </application>

</manifest>

CamaraIntentActivity

Create two new activity members, one for the Uri sent from the requesting app and the other an activity for passing to the image saver’s thread.

private static Uri mRequestingAppUri;
    private Activity mActivity;

Pass the activity to the ImageSaver constructor call

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener =
          new ImageReader.OnImageAvailableListener() {
              @Override
              public void onImageAvailable(ImageReader reader) {
                  mBackgroundHandler.post(new ImageSaver(mActivity, reader.acquireNextImage()));
              }
          };

Inside the ImageSaver class add a local Activity member and initialise it. Then in the ImageSaver run method set the Uri member to null so the app will run in stand alone mode, set the activity result to OK & close the main activity.

private static class ImageSaver implements Runnable {

        private final Image mImage;
        private final Activity mActivity;

        private ImageSaver(Activity activity, Image image) {
            mActivity = activity;
            mImage = image;
        }

        @Override
        public void run() {
            ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[byteBuffer.remaining()];
            byteBuffer.get(bytes);

            FileOutputStream fileOutputStream = null;

            try {
                fileOutputStream = new FileOutputStream(mImageFile);
                fileOutputStream.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mImage.close();
                if(fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(mRequestingAppUri != null) {
                    mRequestingAppUri = null;
                    mActivity.setResult(RESULT_OK);
                    mActivity.finish();
                }
            }

        }
    }

Inside the onCreate method get the Uri from the intent & initialise the mActivity member

@Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_camara_intent);

       Intent intent = getIntent();
       String action = intent.getAction();
       if(MediaStore.ACTION_IMAGE_CAPTURE.equals(action)) {
           mRequestingAppUri = intent.getParcelableExtra(MediaStore.EXTRA_OUTPUT);
       }
       mActivity = this;

       createImageGallery();

       mRecyclerView = (RecyclerView) findViewById(R.id.galleryRecyclerView);
       GridLayoutManager layoutManager = new GridLayoutManager(this, 1);
       layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
       mRecyclerView.setLayoutManager(layoutManager);
       RecyclerView.Adapter imageAdapter = new ImageAdapter(sortFilesToLatest(mGalleryFolder), this);
       mRecyclerView.setAdapter(imageAdapter);

       final int maxMemorySize = (int) Runtime.getRuntime().maxMemory() / 1024;
       final int cacheSize = maxMemorySize / 10;

       mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

           @Override
           protected int sizeOf(String key, Bitmap value) {
               return value.getByteCount() / 1024;
           }
       };

       mTextureView = (TextureView) findViewById(R.id.textureView);
   }

In the takePhoto method check to see if an Uri has been sent and if so create a new file and assign it  to mImageFile

public void takePhoto(View view) {
  
        try {
            if(mRequestingAppUri != null) {
                mImageFile = new File(mRequestingAppUri.getPath());
            } else {
                mImageFile = createImageFile();
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
        lockFocus();
    }
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>