1

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?

Karim
  • 73
  • 8

6 Answers6

4

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.")
}
Karim
  • 73
  • 8
2

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.

Marcel
  • 2,094
  • 3
  • 23
  • 37
  • let's say I have a widget configure activity and I am getting widget id in the intent like this `intent?.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID` and now I would like to figure out which glance id is the same as that widget , this is internal in glance !! I want to update the widget but I don't know which glance id to update so now I have to update all the widgets with glance ids in getGlanceIds – Waqas Tahir Feb 15 '22 at 19:51
  • There is indeed a method missing for the config activity, for the time being you can rely on the order of getGlanceIds, the last one will be the last placed. GlanceId is an internal impl detail and subject to change, that's why it's not exposed. Use the state to store any identifier in the widget instance during the config activity. That will allow you to distinguish instances anywhere else in your app – Marcel Jun 08 '22 at 03:39
2

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

    val glanceId =
        GlanceAppWidgetManager(context).getGlanceIds(YourAppWidget::class.java).firstOrNull()
Enes Zor
  • 973
  • 8
  • 14
1

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.

PierreBdR
  • 42,120
  • 10
  • 46
  • 62
1

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
DRSK FUN cuts
  • 69
  • 1
  • 5
0

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().

mmm111mmm
  • 3,607
  • 4
  • 27
  • 44
  • 2
    We don't recommend to use broadcast events to update Glance app widgets. Instead use the update methods in GlanceAppWidget https://developer.android.com/reference/kotlin/androidx/glance/appwidget/GlanceAppWidget#update or https://developer.android.com/reference/kotlin/androidx/glance/appwidget/package-summary#updateall – Marcel Jan 11 '22 at 08:42
  • I can't access the GlanceAppWidget from the activity/application -- no? – mmm111mmm Jan 11 '22 at 19:56
  • 1
    Yes, you can create an instance of your GlanceAppWidget implementation and call update(..). See my answer to figure out how to get the GlanceId – Marcel Jan 12 '22 at 12:37