Friday, August 5, 2011

Uris and Intents and Cameras, Oh My! - Android Development

For the last couple of days, I've been hacking on the Android camera API functions. Specifically, I've been trying to invoke the camera with an Intent (new Intent(MediaStore.ACTION_IMAGE_CAPTURE);), rather than building out my own preview and capture function.

The main stumbling block has been how to pass file location to the Intent so that the Camera function saves images where I want them to go, rather than the default location (/mnt/sdcard/DCIM/Camera/ I believe). I've looked all over the internet for how to do this properly. After getting some expert advice, this is the best solution I found:

private static Uri getImageFileUri(){

     // Create a storage directory for the images
     // To be safe(er), you should check that the SDCard is mounted
     // using Environment.getExternalStorageState() before doing this
     
     File imagePath = new File(Environment.getExternalStoragePublicDirectory(
                                Environment.DIRECTORY_PICTURES), "CameraTest");
     if (! imagePath.exists()){
      if (! imagePath.mkdirs()){
       Log.d("CameraTestIntent", "failed to create directory");
       return null;
      }
     }
     
     // Create an image file name
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
     image = new File(image.getPath() + File.separator +
                        "IMG_"+ timeStamp + ".jpg");

     // Create an File Uri
     return Uri.fromFile(image);
    }

The key appears to be not to use ContentResolver (e.g.,
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);) to generate a Uri, because this means the Camera app will just save the image in the default location with a default name.

The above solution saves the image in a shared location so other applications (like Gallery) can access it. Files saved to this location also will not be deleted when your application is uninstalled. If you want your image files to be not easily visible to the user and removed when your app is uninstalled, call your application's Context object to create the image path:

     File imagePath = context.getExternalFilesDirectory(
                         Environment.DIRECTORY_PICTURES);

You don't need the "CameraTest" bit in this case, because the imagePath will be specific to your application: /mnt/sdcard/Android/data/<app_package>/Pictures/

No comments:

Post a Comment