3

I have a widget developed with Jetpack Compose and with the Jetpack Glance library, this widget is a LazyColumn list, in which I pass the information after making a query to the Room Database database.

enter image description here

To try to load the image I used Image() with the provider, passing it a string (which is the url of the image I want to load)

Image(
   modifier = GlanceModifier.size(50.dp),
   provider = ImageProvider(item.image),
   contentDescription = null
)

This didn't load the image and I tried to pass that image url to a bitmap, to load it with BitmapImageProvider(), but it didn't work. Is there a way to load a remote image to a widget using Jetpack Glance?

Jéluchu
  • 394
  • 4
  • 13
  • Have you tried using the coil library? – Arfin Hosain Nov 08 '22 at 13:01
  • Yes, I have tried, but at that moment the widget stops showing information and shows a generic GlanceApplicationWidget error, as it doesn't have AsyncImage the Glance modifier, etc. I guess it collapses and stops working – Jéluchu Nov 08 '22 at 13:05
  • Please check this question. I hope it will solve your problem. https://stackoverflow.com/questions/70846371/crash-in-glance-app-widget-image-when-trying-to-display-bitmap?rq=1 – Arfin Hosain Nov 08 '22 at 13:12
  • Thanks, although I had already checked that thread, my error when I try to convert it to bitmap is "Error in Glance App Widget android.os.NetworkOnMainThreadException", which is partly more related to the coroutines, and since the conversion is done right in Image() I can't run the coroutine in a Composable as I could do it anywhere else in the app – Jéluchu Nov 08 '22 at 13:16

2 Answers2

4

I would recommend to check the ImageGlanceWidget sample code. The sample shows how to use WorkManager to load images from network and using URI or bitmaps to display them.

Loading images and doing background work with Glance/Widgets is tricky for now but we are improving this soon by supporting recomposition.

Here is an example of how it will look like in future releases of Glance https://gist.github.com/marcelpinto/6df5e3e6ca42c6a0bf34b9f4b6eb1cff

Marcel
  • 2,094
  • 3
  • 23
  • 37
  • 1
    I'm trying to test it, as I've tried to adapt it to a list item (as each item in the list has a different image), but so far when I apply it I get the message "Can't load widget" – Jéluchu Nov 08 '22 at 15:53
  • I have been testing, I have included the property allowHardware(isHardware) and debugging I have obtained correctly the bitmap, I have come to see in the widget the CircularProgressIndicator(), but at the time of showing the image the widget stops showing, one of the errors that I have come to leave in the logcat is: – Jéluchu Nov 08 '22 at 18:31
  • Error in Glance App Widget java.lang.IllegalStateException: Unable to create a fetcher that supports: coil.intercept.EngineInterceptor.fetch(EngineInterceptor.kt:160) – Jéluchu Nov 08 '22 at 18:32
  • You might be configuring wrongly Coil. This error does not look like Glance related. Try to just convert a drawable resource into a bitmap and ensure that works. If it does, then it must be sth wrong with Coil implementation – Marcel Nov 09 '22 at 11:07
  • 2
    @Marcel I too am getting "Can't load widget" using your sample code. There's a silent error being thrown somewhere in UriImageProvider that crashes the widget when it tries to render. It's not Coil, since Coil is just downloading the image and saving it to the cache (properly). In getImageProvider() I had to replace the implementation to pass a bitmap to the ImageProvider initializer instead: ```val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, pathFromCoilDiskCache.toUri()) return ImageProvider(bitmap)``` Hopefully the future release of Glance is coming soon! – Jon Reed Nov 15 '22 at 19:43
  • I echo the comments from @JonReed. I have been struggling to get glance image from Uri for a long time now and looking at the SO posts seems like I am not the only one. Any upcoming update to the Glance API to address this would be really appreciated. – mars8 Nov 24 '22 at 09:29
  • @JonReed could you please provide more details on how you got this to work? I have created another question [here](https://stackoverflow.com/questions/61892301/how-to-get-bitmap-from-url-using-coil) if you could kindly post an answer? – mars8 Nov 26 '22 at 13:01
  • See my other answer https://stackoverflow.com/a/75476922/1695078 – Marcel Feb 20 '23 at 08:46
0

For your provider parameter, you can use the below function to pull the bitmap from file. The path parameter is where you saved the downloaded bitmap in your local storage.

Image(
   modifier = GlanceModifier.size(50.dp),
   provider = getImageProvider(LocalContext.current),
   contentDescription = null
)
private fun getImageProvider(path: String): ImageProvider {
    return if (path=="") { /*dummy image to return if path is blank*/
        ImageProvider(R.drawable.ic_launcher_background)
    } else {
        val bitmap = BitmapFactory.decodeFile(path)
        ImageProvider(bitmap)
    }
}
/*path parameter example*/
val bitmapFile = File(fileDir, fileName)
val uri = Uri.fromFile(outputFile)
val path = uri.path ?: ""
mars8
  • 770
  • 1
  • 11
  • 25