Reputation: 1
Android 7.0, API 24. Permissions are granted in both AndroidManifest and real time.
Following are the scenarios which I have tried:
Environment.getExternalStorageDirectory().getAbsolutePath()
returns "/storage/emulated/0" (+ "/DCIM/Camera/...")
and it fails at file.exists(). "/SD card/DCIM/Camera/..."
(which should be the correct filepath) fails at file.exists().Weirdly, in the Android Device File Explorer, the files that should be in the SD Card folder are in the "/storage/4ED7-7F17/" folder which the files have a permission listing of -rwxrwx--x. And permission inside "/storage/emulated/" is "Permission denied". But to find the files in Android app MyFiles or Windows File Explorer the files are in "/SD card/DCIM/Camera/...".
Completely confused any help would be greatly appreciated.
File file = new File(filename);
if (file.exists()) {
if (file.canWrite()) {
if (file.delete()) {
// Set up the projection (we only need the ID)
String[] projection = {MediaStore.Files.FileColumns._ID};
// Match on the file path
String selection = MediaStore.Files.FileColumns.DATA + " = ?";
String[] selectionArgs = new String[]{filename};
Uri queryUri;
if (isVideo) {
// Query for the ID of the media matching the file path
queryUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else {
// Query for the ID of the media matching the file path
queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentResolver contentResolver = context.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.Files.FileColumns._ID));
Uri deleteUri = ContentUris.withAppendedId(
MediaStore.Files.getContentUri("external"), id);
contentResolver.delete(deleteUri, null, null);
} else {
// File not found in media store DB
Toast.makeText(context, "File not found: " + filename,
Toast.LENGTH_LONG).show();
}
c.close();
Toast.makeText(context, "File deleted: " + filename,
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "File not deleted: " + filename,
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context, "File cannot be wrote to: " + filename,
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context, "File does not exist: " + filename,
Toast.LENGTH_LONG).show();
}
}
Upvotes: 0
Views: 1179
Reputation: 7827
I stand correct. What's missing on N is MediaStore.getDocumentUri(Context context, Uri mediaUri)
, which provides conversion of fictitious file paths for the DCIM directory on Oreo+ to a Storage Access Framework URI that can be used to delete the file. N doesn't seem to provide an equivalent that I can find. And the content: Uris for media files don't work with Storage Access Framework unless converted.
Upvotes: 0
Reputation: 11224
) "storage/4ED7-7F17/DCIM/Camera/..." it fails at file.canWrite().
Yes of course. Micro SD cards are read only on modern Android systems.
Apps nowadays can only write in one app specific directory on SD card.
If you want write access to the whole card you need to use the Storage Access Framework.
Upvotes: 0