Хватит сохранять фотографии с помощью родной камеры Android - PullRequest
13 голосов
/ 10 ноября 2011

Я использую встроенную камеру Android и сохраняю файл в папке с данными своего приложения (/mnt/sdcard/Android/data/com.company.app/files/Pictures/). При этом другая копия фотографии сохраняется в папке DCIM.

Это мой код:

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);

Как предотвратить сохранение дополнительной копии изображения в папку DCIM?

Большое спасибо

Ответы [ 5 ]

7 голосов
/ 02 марта 2012

Вы можете использовать следующее: Сначала мы получаем последнее сохраненное изображение, проверяя, какое изображение было последним измененным. Затем проверьте, было ли время последнего изменения в последние несколько секунд. Возможно, вам также придется проверить точное местоположение, где камера хранит изображение.

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;
        }

    }
6 голосов
/ 08 апреля 2013

К сожалению, некоторые смартфоны сохраняют изображения в другой папке, например DCIM / 100MEDIA.Поэтому не могу полагаться на эти решения.Я предпочитаю использовать этот способ:

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
}

Я попытался выяснить, существует ли вторая копия, и удалить ее.Я использовал приведенный выше код, чтобы найти последний сделанный снимок.

Примечание: не используйте cursor.close(); после использования managedQuery , оставьте курсор для управления системой Android и неназывать это.Вы можете увидеть managedQuery ()

Замечание2: метод managedQuery устарел, и его следует избегать, вместо этого внедрите CursorLoaders .

4 голосов
/ 10 ноября 2011

проверьте этот код ..

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());
} 

и здесь метод делает всю магию

 /** 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());   
        }         
    }       

}
3 голосов
/ 26 марта 2013

Хорошее решение от Parth. Но это хорошо для Samsungs, которые хранят изображения в DCIM / Camera. Некоторые телефоны - Sony Ericssons, HTC хранят их в таких папках, как DCIM / 100MEDIA, DCIM / 100ANDRO, поэтому я немного изменил код:

 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;
    }

}
0 голосов
/ 08 августа 2018

У меня похожая проблема с Moto Z Force (7.1.1).У меня есть MediaStore.EXTRA_OUTPUT, определенный в намерении, но дубликат файла все еще создается в каталоге камеры.

Мне нужно проверить на других устройствах, но вот подход, который я выбрал в отношении этой проблемы.Вместо того, чтобы пытаться найти конкретный каталог камеры, я использую местоположение MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME.

Вот мой фрагмент кода:

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();
    }
}
...