I'm building a location app where I display background locations from a Room database in my MainActivity. I can get a ViewModel by calling
locationViewModel = ViewModelProviders.of(this).get(LocationViewModel.class);
locationViewModel.getLocations().observe(this, this);
Periodic background locations should be saved to the Room database when I receive location updates via a BroadCastReceiver. They should be saved by calling locationViewModel.getLocations().setValue()
public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {
static final String ACTION_PROCESS_UPDATES =
"com.google.android.gms.location.sample.backgroundlocationupdates.action" +
".PROCESS_UPDATES";
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PROCESS_UPDATES.equals(action)) {
LocationResult result = LocationResult.extractResult(intent);
if (result != null) {
List<Location> locations = result.getLocations();
List<SavedLocation> locationsToSave = covertToSavedLocations(locations)
//Need an instance of LocationViewModel to call locationViewModel.getLocations().setValue(locationsToSave)
}
}
}
}
}
Question is how should I get the LocationViewModel instance in a non-activity class like this BroadcastReceiver? Is it correct to call locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class)
where context is the context that I receive from onReceive (Context context, Intent intent)
of the BroadcastReceiver?
After getting the ViewModel, do I need to use LiveData.observeForever and LiveData.removeObserver since the BroadcastReceiver is not a LifecycleOwner?
Question is how should I get the LocationViewModel instance in a non-activity class like this BroadcastReceiver?
You shouldn't do that. Its bad design practice.
Is it correct to call locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class) where context is the context that I receive from onReceive (Context context, Intent intent) of the BroadcastReceiver?
No. It won't help
You can achieve your desired outcome as follows:
Separate your Room DB operation from ViewModel
in a separate singleton class. Use it in ViewModel
and any other place required. When Broadcast is received, write data to DB through this singleton class rather than ViewModel
.
If you are observing for the LiveData
in your Fragment, then it will update your views too.