Android prevent saving photo on DCIM / public folder

5.6k views Asked by At

I´m developing an Android application. The user could take a photo after a button click. This photo will be saved to internal package storage (data/data/package/...) with the following method:

private String saveToInternalSorage(Bitmap bitmapImage){
    ContextWrapper cw = new ContextWrapper(getApplicationContext());
    File directory = cw.getDir("TEST", Context.MODE_PRIVATE);
    File pod = new File(directory, object.getTitle() + "" +
object.getName() + "" + object.getAge() + ".jpg");

    FileOutputStream fos = null;
    try {           

        fos = new FileOutputStream(pod);
        bitmapImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return pod.getAbsolutePath();
} 

Also it´s possible to delete the picture from this directory. This works like a charm. Tested on Emulator and rooted phone. But the photos were also saved to the public folder DCIM. I´m testing with HTC ONE mini (withtout SD CARD?). Below is the code which shows the methods to take and get the photos.

public void takePhoto() {

    cameraintent = new Intent("android.media.action.IMAGE_CAPTURE");
    startActivityForResult(cameraintent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {

             Bundle extras = data.getExtras();
             Bitmap bmp  = (Bitmap) extras.get("data");

             setPath(saveToInternalSorage(bmp));

I would like to prevent the storage of the photos in a public folder. My approach to delete the latest files in the DCIM folder failed because getExternalStorageDirectory() gives me a emulated path (like emulated/sdcard/...) on HTC One mini. And that´s definitly not the correct path. So how could i be sure that photos will be only stored to the internal package structure and not (without SD card/ with SD card) in a public folder. And when i have to delete photos in the public folder how to do i get the right path (for/on different devices)?

I found no solution to prevent the storage in a public folder "from the beginning".

Thanks in advance!

EDIT

The method below should be able to delete the photo from the DCIM/ public folder.

private void deleteLatestFromDCIM() {

    File f = new File(Environment.getExternalStorageDirectory() + "");

    File [] files = f.listFiles();

    Arrays.sort( files, new Comparator<Object>()
            {
        public int compare(Object o1, Object o2) {

            if (((File)o1).lastModified() > ((File)o2).lastModified()) {
                   return -1;
            } else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
                   return 1;
            } else {
                   return 0;
            }
            ...
    if(files[0].exists())
    files[0].delete();

The problem is that photos in DCIM/public folder get generic names. See image below:

Photos in DCIM

So, how to delete images whose names i don´t "know"? Storing of photos in internal memory works fine! I don´t wont them in a public folder. And with the getExternalStorageDirectory() method i get an emulated path as described above. Is this really the path to the DCIM/public folder?

2

There are 2 answers

1
Jörg Eisfeld On

Do I understand correctly that you want to take a photo with the camera and store it in the internal memory? Then I have two proposals:

  1. Did you try the way described in http://developer.android.com/training/camera/photobasics.html filling MediaStore.EXTRA_OUTPUT with an Uri to the internal storage?

  2. If this does not help to save the image directly in the internal storage, why don't you just delete it from the emulated path returned by getExternalStorageDirectory()? As far as I know, the file access via this path works perfectly, even though it's probably only a link.

0
DehMotth On

Sorry for answering my own question, hope this will be helpfully for other developers: My strategy: Capture the photo as described in the question, save it into the internal memory (data/data/com.package...) After that delete it from the public folder (DCIM/MEDIA/100MEDIA) with the following method (delete last taken picture from that folder...):

  private void deleteLastPhotoTaken() {
    String[] projection = new String[] {
            MediaStore.Images.ImageColumns._ID,
            MediaStore.Images.ImageColumns.DATA,
            MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
            MediaStore.Images.ImageColumns.DATE_TAKEN,
            MediaStore.Images.ImageColumns.MIME_TYPE };

    final Cursor cursor = getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
            null,null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");

    if (cursor != null) {
      cursor.moveToFirst();

      int column_index_data =
              cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

      String image_path = cursor.getString(column_index_data);

      File file = new File(image_path);
      if (file.exists()) {
        file.delete();
      }
    }
  }

As mentioned in other solutions: Don´t close the cursor! Android will do that for you.