I am trying to give users an option to set image as wallpaper/whatsapp dp like this.
But I'm stuck with this code
Uri sendUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.a_day_without_thinking_mobile);
Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
intent.setDataAndType(sendUri, "image/jpg");
intent.putExtra("mimeType", "image/jpg");
startActivity(Intent.createChooser(intent,"Set As"));
It shows a dialog that no apps can perform this action.
I also tried to check my Uri through this method
ContentResolver cr = getContentResolver();
String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cur = cr.query(sendUri, projection, null, null, null);
if (cur != null) {
if (cur.moveToFirst()) {
String filePath = cur.getString(0);
if (new File(filePath).exists()) {
Log.d("URI: ","File path exist");
} else {
Log.d("URI: ","File not found");
}
} else {
Log.d("URI: ","URI ok but no enty found");
}
cur.close();
} else {
Log.d("URI: ","URI was invalid for some other reason");
}
And It always returned that the URI was invalid. But I'm sure that the image is valid jpg and is present in raw folder.
I tried changing URI paths but to no success.
Android file read format has been changed after targetSdkVersion >= 24
You can find the details here;
https://stackoverflow.com/a/38858040/1367450
Related
when I get file path of file in Android 11 .
protected File getOutputMediaFile() {
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, timeStamp + ".jpg");
fileUri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Log.e("File Uri Path", "Uri inserted into media store = " + fileUri);
Toast.makeText(getActivity(), "File uri = "+fileUri, Toast.LENGTH_LONG).show();
String path = getImageRealPathFromURI(fileUri);
File file = new File(path);
return file;
}
private String getImageRealPathFromURI(Uri contentUri) {
String realPath = "";
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
realPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
} else {
Log.e("Image Real Path", "Cursor count appearing to be zero");
Toast.makeText(getActivity(), "Cursor count appearing to be zero", Toast.LENGTH_LONG).show();
realPath = "";
}
} catch (Exception e) {
Log.e("Image Real Path", "Exception fetching getImageRealPathFromURI() due to " + e.toString());
Toast.makeText(getActivity(),"Exception fetching getImageRealPathFromURI() due to "+e.toString(), Toast.LENGTH_LONG).show();
realPath = "";
} finally {
cursor.close();
}
return realPath;
}
I meet error : /storage/emulated/0/Pictures/1614237849822.jpg: open failed: EEXIST (File exists).
at libcore.io.IoBridge.open(IoBridge.java:492).
When I getOutputMediaFile().getpath.
Anyone help me?
add this line in manifest file :
android:requestLegacyExternalStorage="true"
and make sure that you add Read external storage permission and also allow this permission
The getContentResolver().insert() will give you a nice fresh uri to write the content of a file to.
It gives an uri you can use. It does not create a file for you.
Even if you get the path of the yet non existing file with the .DATA column, that file does not exist yet.
You can simply check that with File.exists().
Only if you open an OutputStream for the obtained uri and write to it the file will be created.
Use the uri! For what do you need that data path?
You can use this type to set mMediaRecoder's path:
final ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().
openFileDescriptor(Uri.parse(mVideoProfile.path), "rw");
mMediaRecorder.setOutputFile(parcelFileDescriptor.getFileDescriptor());
mVideoProfile.path = "content://media/external/video/media/751";
I have two type of Uris.
type one :
content://media/external/images/media/465
content://media/external/images/media/466
type two :
file:///storage/emulated/0/DCIM/Camera/20151112_185009.jpg
file:///storage/emulated/0/testFolder/20151112_185010.jpg
What is difference and how to convert file uri to content uri?
Because, file uri is just causing error. When I call method :
ContentResolver contentResolver = getContentResolver();
fis = (FileInputStream) contentResolver.openInputStream(fileTypeUri);
how do I fix this?
Try It :)
public static Uri getImageContentUri(Context context, File file) {
String filePath = file.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (file.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
If you're trying to share data that is stored as part of your app with another app you'll need to use a content:// scheme and not a file:// scheme. This can be accomplished using the FileProvider class found here: https://developer.android.com/reference/android/support/v4/content/FileProvider.html.
By using the FileProvider class you can more precisely and more securely define what files your app can share.
Though be aware that external-cache-path and external-files-path don't work despite what the documentation says. See: how to set FileProvider for file in External Cache dir for more info.
Question: how to make the media store to refresh its entry of a DELETED file?
After deleting a photo in code from the external storage, I still see a slot for the deleted photo in the gallery - blank photo.
It seems that the gallery reflects the media store and the deleted photo is found in the media store until the phone is restarted or generally - until the media is rescanned.
Trying to scan the deleted file did not help scanning deleted files (works just for new or existing files): MediaScannerConnection.scanFile(Application.get(), new String[]{file.getPath()}, null, null) (I tried scanning the parent folder as well).
Also tried ACTION_MEDIA_SCANNER_SCAN_FILE to no avail. Example: Application.get().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)))
Sending a broadcast receiver to rescan the entire external storage (thus refreshing the media store)did the trick: Application.get().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(Environment.getExternalStorageDirectory())))
BUT, it seems that Android, as of 4.4, throws a security exception when trying to manually send the ACTION_MEDIA_MOUNTED system broadcast. See #CommonsWare's post: http://commonsware.com/blog/2013/11/06/android-4p4-permission-regressions.html
So, I'm stuck with no solution for refreshing the media store upon file(/photo/video/etc.) deletion.
I found the following that works for me in 4.4 on a Nexus 10.
// request scan
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, SELECT_PICTURE);
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanIntent.setData(Uri.fromFile(refreshFile));
sendBroadcast(scanIntent);
"refreshFile" is the file I deleted that I get from my String "fPath" and then convert it to a file.
String filePath = fPath;
File refreshFile = new File(filePath);
I had the same issue. I wrote the following code and it worked on all versions from lollipop to oreo. I also called the mediastore.scanfile() method to ensure that MediaStore is updated. Adding the code below - you might not want to use the "delete()" method in future as the scanfile() might be comprehensive. But, if you want to support older phones then delete() would probably be safer.
// fileID == MediaStore.Images.Media._ID; for the file when you get the file from the content
// resolver
public static boolean deleteCREntryForFilePath(Context context, String filePath, long fileID) {
boolean fDeleted = false;
ContentResolver cr = context.getContentResolver();
int rowsDeleted = 0;
Uri imageURI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String deleteStr = MediaStore.Images.Media._ID + "=" + fileID;
MediaScannerConnection.scanFile(context, new String[]{filePath}, null, null);
// Remove entry from database
rowsDeleted = context.getContentResolver().delete(
imageURI, deleteStr, null);
if (rowsDeleted > 0)
fDeleted = true;
return(fDeleted);
}
Here is the code to get the file-id (name of the function is getfileId()) . It works for different file-types. You cannot compile the code as it is because it uses an internal object-type but you should be easily able to convert this for generic use.
public static String[] getCombinedEntityColumns(Constants.DELASHARE_OBJECT_TYPES objType) {
String[] entityColumns = new String[5];
switch (objType) {
case DELASHARE_OBJECT_PICTURE:
case DELASHARE_OBJECT_MUSIC:
case DELASHARE_OBJECT_VIDEO: {
entityColumns[0] = MediaStore.Images.Media.DISPLAY_NAME;
entityColumns[1] = MediaStore.Images.Media.DATA;
entityColumns[2] = MediaStore.Images.Media._ID;
entityColumns[3] = MediaStore.Images.Media.DATE_ADDED;
//entityColumns[3] = MediaStore.Images.Media.DATE_TAKEN;
entityColumns[4] = MediaStore.Images.Media.SIZE;
break;
}
case DELASHARE_OBJECT_APK:
case DELASHARE_OBJECT_DOCUMENT:
case DELASHARE_OBJECT_DOWNLOAD:
case DELASHARE_OBJECT_SEARCH_RESULTS:
default: {
entityColumns[0] = MediaStore.Files.FileColumns.DISPLAY_NAME;
entityColumns[1] = MediaStore.Files.FileColumns.DATA;
entityColumns[2] = MediaStore.Files.FileColumns._ID;
entityColumns[3] = MediaStore.Files.FileColumns.DATE_MODIFIED;
entityColumns[4] = MediaStore.Files.FileColumns.SIZE;
break;
}
}
return (entityColumns);
}
public static Uri getCategoryUri(Constants.DELASHARE_OBJECT_TYPES categoryObjType) {
Uri objUri = null;
switch(categoryObjType) {
case DELASHARE_OBJECT_PICTURE:
objUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case DELASHARE_OBJECT_VIDEO:
objUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case DELASHARE_OBJECT_MUSIC:
objUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
case DELASHARE_OBJECT_DOWNLOAD: {
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
objUri = Uri.fromFile( downloadDir);
//objUri = MediaStore.Files.getContentUri("external");
break;
}
case DELASHARE_OBJECT_APK:
case DELASHARE_OBJECT_DOCUMENT:
case DELASHARE_OBJECT_SEARCH_RESULTS:
default:
objUri = MediaStore.Files.getContentUri("external");
break;
}
return(objUri);
}
public static long getFileId(Context context, String dirPath, String filePath, String fileName, Constants.DELASHARE_OBJECT_TYPES objType) {
boolean fIDFound = false;
long id = 0;
if (!fIDFound) {
String sortOrder = null;
String[] entityColumns = getCombinedEntityColumns(objType);
Uri categoryUri = getCategoryUri(objType);
String selection = null;
String[] selectionArgs = new String[]{Constants.DELA_PERCENT_STR + dirPath};
ContentResolver cr = context.getContentResolver();
Cursor cursor = null;
switch (objType) {
case DELASHARE_OBJECT_PICTURE:
selection = MediaStore.Images.Media.DATA + " LIKE ?";
break;
case DELASHARE_OBJECT_VIDEO:
selection = MediaStore.Video.Media.DATA + " LIKE ?";
break;
case DELASHARE_OBJECT_DOCUMENT:
default:
selection = MediaStore.Files.FileColumns.DATA + " LIKE ?";
break;
}
cursor = cr.query(
categoryUri,
entityColumns,
selection,
selectionArgs,
sortOrder);
if (cursor != null && cursor.moveToFirst()) {
id = cursor.getLong(cursor.getColumnIndex(entityColumns[2]));
if (id != 0) {
fIDFound = true;
}
}
if (cursor != null) {
cursor.close();
cursor = null;
}
}
return(id);
}
I had the same question as you now that the sendBroadcast approach is disallowed in 4.4 and found a good solution here using the Media Store content provider: https://stackoverflow.com/a/20780472/1060805
I tested it out on Android 4.4 and it works nicely. I think it is a solid approach.
Try
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Add this to your manifest:
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
I always found the following answer for my Question:
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
but it do not work on my System (Nexus4 Android 4. ...)
I can create a File and add it to the Media-DB whith this code
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
Where "file" is the new image-file i want to add.
after deleting the File I try to refresch the gallery by
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
Uri contentUri = Uri.parse("file://" + Environment.getExternalStorageDirectory());
intent.setData(contentUri);
context.sendBroadcast(intent);
or
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
but there are still empty placeholder in the Galery.
I do not know why?...
To be on the safe side I add too my Activity in the AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
but the result is the same. Any idea to solve the problem?
After the KitKat you can't send the Intent to run the MediaScanner on whole device's storage, because it is a CPU I\O intensive task and if every single app that download an image or delete one, call that intent battery would drain easily, hence they have decided to block that operation. Here are your options:
Use the old way for pre-KitKat
Pass your filePath:
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
} else{
MediaScannerConnection.scanFile(mContext, filePath, 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);
}
});
}
A more reliable approach is to update the MediaStore directly:
// 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();
Check below code snippet to verify all the cases for add/delete/move image file programmatically and intimate the gallery app to refresh the data
/***
* Refresh Gallery after add image file programmatically
* Refresh Gallery after move image file programmatically
* Refresh Gallery after delete image file programmatically
*
* #param fileUri : Image file path which add/move/delete from physical location
*/
public void refreshGallery(String fileUri) {
// Convert to file Object
File file = new File(fileUri);
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
// Write Kitkat version specific code for add entry to gallery database
// Check for file existence
if (file.exists()) {
// Add / Move File
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(new File(fileUri));
mediaScanIntent.setData(contentUri);
BaseApplication.appContext.sendBroadcast(mediaScanIntent);
} else {
// Delete File
try {
BaseApplication.appContext.getContentResolver().delete(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media.DATA + "='"
+ new File(fileUri).getPath() + "'", null);
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
BaseApplication.appContext.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ getBaseFolder().getAbsolutePath())));
}
}
For Xamarin C# you can Use following Code!
Just pass the full File path to the Array
Android.Media.MediaScannerConnection.ScanFile(Android.App.Application.Context, new string[] { deletedImageFilePath}, null, null);
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
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
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();
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
To delete image,
ContentResolver contentResolver = getContentResolver();
contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.ImageColumns.DATA + "=?" , new String[]{ imagePath });
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.
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")
}
}
}
}
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.
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!
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();
}
DocumentFile.fromSingleUri(context, uri).delete();
Working great for me
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