I am trying to implement inapp-updates, I’ve Activity which has a ViewModel I added a method to it to “checkAppUpdates” which invokes “CheckAppUpdateUseCase” which take AppUpdateManager as a constructor parameter and then calls its checkForAppUpdates which do the actual checking for updates, the implementation needs either an instance of “Activity” or ”ActivityResultLauncher” to be passed to google’s AppUpdateManager’s startUpdateFlow or startUpdateFlowForResult method respectively my problrm is with injecting activity as a constructor parameter to my AppUpdateManager but it is not working, I am getting this build error >
MyApplication_HiltComponents.java:186: error: [Dagger/MissingBinding] @dagger.hilt.android.qualifiers.ActivityContext android.app.Activity cannot be provided without an @Provides-annotated method. public abstract static class SingletonC implements FragmentGetContextFix.FragmentGetContextFixEntryPoint,
Missing binding usage: @dagger.hilt.android.qualifiers.ActivityContext android.app.Activity is injected at com.my.app.AppUpdateManager(activity) com.my.app.AppUpdateManager is injected at com.my.app.CheckAppUpdateUseCase(appUpdateManager) com.my.app.CheckAppUpdateUseCase is injected at com.my.app.MainViewModel(…, checkAppUpdateUseCase, …) com.my.app.MainViewModel is injected at com.my.app.MainViewModel_HiltModules.BindsModule.binds(arg0) @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.my.app.MyApplication_HiltComponents.SingletonC → com.my.app.MyApplication_HiltComponents.ActivityRetainedC → com.my.app.MyApplication_HiltComponents.ViewModelC]
I've an activity like that
@AndroidEntryPoint
class MainActivity : AppCompatActivity(){
private val viewModel by viewModels<MainViewModel>()
...
The viewmodel
@HiltViewModel class MainViewModel @Inject constructor( private val logoutUseCase: LogoutUseCase, private val checkAppUpdateUseCase: CheckAppUpdateUseCase, ...
The use-case
class CheckAppUpdateUseCase @Inject constructor(
private val appUpdateManager: AppUpdateManager){
suspend fun checkForAppUpdates() {
appUpdateManager.checkForAppUpdates()
}
}
The AppUpdateManager
private const val UPDATE_PRIORITY_HIGH = 4
class AppUpdateManager @Inject constructor(private val activity: Activity) {
suspend fun checkForAppUpdates() {
// use the activity here
}
}
and I provide the AppUpdateManager like that
import android.app.Activity
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.qualifiers.ActivityContext
import com.my.app.AppUpdateManager
@Module
@InstallIn(ActivityComponent::class)
object UpdateManagerModule {
@Provides
fun provideActivity(@ActivityContext activity: Activity) = activity
@Provides
fun provideUpdateManager(@ActivityContext activity: Activity): AppUpdateManager {
return AppUpdateManager(activity)
}
}
I tried to inject the Activity directly to isolate the problem and commented the unnecessary code but I got the same error.
The Librarian's answer was helpful and it directed me to think about not using the ActivityContext in the ViewModel, but this SO Answer solved my problem by changing the activity dependency to context and then casting it to activity
class AppUpdateManager @Inject constructor(@ActivityContext private val activityContext: Context) {
And in module
@Provides
fun provideAppUpdateManager(@ActivityContext context: Context): AppUpdateManager =
AppUpdateManager(context
)