Android KitKat securityException when trying to read from MediaStore Android KitKat securityException when trying to read from MediaStore android android

Android KitKat securityException when trying to read from MediaStore


Had the same problem for the last couple of days. Tried a few solutions, but for some reason I was getting permission denial on Uri content provider for some images even when I had the android.permission.MANAGE_DOCUMENTS permission added to my manifest.

Here's a workaround, for the time being:

i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(i, CHOOSE_IMAGE);

This forces the older image gallery to open instead of the new Kitkat documents view.

Now, you can get the Uri by calling the following in your onActivityResult:

Uri selectedImageURI = data.getData();

Hope this helps.


In the Intent used to prompt the user to add a file, use Intent.ACTION_OPEN_DOCUMENT (on KitKat API 19 or higher) instead of Intent.ACTION_GET_CONTENT or Intent.ACTION_PICK. Then, when you want to use the Uri, take the previous persistent permissions that were set by Intent.ACTION_OPEN_DOCUMENT as described in @feri's link ( https://developer.android.com/guide/topics/providers/document-provider.html#permissions):

final int takeFlags = data.getFlags()        & (Intent.FLAG_GRANT_READ_URI_PERMISSION        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);// Check for the freshest data.getContentResolver().takePersistableUriPermission(originalUri, takeFlags);

You can read more about the differences between Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK, and Intent.ACTION_OPEN_DOCUMENT here: http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT


OK, I found a working sample that gets past the issue:

            intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);            intent.addCategory(Intent.CATEGORY_OPENABLE);            intent.setType("image/*");            startActivityForResult(intent, myClassConstant.SELECT_PICTURE);

Here's what I've learned...this is a change in KitKat, and this code only works on API 19 and up. It will not work for older versions so you need to have methods for pre-KitKat as well. Once you get the file using the Category_Openable argument, in my case an image, you can then use it by referencing it as the URI. In my case, I store the URIString (file path) and I'm able to do what I want with it after the open occurs.

The issue I'm now trying to figure out is how long the file permissions persist. It appears that it expired since yesterday, as my code looks for the UriString, then tries to open the file. If I use the code above to select the image, it works - it stores the name, and I was able to exit the program, go back in and it still worked...however, my first run of the program this morning (after not touching it in 12+ hours), it acted like it couldn't find the file (and I'm sure if watching through the debugger, I'd see the non-critical error appear again.

So now the question is: How do we persist the permissions once I know what the file (name) is?