08 January 2010

Taking photos from the handset's camera via Intents

Taking a photo via the camera is actually a really easy task in Android if using Intents. I provide a little code snippet which illustrates its usage.

Fire up an intent to start the 'photo-taking' activity:
mTakePhoto = (ImageButton)findViewById(R.id.takePhoto);
mTakePhoto.setOnClickListener(new View.OnClickListener()
{
 @Override
 public void onClick(View v)
 {
  // fire off an intent for the camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  startActivityForResult(intent, REQUEST_CAMERA);
 }
});
This will launch the 'photo-taking' activity which lets you take a picture. To get (and handle) the result you will need a listener to respond when the image capture is finished:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{  
super.onActivityResult(requestCode, resultCode, data);

 // if Activity was canceled, display a Toast message for 1 second
if (resultCode == RESULT_CANCELED) {
  Toast toast = Toast.makeText(this,"Activity cancelled", 1000);
  toast.show();
  return;
 }

 // lets check if we are really dealing with a picture
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK)
 {
  String timestamp = Long.toString(System.currentTimeMillis());
  // get the picture
mPicture = (Bitmap) data.getExtras().get("data");

  // save image to gallery
  MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp);

  Uri uri=MediaStore.Images.Thumbnails.getContentUri("external");

  Cursor cursor=MediaStore.Images.Thumbnails.queryMiniThumbnails
  (getContentResolver(), uri, MediaStore.Images.Thumbnails.MICRO_KIND, null);

  Long _imageId = null;
  cursor.moveToFirst();
  while(true){
   for(int i=0;i<cursor.getColumnCount();i++){
    if(cursor.getColumnName(i).equals("image_id")) {
     _imageId = Long.parseLong(cursor.getString(i));
    }
   }
   if(cursor.isLast()){
    break;
   } else {
    cursor.moveToNext();
   }
  }
  // Get Bitmap and scale to default icon size
  Bitmap tmp = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(), _imageId, MediaStore.Images.Thumbnails.MICRO_KIND, null);
  tmp = Bitmap.createScaledBitmap(tmp, 48, 48, true);
  // Update ImageButton icon
  mTakePhoto.setImageBitmap(tmp);

  // save image to SD card
  try {
   File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/SOME_DIR/");
   if(!directory.exists()) directory.mkdir();
   FileOutputStream fos = new FileOutputStream(directory+"/"+timestamp+".jpg");
   Environment.getExternalStorageDirectory().mkdir();
   mPicture.compress(Bitmap.CompressFormat.JPEG, 90, fos);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
The listener responds when an photo was taken and lets you access the data. What I am doing with the data is this:
  • add it to the device's media gallery
  • create a bitmap thumbnail to update to button's icon with the just taken picture
  • additionally store the image on the sd-card on an arbitrary location
Obviously, this is quite a lot of code. If you just want to add the picture to the media gallery, code reduces to just 2 lines (after the checks) for the listener:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
 super.onActivityResult(requestCode, resultCode, data);

 // if Activity was canceled, display a Toast message for 1 second if (resultCode == RESULT_CANCELED) {
  Toast toast = Toast.makeText(this,"Activity cancelled", 1000);
  toast.show();
  return;
 }

 // lets check if we are really dealing with a picture if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK)
 {
  // get the picture
  mPicture = (Bitmap) data.getExtras().get("data");

  // save image to gallery
  MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp);
 }
}

3 comments:

  1. Thanks for this tutorial mate!

    ReplyDelete
  2. There's a lot more to come since the learning curve is at quite a pace. Just need to find time...

    ReplyDelete
  3. Thanks a lot! So wonderful~!

    ReplyDelete