androidexceptionandroid-contentresolver

Android Q RecoverableSecurityException not granting access


I'm trying to get my file handling sorted for Android API 29. Since I'm no star in anything related to files on Android, I've run into a problem.

When I add images to my app I can delete them using contentResolver.delete(deleteUri, null, null); and everything works fine. But when the app is removed and then reinstalled it gives me a RecoverableSecurityException, this is accounted for and I've made it so that permission is requested to the file to be able to delete it. When permission is granted and I'm trying to delete the file again, it still gives me android.app.RecoverableSecurityException: **app**.debug has no access to content://media/external/images/media/280. It is removed from the ContentResolver since it's no longer visible in any of the galleries and it returns no result when queried for, but the file is still "physically" on the device.

Where do I need to look to fix this problem? There is only one result from the ContentResolver, the file path it shows in a different error(shown together with the above error) is correct: E/MediaProvider: Couldn't delete /storage/emulated/0/Pictures/**app**/**filename**.jpeg

Delete file function:

Cursor c = getCursorFromContentResolver(fileName);

        if (c != null && c.moveToFirst())
        {
            long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
            Uri deleteUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
            try
            {
                contentResolver.delete(deleteUri, null, null);
            }catch (RecoverableSecurityException e)
            {
                //After the below Intent returns, the current function is run again
                activity.startIntentSenderForResult(e.getUserAction().getActionIntent().getIntentSender(), requestCode, null, 0, 0, 0, null);
            }
            c.close();
            return true;
        }

Other permissions are requested:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Solution

  • I have come across a very similar issue in Android Q, when deleting an image using Content resolver delete call. It turned out that despite me catching RecoverableSecurityException for permission to delete the image from the android gallery - it still has thrown an error that it could not delete the file because the app doesn't have permission (thus after opening Google Photos it would scan for images and find the "undeleted" one making it come back). This is where I saw the same error as in your question. When I tried the same code on Android R file did not come back.

    After reading on this issue I tried SAF as a solution. The way I managed to delete image for good was to get the user to select a directory of the images (in my case DCIM/Camera) using Intent.ACTION_OPEN_DOCUMENT_TREE

    Then I've captured Uri of the parent folder and name of the file in that folder when delete button was pressed:

     String filename = queryUriName(content, photoUri);
    
     DocumentFile docF = DocumentFile.fromTreeUri(context,myTree);
     Boolean docex = docF.exists();
     String idDoc = DocumentsContract.getTreeDocumentId(myTree);
     idDoc = idDoc + "/"+filename;
     Uri childrenUri = DocumentsContract.buildDocumentUriUsingTree(myTree,idDoc);
    
     DocumentFile childfile = DocumentFile.fromSingleUri(context,childrenUri);
     Boolean chex = childfile.exists();
     System.out.println("child exist: "+ chex+ " file name is " + filename +"   "+idDoc);
    

    This allowed to delete the actual file and from what I can tell it does not throw any errors and file is gone.

    Take this with caution as I am ~3 weeks into android dev and could not find problem described nor solution elsewhere. But would be happy to expand on or update the answer if needed.