Tiago Scolari

bits for fun

Android: Camera and Image Gallery

2011-10-10

Here is some simple steps to access the phone camera and image gallery. This will be a very simple app. There is only one view, it will hold 2 buttons for selecting the image (one from camera and another from the gallery) and a ImageView that will show the selected image. I’ll not talk about the layout here, what I did is ugly and looks like this:

First of all, the app needs permission to do this:

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

On the activity, define 2 constants to hold the requestCode (values of your choice, must be unique request codes within this activty):

private static final int IMAGE_PICK     = 1;
private static final int IMAGE_CAPTURE  = 2;

I created 2 OnClickListener classes and bound each one to a button:

/**
 * Click Listener for selecting image from phone gallery
 */
class ImagePickListener implements OnClickListener {
  @Override
  public void onClick(View v) {
    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("image/*");
    startActivityForResult(Intent.createChooser(intent, "Escolha uma Foto"), IMAGE_PICK);
  }
}

/**
 * Click listener for taking a new picture
 */
class TakePictureListener implements OnClickListener {
  @Override
  public void onClick(View v) {
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, IMAGE_CAPTURE);
  }
}

To bind these Listeners, select each button and use the setOnClicsetOnClickListener. The request code, that we sent to startActivityForResult, will be fetch on the onActivityResult method:

/**
 * Receive the result from the startActivity
 */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

  if (resultCode == Activity.RESULT_OK) {
    switch (requestCode) {
      case IMAGE_PICK:
        this.imageFromGallery(resultCode, data);
        break;
      case IMAGE_CAPTURE:
        this.imageFromCamera(resultCode, data);
        break;
      default:
        break;
    }
  }
}

And, finally, fetch each data and set it as the ImageView image of the view:

/**
 * Image result from camera
 * @param resultCode
 * @param data
 */
private void imageFromCamera(int resultCode, Intent data) {
  this.imageView.setImageBitmap((Bitmap) data.getExtras().get("data"));
}

/**
 * Image result from gallery
 * @param resultCode
 * @param data
 */
private void imageFromGallery(int resultCode, Intent data) {
  Uri selectedImage = data.getData();
  String [] filePathColumn = {MediaStore.Images.Media.DATA};

  Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
  cursor.moveToFirst();

  int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
  String filePath = cursor.getString(columnIndex);
  cursor.close();

  this.imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
}

I created this app for testing image processing, there is a github repo with my tests. I created a tag (blog-post) to date this post, where things were working, at least =p