Room 小部件中的 setImageViewUri

setImageViewUri in widget from Room

我有一个允许用户拍照的应用程序。然后我将图像存储在本地文件中并将 URI 保存到 Room。然后我有一个与具有图像视图的应用程序关联的小部件。我使用 Dagger-Hilt 将我的数据库注入到小部件中,并成功将该 URI 传递给我的 updateAppWidget 方法

有问题的 URI:

file:///storage/emulated/0/Android/media/com.sudharsanravikumar.myapplication/AlbumExpo/2021-11-08-07-37-55-596.jpg

问题是应用程序崩溃并出现以下错误:

java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/emulated/0/Android/media/com.sudharsanravikumar.myapplication/AlbumExpo/2021-11-08-07-37-55-596.jpg

我已经在类似的 SO 问题上尝试了很多东西,但感觉我遗漏了一些重要信息。我想我只是不太清楚如何使用我的清单上的文件提供程序标签将应用程序正确指向应用程序存储我的图像的目录。我不确定在代码方面要显示什么,所以如果您需要任何东西,请在评论中询问。

最初我的错误是:

    android.os.FileUriExposedException: file:///storage/emulated/0/Android/media/com.sudharsanravikumar.myapplication/AlbumExpo/2021-11-08-07-37-55-596.jpg exposed beyond app through RemoteViews.setUri()

这是我直接调用时生成的

 views.setImageViewUri(R.id.img_1, Uri.parse(uri.uri))

使用我上面的原始 uri。为了尝试解决这个问题,我遵循了这个接受的答案

引导我做的事情:

val photoURI = FileProvider.getUriForFile(
    context,
    "com.sudharsanravikumar.myapplication.provider",
    File(uri.uri)
)
 views.setImageViewUri(R.id.img_1, photoURI)

我假设从我的原始 uri 创建文件然后使用文件提供程序将其重新转换为 uri 的过程使它的路径变为错误所说的内容。

val photoURI = FileProvider.getUriForFile(
    context,
    "com.sudharsanravikumar.myapplication.provider",
    File(uri.uri)
)

uri.uri 似乎是 String,值为:file:///storage/emulated/0/Android/media/com.sudharsanravikumar.myapplication/AlbumExpo/2021-11-08-07-37-55-596.jpg.

这是 Uri 的字符串表示形式,file 方案。它不是文件系统路径。您不能将它传递给 File 构造函数并获得有用的东西。

您似乎最初是通过 getExternalMediaDirs() 获得您的价值的。您可能会考虑保留该文件系统路径值,而不是使用您无法使用的 file 方案将其转换为 Uri(通过 Uri.fromFile())。

但是,鉴于您当前的 uri.uri 值,您需要将代码更改为:

val photoURI = FileProvider.getUriForFile(
    context,
    "com.sudharsanravikumar.myapplication.provider",
    File(Uri.parse(uri.uri).path)
)

Uri.parse(uri.uri) 会将 String 变回 Uri,尽管其中的 file 方案几乎毫无用处。 Uri.parse(uri.uri).path 将提取文件系统路径 (/storage/emulated/0/Android/media/com.sudharsanravikumar.myapplication/AlbumExpo/2021-11-08-07-37-55-596.jpg)。然后将 that 传递给 File 构造函数。始终将文件系统路径传递给 File 构造函数。