Count Your SAF Uri Persisted Permissions!
Now that everyone (cough) is using the Storage Access Framework (SAF), we are starting to push the boundaries of what it can and cannot do. As developers have yelped about over the years, the SAF has its limits.
And, as one of my subscribers pointed out recently, one of those limits is how many persistable permission grants you can take.
As I wrote about last year,
you can call
Uri that you get back from an SAF request like
This indicates your interest in long-term access to the content, and typically
that will be granted (though, technically, it depends on the
However, there is a cap of 128 persisted permission grants that you can obtain.
I agree with the analysis in the associated issue: 128 is rather low. However, since AFAIK this limit has been there since the outset, even if it changed for Android 11 (or 12 or …), we still have to cope with the limit on older devices.
You can find out how many grants you have by calling
ContentResolver. If you are near the limit, you may need to release an older
grant by means of calling
releasePersistableUriPermission() on a
That could be based on a user selection of some past document in your UI, or perhaps
chosen automatically via an LRU algorithm. For those that you release, AFAIK you would need
to ask the user to re-select the document in the SAF in order to get rights to it
again in the future.
Also, AFAIK, it is possible for the user to choose over 128 documents if
EXTRA_ALLOW_MULTIPLE. Hence, you might not be able to
assume that you can just spin through the returned
Uri roster and take persistable
permissions for each of them. This may not be limited to some accumulation of
grants over time — you could run into the problem right away.
Ideally, you aim to request fewer persisted permission grants. For example, if you are going to need a bunch of documents from the user that might be in the same tree, ask the user to give you access to the tree, not the individual documents in that tree.
Or, consider whether you need to change the semantics of your app’s use of selected documents. Instead of some sort of “link” action that implies that you are retaining access to the original document, you may need to offer “import” and make your own copy of the document. This takes up more disk space, but it avoids having to shuffle around permission grants to keep under the limit. Or, if you reach the limit, give the user a choice of dropping access to an older document or importing it, so you can work with the copy.
There may be other strategies as well. If you have come up with an interesting workaround, post it as a comment on the issue!
Interested in Jetpack Compose?
jetc.dev has a weekly newsletter of the latest articles, samples, and other details of Compose development!