AndroidX Glance ImageProvider(Bitmap) does not update after system theme changes while ColorProvider content does


I'm investigating what appears to be an issue with AndroidX Glance widgets and would like to know whether this is expected behavior, a limitation of ImageProvider(Bitmap), or a bug.

Environment

  • AndroidX Glance: 1.1.1

  • Android API: 34–36

  • Tested on:

    • Android Emulator (AOSP / Pixel Launcher)

    • Xiaomi 15 (HyperOS Launcher)

    • ZTE Blade V70 MAX

  • Kotlin

Expected behavior

My widget contains:

  • a Text using ColorProvider

  • an Image created from a Bitmap using ImageProvider(bitmap)

When the system theme changes (Light ↔ Dark), I expect:

  • the Text to update

  • a new bitmap to be generated

  • the widget image to update to the newly generated bitmap

Actual behavior

<s>The Text updates correctly.</s> Text color updates, the content doesn't.

The bitmap-backed Image continues displaying the previous bitmap.

The bitmap only updates after a completely new widget session is created (for example after force stopping the app or recreating the widget).

code to reproduce: https://github.com/JuanJoseDev88/Glance-imageprovider-theme-bug.git

minimal example (updated):

class GlanceBugWidget : GlanceAppWidget() {
    override suspend fun provideGlance(context: Context, id: GlanceId) {
        Log.d(&quot;GlanceBug&quot;, &quot;provideGlance()&quot;)
        
        provideContent {
            WidgetContent()
        }
    }
}

@Composable
private fun WidgetContent() {
    val context = LocalContext.current
    val uiMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
    val isDark = uiMode == Configuration.UI_MODE_NIGHT_YES

    val timestamp = System.currentTimeMillis()
    val uuid = UUID.randomUUID().toString()

    Log.d(&quot;GlanceBug&quot;, &quot;WidgetContent()&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;timestamp=$timestamp&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;uuid=$uuid&quot;)

    val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
    if (isDark) {
        bitmap.eraseColor(android.graphics.Color.WHITE)
    } else {
        bitmap.eraseColor(android.graphics.Color.BLACK)
    }
    
    Log.d(&quot;GlanceBug&quot;, &quot;uiMode=${if (isDark) &quot;DARK&quot; else &quot;LIGHT&quot;}&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;bitmap generationId=${bitmap.generationId}&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;bitmap hash=${System.identityHashCode(bitmap)}&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;bitmap size=${bitmap.width}x${bitmap.height}&quot;)
    Log.d(&quot;GlanceBug&quot;, &quot;pixel00=${String.format(&quot;#%08X&quot;, bitmap.getPixel(0, 0))}&quot;)

    val themeText = &quot;Theme: ${if (isDark) &quot;DARK&quot; else &quot;LIGHT&quot;}\n\nTimestamp:\n$timestamp\n\nUUID:\n$uuid&quot;

    Column {
        Text(
            text = themeText,
            style = TextStyle(
                color = ColorProvider(
                    day = Color.Black,
                    night = Color.White
                )
            )
        )
        Image(
            provider = ImageProvider(bitmap),
            contentDescription = &quot;Theme rectangle&quot;,
            modifier = GlanceModifier.size(100.dp)
        )
    }
}

I spent quite a bit of time trying to rule out application bugs.

I verified that:

  • A new Bitmap is created every render.

  • Every bitmap has a new generationId.

  • Every bitmap has a different object identity.

  • The bitmap contains the expected pixels before being passed to ImageProvider.

  • The bitmap colors are correct before ImageProvider(bitmap) is constructed.

  • The issue reproduces on both Pixel Launcher and HyperOS Launcher.

  • The issue reproduces on the Android Emulator and real device.

The only thing that does not update is the bitmap displayed by ImageProvider.

0
Jul 2 at 9:41 PM
User Avatarjuan jose perez hernandez
#android#bitmap#androidx#remoteview#glance-appwidget

No answer found for this question yet.