0

Android 7.0, API 24. Permissions are granted in both AndroidManifest and real time.

Following are the scenarios which I have tried:

  • Only using the content resolver removes it from MediaStore but it comes back when the device is restarted.
  • When deleting an internal image "/storage/emulated/0/DCIM/Camera/..." it works, but when trying to delete an external image (or what should be external image) "/storage/4ED7-7F17/DCIM/Camera/..." it fails at file.canWrite().
  • Using Environment.getExternalStorageDirectory().getAbsolutePath() returns "/storage/emulated/0" (+ "/DCIM/Camera/...") and it fails at file.exists().
  • Hardcoding "/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();
    }
}
pfx
  • 20,323
  • 43
  • 37
  • 57
andytimmy
  • 1
  • 2
  • `fails at file.exists()` can you update your question with the error log you see? – Sagar May 03 '18 at 01:33
  • `getAbsolutePath() returns "storage/emulated/0"`. No that will return `/storage/emulated/0`. You made that error several times. Please update your post. – greenapps May 03 '18 at 07:39
  • `"/SD card/DCIM/Camera/..." (which should be the correct filepath) `. Not at all. That is a non existing path on an Android devics. – greenapps May 03 '18 at 07:49
  • `Weirdly, in the Android Device File Explorer, the files that should be in the SD Card folder are in the "storage/4ED7-7F17/" `. No. If you mean in /storage/4ED7-7F17 than that is pretty normal. Thats the way it goes. Weird would be if they would be in 'the SD Card folder'. Whatever that would be. – greenapps May 03 '18 at 07:51

2 Answers2

0

) "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.

greenapps
  • 11,154
  • 2
  • 16
  • 19
  • That is true on Oreo+. This behavior occurs on N, but the Storage Access framework isn't available on N. And it does not occur on – Robin Davies May 18 '18 at 13:39
  • Storage Access Framework is available on Android 7. Even on Android 5 and 6. – greenapps May 18 '18 at 13:44
  • Which will fail on Q with "java.lang.UnsupportedOperationException: Delete not supported" if the image is on an SD Card. Of course. Because storage access framework continues to be increasingly more broken. You can create an image. But you can't delete it. What's with THAT?!!!! – Robin Davies Feb 06 '20 at 20:22
0

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.

Robin Davies
  • 7,547
  • 1
  • 35
  • 50