'Persisted SAF URI from Google Drive changes after a few days, content is unreachable

I'm persisting an URI obtained via SAF launched with the following intent:

val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
    .setType("application/json")
    .putExtra("android.content.extra.SHOW_ADVANCED", true)
    .putExtra("android.content.extra.FANCY", true)
    .putExtra("android.content.extra.SHOW_FILESIZE", true)
    .addCategory(Intent.CATEGORY_OPENABLE)
    .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
        Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)

I didn't use the Intent.FLAG_GRANT_READ_URI_PERMISSION flag, because I don't need it. This initially works, and keeps working after activity is destroyed, at least for a few days. After a few days:

  • The URI saved to my database is apparently no longer valid. ContentResolver.persistedUriPermissions doesn't show it. Yet, the file hasn't moved and wasn't renamed.
  • ContentResolver.persistedUriPermissions does return a few URIs, but none can be resolved, despite being supposedly persisted. The error I get with contentResolver.openOutputStream(uri) is: "Failed to find provider info for com.google.android.apps.docs.storage" (as if it wasn't being found the day before!).

I have only tested with Google Drive for now, so I assumed the issue is related to it. I'm testing it with local storage, but I'll have to wait a few days to see the result. In the meantime: am I missing important flags on the Intent? Am I correct to save the URI as a string? Has this been known to happen to anyone else?



Solution 1:[1]

I'm running in to this issue too. It seems to be ok with Uris selected from the Files app, but the Google Drive Uris that I persist as Strings will stop working after an hour or so (a seemingly random delay, but after an app restart). On app startup, I could see that the Uri is still returned by getPersistedUriPermissions(), but when used in mediaMetadataRetriever.setDataSource(context, uri) it would throw an IllegalArgumentException. After this, it would not be returned by getPersistedUriPermissions() anymore, and if I try to access it again, it would throw a java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFEA.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcus Hultman