Reputation: 4408
I am deleting an image file from my application. I was doing
new File(filename).delete ();
This was actually deleting the file. But the image was still visible in the gallery.
On search i found that we should use
getContentResolver().delete(Uri.fromFile(file), null,null);
to delete
But here i am getting the exception:
Unknown file URL. java.lang.IllegalArgumentException: Unknown URL file:///mnt/sdcard/DCIM/Camera/IMG_20120523_122612.jpg
When i see with any file browser, this particular image is present. Please help me to fix this issue. Is there any other way to update gallery when image is physically deleted
Upvotes: 35
Views: 70466
Reputation: 1
this all method deprecated for Android 11+, for Delete any media file in Android11+ you can send request for delete., for this i found one dependency for this just check i hope your issue is resolve using this method.
https://github.com/jcredking/Delete1
Upvotes: 0
Reputation: 2536
DocumentFile.fromSingleUri(context, uri).delete();
Working great for me
Upvotes: 0
Reputation: 36
public static boolean deltefolderwithimages(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++) {
boolean success = deltefolderwithimages(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
return dir.delete();
}
Upvotes: 0
Reputation: 825
I had the same issue, and I tried three different methods to delete an image. Sometimes it was working sometimes it wasn't. After too much time spent now every method that I have will delete the image.What I wanna say is: BE CAREFUL WITH PROCESSING BITMAP. I was taking a picture persist it and then rotate if needed:
public static Bitmap rotatePictureToPortraitMode(String filePath, Bitmap myBitmap) {
try {
ExifInterface exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); // rotating bitmap
} catch (Exception e) {
}
return myBitmap;
}
after that I tried to delete the image but as I said previously it wasn't working. Removing this method helped to me to solve the issue.
Maybe this was only my issue but as soon as I removed this it helped me a lot, so I wanna say careful how you are processing the image. For my case I used the answer that is previously mentioned :
File file = new File(photoUri);
file.delete();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(new File(photoUri))));
Hope it helps!
Upvotes: 1
Reputation: 3971
In Kotlin you can do this :
private fun deleteImage(path: String) {
val fDelete = File(path)
if (fDelete.exists()) {
if (fDelete.delete()) {
MediaScannerConnection.scanFile(this, arrayOf(Environment.getExternalStorageDirectory().toString()), null) { path, uri ->
Log.d("debug", "DONE")
}
}
}
}
Upvotes: 5
Reputation: 491
I tried all those solutions but had no luck in Android 6.
In the end, I found this snipped of code that worked fine.
public static void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
}
I also tested this in Android 4.4 and 5.1 and it works perfectly.
Upvotes: 5
Reputation: 18978
Use the code below, it may help you.
File fdelete = new File(file_dj_path);
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + file_dj_path);
} else {
System.out.println("file not Deleted :" + file_dj_path);
}
}
to refresh gallery after deleting image use below code for send Broadcast
(for < KITKAT API 14)
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
For >= KITKAT API 14 use below code
MediaScannerConnection.scanFile(this, new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* @see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Because:
ACTION_MEDIA_MOUNTED
is deprecated in KITKAT(API 14).
EDITED 04-09-2015
its working fine check below code
public void deleteImage() {
String file_dj_path = Environment.getExternalStorageDirectory() + "/ECP_Screenshots/abc.jpg";
File fdelete = new File(file_dj_path);
if (fdelete.exists()) {
if (fdelete.delete()) {
Log.e("-->", "file Deleted :" + file_dj_path);
callBroadCast();
} else {
Log.e("-->", "file not Deleted :" + file_dj_path);
}
}
}
public void callBroadCast() {
if (Build.VERSION.SDK_INT >= 14) {
Log.e("-->", " >= 14");
MediaScannerConnection.scanFile(this, new String[]{Environment.getExternalStorageDirectory().toString()}, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* @see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri) {
Log.e("ExternalStorage", "Scanned " + path + ":");
Log.e("ExternalStorage", "-> uri=" + uri);
}
});
} else {
Log.e("-->", " < 14");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
}
below is logs
09-04 14:27:11.085 8290-8290/com.example.sampleforwear E/-->﹕ file Deleted :/storage/emulated/0/ECP_Screenshots/abc.jpg
09-04 14:27:11.085 8290-8290/com.example.sampleforwear E/-->﹕ >= 14
09-04 14:27:11.152 8290-8290/com.example.sampleforwear E/﹕ appName=com.example.sampleforwear, acAppName=/system/bin/surfaceflinger
09-04 14:27:11.152 8290-8290/com.example.sampleforwear E/﹕ 0
09-04 14:27:15.249 8290-8302/com.example.sampleforwear E/ExternalStorage﹕ Scanned /storage/emulated/0:
09-04 14:27:15.249 8290-8302/com.example.sampleforwear E/ExternalStorage﹕ -> uri=content://media/external/file/2416
Upvotes: 38
Reputation: 659
To delete image,
ContentResolver contentResolver = getContentResolver();
contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.ImageColumns.DATA + "=?" , new String[]{ imagePath });
Upvotes: 19
Reputation: 4491
File file = new File(photoUri);
file.delete();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(photoUri))));
This code works for me and I think it better than remount whole SD card with Intent.ACTION_MEDIA_MOUNTED
Upvotes: 24
Reputation: 3133
I've seen a lot of answers suggesting the use of
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
This works but causes the Media Scanner to re-scan the media on the device. A more efficient approach would be to query/delete via the Media Store content provider:
// Set up the projection (we only need the ID)
String[] projection = { MediaStore.Images.Media._ID };
// Match on the file path
String selection = MediaStore.Images.Media.DATA + " = ?";
String[] selectionArgs = new String[] { file.getAbsolutePath() };
// Query for the ID of the media matching the file path
Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = getContentResolver();
Cursor c = contentResolver.query(queryUri, projection, selection, selectionArgs, null);
if (c.moveToFirst()) {
// We found the ID. Deleting the item via the content provider will also remove the file
long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
Uri deleteUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
contentResolver.delete(deleteUri, null, null);
} else {
// File not found in media store DB
}
c.close();
Upvotes: 35
Reputation: 41
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
This code works, but it is very resource expensive. It unmounts & then mounts the SDCard which may affect some applications or take huge system resources in order to refresh the gallery. I am still looking for a best alternative & will post if i get one.
Upvotes: 4