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:31
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.
CodePudding user response:
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.