Прекратите сохранять фотографии с помощью родной камеры Android
Я использую собственную камеру Android и сохраняю файл в папке данных приложения (/mnt / sdcard / Android / data / com.компания.приложение / Файлы / картинки/). При этом пыльниковая копия фотографии сохраняется в папку 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 ответов:
Проверьте этот код..
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()); } } }
Вы можете использовать следующее : Сначала мы получаем последнее сохраненное изображение, проверяя, которое было последним измененным изображением. Затем проверьте, если последнее измененное время находится в последние несколько секунд. Возможно, Вам также придется проверить точное место, где камера хранит изображение.
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; } }
К сожалению, некоторые смартфоны сохраняют изображения в другой папке, такой как 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 .
Хорошее решение парта. Но это хорошо для Samsungs, которые хранят изображения в DCIM / Camera. Некоторые телефоны-Sony Ericssons, HTCs хранят их в папках, таких как 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; } }
Я сталкиваюсь с аналогичной проблемой с Moto Z Force (7.1.1). У меня есть
MediaStore.EXTRA_OUTPUT
, определенный на intent, но дубликат файла все еще создается в каталоге камеры.Мне нужно протестировать на других устройствах, но вот подход, который я принял в отношении этой проблемы. Вместо того, чтобы пытаться найти конкретный каталог камеры, я использую расположение
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(); } }