Pergunta

I am using native Android camera and save file to my application data folder (/mnt/sdcard/Android/data/com.company.app/files/Pictures/). At the same time anther copy of photo is saved to DCIM folder.

This is my code:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String formattedImageName = getDateString() + ".jpg";
File image_file = new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), formattedImageName);
Uri imageUri = Uri.fromFile(image_file);
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent, REQUEST_FROM_CAMERA);

How can I prevent saving additional copy of image to DCIM folder?

Many Thanks

Foi útil?

Solução

check this code..

private void FillPhotoList() {  
    // initialize the list!    
    GalleryList.clear();    
    String[] projection = { MediaStore.Images.ImageColumns.DISPLAY_NAME }; 
    for(int i=0;i<projection.length;i++)
        Log.i("InfoLog","projection "+projection[0].toString());
    // intialize the Uri and the Cursor, and the current expected size.    
    Cursor c = null;     
    Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
    Log.i("InfoLog","FillPhoto Uri u "+u.toString());
    // Query the Uri to get the data path.  Only if the Uri is valid.    
    if (u != null)    
    {       
        c = managedQuery(u, projection, null, null, null);    
    }     
    // If we found the cursor and found a record in it (we also have the id).    
    if ((c != null) && (c.moveToFirst()))     
    {       
        do        
        {         
            // Loop each and add to the list.         
            GalleryList.add(c.getString(0)); // adding all the images sotred in the mobile phone(Internal and SD card)

        }            
        while (c.moveToNext());    
    } 
    Log.i(INFOLOG,"gallery size "+ GalleryList.size());
} 

and this is where the method is doing all magic

 /** Method will check all the photo is the gallery and delete last captured and move it to the required folder.
 */
public void movingCapturedImageFromDCIMtoMerchandising()
{

    // This is ##### ridiculous.  Some versions of Android save         
    // to the MediaStore as well.  Not sure why!  We don't know what        
    // name Android will give either, so we get to search for this         
    // manually and remove it.           
    String[] projection = { MediaStore.Images.ImageColumns.SIZE, 
            MediaStore.Images.ImageColumns.DISPLAY_NAME, 
            MediaStore.Images.ImageColumns.DATA, 
            BaseColumns._ID,}; 
    // intialize the Uri and the Cursor, and the current expected size.  

    for(int i=0;i<projection.length;i++)
        Log.i("InfoLog","on activityresult projection "+projection[i]);
    //+" "+projection[1]+" "+projection[2]+" "+projection[3] this will be needed if u remove the for loop
    Cursor c = null;          
    Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;       
    Log.i("InfoLog","on activityresult Uri u "+u.toString());

    if (CurrentFile != null)      
    {                          
        // Query the Uri to get the data path.  Only if the Uri is valid,     
        // and we had a valid size to be searching for.     
        if ((u != null) && (CurrentFile.length() > 0))        
        {              
            //****u is the place from data will come and projection is the specified data what we want
            c = managedQuery(u, projection, null, null, null);      
        }           
        // If we found the cursor and found a record in it (we also have the size). 
        if ((c != null) && (c.moveToFirst()))     
        {             
            do              
            {                
                // Check each area in the gallery we built before.     
                boolean bFound = false;               
                for (String sGallery : GalleryList)                  
                {                      
                    if (sGallery.equalsIgnoreCase(c.getString(1)))  
                    {                      
                        bFound = true;
                        Log.i("InfoLog","c.getString(1) "+c.getString(1));
                        break;                    
                    }                   
                }                   
                // To here we looped the full gallery.                   
                if (!bFound)     //the file which is newly created and it has to be deleted from the gallery              
                {                     
                    // This is the NEW image.  If the size is bigger, copy it.          
                    // Then delete it!                    
                    File f = new File(c.getString(2));




                    // Ensure it's there, check size, and delete!            
                    if ((f.exists()) && (CurrentFile.length() < c.getLong(0)) && (CurrentFile.delete()))     
                    {                       
                        // Finally we can stop the copy.       
                        try                      
                        {                         
                            CurrentFile.createNewFile();     
                            FileChannel source = null;   
                            FileChannel destination = null; 
                            try                           
                            {                         
                                source = new FileInputStream(f).getChannel();
                                destination = new FileOutputStream(CurrentFile).getChannel();  
                                destination.transferFrom(source, 0, source.size());
                            } 
                            finally                    
                            {
                                if (source != null)        
                                {   
                                    source.close();  
                                }       
                                if (destination != null)   
                                {   
                                    destination.close(); 
                                }                            
                            }                     
                        }                         
                        catch (IOException e)                 
                        {                            
                            // Could not copy the file over.      
                            ToastMaker.makeToast(this, "Error Occured", 0);   
                        }                      
                    }                   
                    //****deleting the file which is in the gallery                           
                    Log.i(INFOLOG,"imagePreORNext1 "+imagePreORNext);
                    Handler handler = new Handler();
                    //handler.postDelayed(runnable,300);
                    Log.i(INFOLOG,"imagePreORNext2 "+imagePreORNext);
                    ContentResolver cr = getContentResolver();       
                    cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, BaseColumns._ID + "=" + c.getString(3), null);

                    break;                                          
                }              
            }            
            while (c.moveToNext());   
        }         
    }       

}

Outras dicas

You can use the following : First we get the last saved image by checking which was the last modified image. Then check if last modified time is in the last few seconds. You may also have to check the exact location of where camera stores the image.

private boolean deleteLastFromDCIM() {

        boolean success = false;
        try {
            File[] images = new File(Environment.getExternalStorageDirectory()
                    + File.separator + "DCIM/Camera").listFiles();
            File latestSavedImage = images[0];
            for (int i = 1; i < images.length; ++i) {
                if (images[i].lastModified() > latestSavedImage.lastModified()) {
                    latestSavedImage = images[i];
                }
            }

                    // OR JUST Use  success = latestSavedImage.delete();
            success = new File(Environment.getExternalStorageDirectory()
                    + File.separator + "DCIM/Camera/"
                    + latestSavedImage.getAbsoluteFile()).delete();
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            return success;
        }

    }

Unfortunately, some smart phones save images in another folder such as DCIM/100MEDIA. So can't rely to these solution. I prefer use this way:

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 = managedQuery(
     MediaStore.Images.Media.EXTERNAL_CONTENT_URI,projection, null, null,
     MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC"); 

if(cursor != null){
     cursor.moveToFirst();
     // you will find the last taken picture here and can delete that
}

I tried to find out if a second copy exists and delete the copy. I used the above code to find the last taken picture.

Notice: Don't use cursor.close(); after using managedQuery, Leave the cursor for the Android system to manage and don't call that. You can see managedQuery()

Notice2: The managedQuery method is deprecated and it should be avoided, implement CursorLoaders instead.

A nice solution by Parth. But it's good for Samsungs that keep images in DCIM/Camera. Some phones - Sony Ericssons, HTCs keep them in folders like DCIM/100MEDIA, DCIM/100ANDRO so I have slightly modified the code:

 private boolean deleteLastFromDCIM() {
    boolean success = false;
    try {           
        //Samsungs:
        File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "DCIM/Camera");
        if(!folder.exists()){ //other phones:
            File[] subfolders = new File(Environment.getExternalStorageDirectory() + File.separator + "DCIM").listFiles();
            for(File subfolder : subfolders){
                if(subfolder.getAbsolutePath().contains("100")){  
                    folder = subfolder;
                    break;
                }
            }
            if(!folder.exists())
                return false;
        }

        File[] images = folder.listFiles();
        File latestSavedImage = images[0];
        for (int i = 1; i < images.length; ++i) {
            if (images[i].lastModified() > latestSavedImage.lastModified()) {
                latestSavedImage = images[i];
            }
        }            
        success = latestSavedImage.delete();
        return success;
    } catch (Exception e) {
        e.printStackTrace();
        return success;
    }

}

I am encountering a similar problem with the Moto Z Force (7.1.1). I have the MediaStore.EXTRA_OUTPUT defined on the intent, but a duplicate file is still created in the camera directory.

I need to test on other devices, but here's an approach I took regarding this issue. Rather than trying to find the specific camera directory, I'm using the MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME location.

Here's my code snippet:

private void removeCameraDuplicate() {
    String[] proj = {
        MediaStore.Images.ImageColumns.DATA,
        MediaStore.Images.ImageColumns._ID };

    String selection = MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME + " = ? ";
    String[] selectionArgs = new String[] { "Camera" };

    Cursor cursor = mActivity.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, selection, selectionArgs, MediaStore.Images.ImageColumns.DATE_TAKEN + " desc");

    if (cursor != null) {
        int idxPath = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);

        if (cursor.getCount() > 0 && idxPath > -1 && cursor.moveToFirst()) {
            File original = new File(mMediaPath);
            File cameraDupe = new File(cursor.getString(idxPath));
            if (original.exists() && cameraDupe.exists()) {
                LogUtils.LOGE("***> camera", "original " + original.length());
                LogUtils.LOGE("***> camera", "original " + original.lastModified());

                LogUtils.LOGE("***> camera", "duplicate " + cameraDupe.length());
                LogUtils.LOGE("***> camera", "duplicate " + cameraDupe.lastModified());

                if (original.length() == cameraDupe.length() && original.lastModified() == cameraDupe.lastModified()) {
                    if (cameraDupe.delete()) {
                        LogUtils.LOGE("***> camera", "duplicate deleted");
                    }
                }
            }
        }
        cursor.close();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top