Karim
Karim

Reputation: 233

How to update the AppWidgetState of a Compose Glance Widget from a Configuration/Main Activity?

My latest idea was to use

updateAppWidgetState(context = context, definition = PreferencesGlanceStateDefinition, glanceId = glanceId) {
   // ...
}

and

GlanceWidget().update(context = context, glanceId = glanceId)

but I don't have access to glanceId.

The background of the question is that I want to add the uid to the AppWidgetState as described in this question: How to get the AppWidgetId of a Compose Glance widget?

How can I get the glanceId (e.g. from the appWidgetId that I have access to in the Configure activity) or how else would I achieve this?

Upvotes: 2

Views: 3175

Answers (6)

Karim
Karim

Reputation: 233

I finally solved my own problem a few months later. With version 1.0.0-alpha04 released a month ago, there is a new getGlanceIdBy method.

New method to get GlanceId from an existing appWidgetId or an intent from a configuration activity (Icb70c, b/230391946)

My code now looks like this:

// Try block because getGlanceIdBy throws IllegalArgumentException if no GlanceId is found for this appWidgetId.
try {
    val glanceAppWidgetManager = GlanceAppWidgetManager(context)
    val glanceId: GlanceId = glanceAppWidgetManager.getGlanceIdBy(appWidgetId)
    updateAppWidgetState(context = context, glanceId = glanceId) {
        it[intPreferencesKey("uid")] = uid
    }
    val glanceAppWidget: GlanceAppWidget = GlanceWidget()

    glanceAppWidget.update(context, glanceId)
} catch (e: IllegalArgumentException) {
    Log.d(TAG, "No GlanceId found for this appWidgetId.")
}

Upvotes: 6

DRSK FUN cuts
DRSK FUN cuts

Reputation: 89

If you are trying to get GlanceId inside your GlanceAppWidget class you can use

val glanceId = LocalGlanceId.current 
//You can use this only in @Composable annoted methods. You can get id in composable method

If you are trying to get GlanceId outside or another class you can use

val glanceId = GlanceAppWidgetManager(context).getGlanceIds(BasicGlanceWidget::class.java).last() 
//getGlanceIds is a suspend func so don't forget to use coroutine

Upvotes: 1

Enes Zor
Enes Zor

Reputation: 1190

I am getting the ids this piece of code. May be it works for you.

    val glanceId =
        GlanceAppWidgetManager(context).getGlanceIds(YourAppWidget::class.java).firstOrNull()

Upvotes: 2

mmm111mmm
mmm111mmm

Reputation: 4085

Update your widgets from anywhere where you have a Context:

fun updateWidgets(context: Context) {
  val widgetProvider = YourGlanceWidgetReceiver::class.java
  val comp = ComponentName(context, widgetProvider)
  val ids = AppWidgetManager.getInstance(context)
    .getAppWidgetIds(comp)
  val intent = Intent(context, widgetProvider).apply {
    this.action = AppWidgetManager
      .ACTION_APPWIDGET_UPDATE
    this.putExtra(
      AppWidgetManager.EXTRA_APPWIDGET_IDS,
      ids
    )
  }
  context.sendBroadcast(intent)
}

This will call update() in your GlanceWidgetReceiver which will in turn call your GlanceAppWidget's Content().

Upvotes: 0

PierreBdR
PierreBdR

Reputation: 43264

Ideally, you would attach some information to the state that allows you to identify the state without needing the GlanceId. You could either generate a unique ID that is app specific when rendering the app widget (if you want each widget to be different), or you can rely on some configuration (in which case all widgets with the same configuration would be treated in the same way).

Once this is done, you can use the existing GlanceAppWidget.updateIf to update an app widget with a given state.

If you want some more combine behavior (as you suggest: update the state and then update the app widget), you can check the implementation of GlanceAppWidget.updateIf (which is really 4 lines long and only uses public methods) and adapt it to your exact needs.

Upvotes: 1

Marcel
Marcel

Reputation: 2184

We are looking into this. The best option for now is to use the GlanceAppWidgetManager to retrieve the last GlanceId associated to your GlanceAppWidget using the getGlanceIds(..) method.

That's indeed not ideal, but for the time being it should work.

Upvotes: 2

Related Questions