Android Question Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider

LucaMs

Expert
Licensed User
Longtime User
With reference to this post and the following ones...

MediaPlayer can successfully play the selected file, if newly selected.
If I save "directory" and file name, retrieve them from file and send them to the MediaPlayer, I get that error message, a permission is missing.

(... requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs)

How to do?
 

LucaMs

Expert
Licensed User
Longtime User
I'm attaching an example.

Select an audio file; MediaPlayer will play it, Dir and FileName will be saved as text file.

Start the app again. The two strings will be read and displayed. Pressing Play will call MediaPlayer's Play method, passing the two strings to it and then the app will crash.
 

Attachments

  • ContentChooserTest.zip
    16.6 KB · Views: 329
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
android documentation states:
"Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to
documents owned by a document provider."
implying exactly what you've seen: first time works ok, subsequent attempts fail, apparently having lost
permission to access.
it looks like you'll need an intent with the abovementioned action to access the uri.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
it works here with permission

B4X:
For Each permission As String In Array(rp.PERMISSION_READ_EXTERNAL_STORAGE,rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
        rp.CheckAndRequest(permission)
        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
        If Result = False Then
            ToastMessageShow("No permission!", True)          
            Return
        End If
    Next
Sorry but this has nothing to do with it.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
without permissions I have this log and it doesn't work while with permissions it works.
If it has nothing to do with your post I can delete my post

log:
B4X:
(SecurityException) java.lang.SecurityException:
Permission Denial: reading com.android.providers.media.MediaProvider
uri content://media/external/audio/media/2399 from pid=13489,
uid=10451 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
B4X:
It's a different matter, believe me.

EREEEEEEEEL ?
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
you may have already discovered all or most of this.
the key: "The permission denial issue needs to be dealt with the first time you receive a URI."

our content chooser is designed to allow one-time access a resource: at the time of selection. to access the same resource at some other time, you have to run the chooser again and select the same resource. not the end of the world, but it is what it is. saving the uri in some file for later access does not work. (obviously, copying the contents of the uri to local storage is a different matter, but we're talking about saving the uri as if it were some file name.)

the explanation is found at https://stackoverflow.com/questions...n-action-get-content-and-action-open-document
basically:
Use ACTION_GET_CONTENT if you want your app to simply read/import data. when the selection is made in the chooser.
Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to documents owned by a document provider.

our content chooser uses ACTION_GET_CONTENT. whether it can simply be recompiled with ACTION_OPEN_DOCUMENT is something i'm working up to.
while recompiling might be simple enough, there is another part to the solution. that part is a little more involved.
it is found here: https://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
basically:
a persistable permission must be granted by the provider. this would be done when the chooser returns the uri (our chooser only returns the uri)
that permission then needs to be "taken" by the entity that accesses the uri.
if you want to maintain access to the resource, you need to explicitly take the persistable permissions using ContentResolver#takePersistableUriPermission(Uri, int).
in other words, the provider will supply the special permission, but the entity that wants to access the uri at a later time has to capture that permission when the uri is first
received and then invoke the permission the next time it tries to access the resource using the originally supplied uri. so, save the permissions + the uri and then use them both later.
i'm thinking (hoping) a remodeled chooser will expose the permission. then, when the chooser triggers the CC_result event, it can return the permission to the app, along with the uri.
at least that's what i'm going to try.
Ok, but so... what's the solution for such an app?
It is not for me (as always now) but for another Italian member. Its operation is similar to the attached project.

Also, the question could be about any other file type (MIME).
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
i don't see why a different mime type cannot be specified
I meant to say...

Erel posts a link to that thread, that example, whenever it comes to accessing external storage. Just as "Background location tracking" is always suggested when it comes to keeping an app active in the background. We can consider them two "reference projects".

But that example is specific to the text MIME type and yes, you can easily change it (as indeed I did for audio files); it is a "Save As" but it is not suitable for every MIME type in reading, as in this case, audio files.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
as discussed.
Yes, it works but it allows you to choose from fewer sources; for example (and mainly) it does not let you access (and then select) a file from the file manager.

ContentChooser.............................................................................GContentChooser
Screenshot_20230306-023417.jpg
Screenshot_20230306-023500.jpg
 
Last edited:
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
i don't have a "file manager" (whatever that is). please delete my solution. thanks.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
If you want (almost) permanent access to a folder then you need to use ExternalStorage.
What "I" (another Italian member) needs would be to be able to make the user of his app choose audio files from his device without knowing the path and to be able to associate that audio file to a button, so as to be able to play the file in MediaPlayer when pressing the button, even in different "sessions".

So I guess the only solution is that the first time the file is selected, you should save it in the DirInternal.
I'll see if I can do it (and if the Italian member will be "happy" with it ?).

Thank you
 
Upvote 0
Top