简体   繁体   中英

How long can I use the URI from ActivityResultContracts.GetContent() for?

Basically, I'm trying to let users choose pictures from their phone's image gallery to use as background images in my app.

Here is my code:

private val pickImages = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
    // e.g. content://com.android.providers.media.documents/document/image%3A31
    android.util.Log.d("dev-", "uri = $uri?.toString()")
    uri?.let {
        // save uri to my DB, etc.
    }
}

My concern is: what happens if the user deletes the images or switches to a new phone. The URI should break, right? And a better approach would be to save the picture to my local app storage and save a URI that points there?

However, I've tried deleting the picture from my phone's gallery, resetting the gallery cache, close & re-open the app, restarting the phone...and I'm still able to the image in my app.

Is it really necessary to create my own copy of the file?

How long does the URI I'm given by registerForActivityResult(ActivityResultContracts.GetContent()) last?

I found this SO post & this article by CommonsWare , but nothing else online and I haven't encountered any errors yet...

Note: I've been testing on Android 12 API 31.

Update :

I finally found official documentation that answers my question .

When your app opens a file for reading or writing, the system gives your app a URI permission grant for that file, which lasts until the user's device restarts.

My concern is: what happens if the user deletes the images or switches to a new phone. The URI should break, right?

Usually it will. More importantly, you may be unable to use that Uri as soon as your app process terminates.

However, I've tried deleting the picture from my phone's gallery, resetting the gallery cache, close & re-open the app, restarting the phone...and I'm still able to the image in my app.

You should not assume that it will work across all Android OS versions, Android device models, gallery apps, etc. You appear to have tested on one device model out of tens of thousands, using an OS version that, at present, is used by a small percentage of the user base.

If, OTOH, you are the only user of your app, and only ever on this device, you are welcome to do whatever you want.

Is it really necessary to create my own copy of the file?

That depends on your objective.

You could use OpenDocument instead of GetContent , and use takePersistableUriPermission() to get long-term access to that content. This is the "attach" action: you want to attach content to your app but you are happy letting external tools manage that content. This handles the process-was-terminated scenario and the phone-was-rebooted scenario. It does not handle the user-nuked-the-content-from-orbit scenario, the user-modified-the-content scenario, etc.

If you need access to the content regardless external user manipulation, make a copy of that content. This is the "import" action: you want a copy of the content to be managed exclusively by your app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM