我可以使用 ActivityResultContracts.GetContent() 中的 URI 多长时间?

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

基本上,我试图让用户从他们 phone 的图片库中选择图片作为我应用程序的背景图片。

这是我的代码:

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.
    }
}

我担心的是:如果用户删除图像或切换到新图像会发生什么情况 phone。 URI 应该中断,对吧?更好的方法是将图片保存到我的本地应用程序存储并保存指向那里的 URI?

但是,我已经尝试从 phone 的图库中删除图片,重置图库缓存,关闭并重新打开应用程序,重新启动 phone...然后我我仍然可以在我的应用程序中查看图像。

真的有必要创建我自己的文件副本吗?

registerForActivityResult(ActivityResultContracts.GetContent()) 给我的 URI 持续多长时间?

我找到了这个 SO post & this article by CommonsWare,但网上没有其他东西,而且我还没有遇到任何错误...

注意:我一直在测试 Android 12 API 31.

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

通常会。更重要的是,您可能无法在您的应用进程终止后立即使用该 Uri

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.

您不应假定它适用于所有 Android OS 版本、Android 设备型号、图库应用等。您似乎已经在一种设备型号上进行了测试数以万计,使用 OS 目前只有一小部分用户使用的版本。

如果,OTOH,你是你的应用程序的唯一用户,并且只在这个设备上,欢迎你做任何你想做的事。

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

这取决于你的 objective。

您可以使用 OpenDocument 而不是 GetContent,并使用 takePersistableUriPermission() 获得对该内容的 long-term 访问权限。这是“附加”操作:您想将内容附加到您的应用程序,但您很乐意让外部工具管理该内容。这处理 process-was-terminated 场景和 phone-was-rebooted 场景。它不处理 user-nuked-the-content-from-orbit 场景、user-modified-the-content 场景等

如果您需要访问内容而不考虑外部用户操作,请复制该内容。这是“导入”操作:您希望内容的副本由您的应用专门管理。