19

I insert an image via:

    ContentValues values = new ContentValues();   
    values.put(Images.Media.TITLE, filename);
    values.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 
    values.put(Images.Media.MIME_TYPE, "image/jpeg");

    Uri uri = this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);

But when I try to delete

    File f = new File(imageURI);
    f.delete();

The picture is no longer there but an empty placeholder is. Any ideas?

Paul
  • 1,634
  • 7
  • 21
  • 45

9 Answers9

17

Android has a cache of sorts that keeps track of media files.

Try this:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));

It makes the MediaScanner service run again, which should remove the deleted image from the device's cache.

Looks like you also need to add this permission to your AndroidManifest.xml:

<intent-filter>
  <action android:name="android.intent.action.MEDIA_MOUNTED" />
  <data android:scheme="file" /> 
</intent-filter>
Marc Bernstein
  • 11,153
  • 5
  • 32
  • 32
  • @aloneguid, care to explain why? – Marc Bernstein Sep 19 '11 at 20:12
  • Intent.ACTION_MEDIA_MOUNTED rescans all media collection, there is a strong reason why Android OS does it only once when SD card mounted. – Ivan G. Sep 19 '11 at 20:29
  • 4
    There doesn't seem to be an equivalent of MediaScannerConnection.scanFile() for deleting files. Please let me know if you've found a different way of doing this, otherwise I stand by my answer as the correct one. – Marc Bernstein Sep 19 '11 at 23:33
  • Very helpful. I have an application that I am using on an Android 4.1 device, and this was the ONLY way the OS fully recognizes that a file has actually been deleted – TwinPrimesAreEz Aug 21 '14 at 19:59
11

As stated in the comments, the accepted answer uses a lot of memory. While MediaScannerConnection doesn't have a "deleteFile" method, just pass in the the old file path to the "scanFile" method once you've deleted the file. The media scanner will rescan and remove the media.

tested on N5. Android 4.4.

EDIT: Other have stated this doesn't work on 4.2

new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            String filePath = recording.file.getAbsolutePath();
            recording.file.delete();
            MediaScannerConnection.scanFile(context,
                    new String[]{filePath}, null, null);
            return null;
        }
    }.execute();
whizzle
  • 1,913
  • 15
  • 20
6

You can also delete the image from the Gallery by using:

getContentResolver().delete(imageUri, null, null);

Just make sure that 'imageUri' is the uri returned to you when you called insert.

manisha
  • 4,414
  • 2
  • 15
  • 10
  • 1
    I keep getting "Unknown URL" errors. Are you passing the full path with the phone root or just the top level path? I've tried both and keep getting the unknown url error. I am not able to maintain a database of the insert URI of when I added the file to the gallery. Can I remove the item from the gallery by just using a file path that I know is valid? I am able to add items to the gallery using the media scanner but I can not remove an item after the file is deleted. – nomaam Jan 13 '14 at 05:08
  • does this method delete the real image from galley or it just hide the image with this path from gallery? – hadi Apr 24 '15 at 00:04
  • @hadi this will delete the item from the mediaDB. Since this is implemented via SQLite with a cascade-file-delete-trigger the file is also deleted. – k3b Jun 16 '16 at 07:52
4

If you donot know the image-id as required in the answer of @manisha and @Muhammad Waqas Khan you can also delete by file name

    String fullPathToFile = "/storage/sdcard0/DICM/test.jpg";
    getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        MediaStore.Images.Media.DATA + "=?", new String[]{ fullPathToFile } );

[Update 2016-06-16]

Danger: this looks like "Only delete the item from the mediaDB". Since there is a SQLite-cascade-file-delete-trigger in the mediaDB the referenced file is also deleted if it exist.

To avoid this you have to change the column MediaStore.Images.Media.DATA to a non-existing filepath before calling delete.

k3b
  • 13,724
  • 6
  • 47
  • 81
2

taken from: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.html

This worked for me ( tested on HTC Desire, Android 2.3)

// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
brad426
  • 74
  • 5
1

Use this method getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );

1

Add this line after File.delete();:

MediaScannerConnection.ScanFile(this,new string[]{fileUrl.ToString()}, null, null);
MJH
  • 2,231
  • 7
  • 15
  • 20
1

Add this right after deleting a file:

MediaScannerConnection.scanFile(context, arrayOf(imageURI.getPath()), null, null)

:)

1
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  MediaScannerConnection.scanFile(context,new String[]{selectedVideoDelete}, null, null);
} else {
  context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
kyun
  • 7,487
  • 4
  • 21
  • 44