Как загрузить растровое изображение в компонуемый Glance через Coil Uri?

Я следую примеру кода из ImageGlanceWidget, чтобы загрузить растровое изображение в Glance через Uri.

Как упоминалось в комментариях к этому ответу, я заменил метод getImageProvider() приведенным ниже кодом. Однако, когда я это делаю, я получаю сообщение об ошибке: Error in Glance App Widget java.io.FileNotFoundException: No content provider:/data/user/0/com.example.myappname/cache/image_cache/56448.....8e0ad2fac0.1.

Как я могу вытащить растровое изображение из кеша диска катушки?

private fun getImageProvider(context: Context, coilPath: String): ImageProvider {
    val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, coilPath.toUri())
    return ImageProvider(bitmap)
}

Значения параметров

val coilPath = context.imageLoader.diskCache?.get("https://picsum.photos/${width.roundToInt()}/${height.roundToInt()}")?.data?.toFile()?.path!! /*uses worker context*/
val context = LocalContext.current /*pass in context from glance composable to getImageProvider*/

Полная трассировка стека

E/GlanceAppWidget: Error in Glance App Widget
    java.io.FileNotFoundException: No content provider: /data/user/0/com.example.mpappname/cache/image_cache/56448c7214ea904b18f01d34bdd997afd53c1c976abda4a67546d08e0ad2fac0.1
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2013)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1842)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1518)
        at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:2322)
        at com.example.stockwidgetv1.clean.widget.glance.utility.WidgetDummy.getImageProvider2(WidgetDummy.kt:145)
        at com.example.stockwidgetv1.clean.widget.glance.utility.WidgetDummy.access$getImageProvider2(WidgetDummy.kt:44)
        at com.example.stockwidgetv1.clean.widget.glance.utility.WidgetDummy$Content$1.invoke(WidgetDummy.kt:101)
        at com.example.stockwidgetv1.clean.widget.glance.utility.WidgetDummy$Content$1.invoke(WidgetDummy.kt:97)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.glance.layout.BoxKt.Box(Box.kt:74)
        at com.example.stockwidgetv1.clean.widget.glance.utility.WidgetDummy.Content(WidgetDummy.kt:92)
        at androidx.glance.appwidget.GlanceAppWidget$setContent$1$1.invoke(GlanceAppWidget.kt:404)
        at androidx.glance.appwidget.GlanceAppWidget$setContent$1$1.invoke(GlanceAppWidget.kt:404)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.glance.appwidget.GlanceAppWidget$setContent$1.invoke(GlanceAppWidget.kt:398)
        at androidx.glance.appwidget.GlanceAppWidget$setContent$1.invoke(GlanceAppWidget.kt:397)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3248)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3238)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3238)
        at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3173)
        at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:950)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
        at androidx.glance.appwidget.GlanceAppWidget.setContent-Cox8Y-g(GlanceAppWidget.kt:397)
        at androidx.glance.appwidget.GlanceAppWidget.access$setContent-Cox8Y-g(GlanceAppWidget.kt:72)
        at androidx.glance.appwidget.GlanceAppWidget$composeForSize$2.invokeSuspend(GlanceAppWidget.kt:372)
        at androidx.glance.appwidget.GlanceAppWidget$composeForSize$2.invoke(Unknown Source:8)
        at androidx.glance.appwidget.GlanceAppWidget$composeForSize$2.invoke(Unknown Source:4)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:169)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
        at androidx.glance.appwidget.GlanceAppWidget.composeForSize-AAqiGWc$glance_appwidget_release(GlanceAppWidget.kt:365)
        at androidx.glance.appwidget.GlanceAppWidget$Api31Impl$composeAllSizes$2$allViews$1$1.invokeSuspend(GlanceAppWidget.kt:431)
E/GlanceAppWidget:     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Я предлагаю вам отредактировать свой вопрос и предоставить полную трассировку стека.

CommonsWare 26.11.2022 14:44
1
1
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте BitmapFactory.decodeFile(), чтобы получить Bitmap из File, указывающего на растровое изображение.

Было бы чище просто попросить Coil загрузить изображение. Таким образом, вы не будете пытаться возиться с кешем Coil (которым Coil также может манипулировать, например, очищать записи), и вы можете справиться с состоянием гонки вашего изображения, которое было извлечено из кеша, прежде чем вы попытаетесь его использовать. :

val request = ImageRequest.Builder(context)
    .data("https://www.example.com/image.jpg")
    .build()
val bitmap = imageLoader.execute(request).drawable.bitmap

спасибо, в моем случае я не буду делать http-запросы для изображения. как мне заставить это работать с локальным файлом, т.е. .data(file)? P.S. вторая гиперссылка в вашем ответе такая же, как и первая...

mars8 26.11.2022 15:11

@mairs8: «в моем случае я не буду делать http-запросы для изображения» — согласно вашему вопросу, вы загружаете изображение из picsum.photos. Несмотря на это, попробуйте передать объект File в data(). File по крайней мере работает с load(). И извините за URL-адрес — я забыл, что GitHub не копирует URL-адрес в буфер обмена, когда вы нажимаете значок ссылки, как это делают документы Android. Теперь это исправлено.

CommonsWare 26.11.2022 15:17

«Используйте BitmapFactory.decodeFile(), чтобы получить растровое изображение из файла, указывающего на растровое изображение». Я могу успешно увидеть свое растровое изображение, сохраненное в расположении файла в проводнике устройства. Однако, когда я использую файл декодирования (файл), я получаю сообщение об ошибке E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: file:/data/user/0/com.example.myappname/files/glance/64/130_‌​101.png: open failed: ENOENT (No such file or directory). Есть идеи?

mars8 26.11.2022 17:33

точное значение пути file следующее file:///data/user/0/com.example.myappname/files/glance/64/13‌​0_101.png

mars8 26.11.2022 17:34

@mairs8: Похоже, вы неправильно создаете свой объект File. Путь к файловой системе не должен иметь префикс file:.

CommonsWare 26.11.2022 17:36

спасибо, я использовал uri.toString вместо uri.path, который добавлял префикс `file:\`

mars8 26.11.2022 18:13

Другие вопросы по теме