Home > OS >  Injecting Context into a Broadcast Receiver using Hilt/Dagger?
Injecting Context into a Broadcast Receiver using Hilt/Dagger?

Time:11-04

I am using context() in my GlanceAppWidget() for tasks like retrieving glanceId and updating app widget state. I am having issue with how I inject the context object.

I would like to use the dagger/hilt framework to inject the context into my GlanceAppWidget() constructor. See MyWidget() below.

However by injecting the context into MyWidget, I then need to pass the context as constructor parameter in MyWidgetReceiver() for val glanceAppWidget. Broadcast receivers are not meant to have constructor arguments so this gives me an Instantiation Exception.

How can I inject context into my GlanceAppWidget? Any help will be much appreciated.

Note: I have also tried using default arguments in MyWidget() to avoid providing context in MyWidgetReceiver but this throws "Type may only contain one injected constructor".

@Singleton
class MyWidget @Inject constructor(
    @ApplicationContext val context: Context
) : GlanceAppWidget() 
@AndroidEntryPoint
@Singleton
class MyWidgetReceiver @Inject constructor(
    @ApplicationContext val context: Context /*<-java.lang.InstantiationException when trying to inject into BroadcastReceiver*/
) : GlanceAppWidgetReceiver() {

    override val glanceAppWidget: GlanceAppWidget
        get() = MyWidget(context)
}

CodePudding user response:

onReceive method of the BroadcastReceiver has the context as its argument. You probably want to bind your widget-creating logic to this method

fun onReceive(context: Context, intent: Intent)

EDIT:

I did not noticed that you are using Glance. Since that, I recommend to stop using context in constructor and instead update glanceId and widget state when you will actually have access to context via some kind of method.

override fun onReceive(context: Context, intent: Intent) {
    glanceAppWidget.update(context)
}

MyWidget:

fun update(context: Context) {
   // do some work
}

In case when you will need update, you will simply send matching intent which will be received by the receiver.

CodePudding user response:

Couple of things:

  1. GlanceAppWidgetReceiver is a BroadcastReceiver thus you can't have constructor parameters. Also it shouldn't be a singleton. BroadcastReceivers are short-term living classes.

  2. You can retrieve the context inside a @Composable function by calling LocalContext.current. Also you can retrieve the glanceId by calling LocalGlanceId.current

Thus you don't need to inject the context in the first place.

  • Related