I am trying to observe data changes in shared preferences. I found this similar question answered by @SimplyProgrammerand followed the steps that he directed and at the end of the day my observer was still not working.
Then I decided to seek some assistance to better understand why.
this is my implementation
I started by implementing the abstract live data
SharedPreferences preference;
String key;
T defValue;
public SharedPrefferenceLiveData(SharedPreferences preference,String key,T defValue){
this.preference=preference;
this.key=key;
this.defValue=defValue;
}
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener=new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(SharedPrefferenceLiveData.this.key.equals(key)){
setValue(getValueFromPreferences(key,defValue));
}
}
};
abstract T getValueFromPreferences(String key, T defValue);
@Override
protected void onActive(){
super.onActive();
setValue(getValueFromPreferences(key,defValue));
preference.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
}
@Override
protected void onInactive() {
preference.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
super.onInactive();
}
}
I then implemented the live data type class
public class LocationLiveData extends SharedPrefferenceLiveData<String>{
public LocationLiveData(SharedPreferences preferences, String key, String string){
super(preferences,key,string);
}
@Override
public String getValueFromPreferences(String key, String defValue) {
return preference.getString(key,defValue);
}
}
I then added this to my Preference management class like so
instantiation and setting getters
private LocationLiveData sharedPreferenceLiveData;
public LocationLiveData getSharedPrefs(){
return sharedPreferenceLiveData;
}
then assigned values like so
public void saveUserLocation(Location location){
...
settings = context.getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
editor = settings.edit();
editor.putString(User_Location, currentLocation);
editor.apply();
sharedPreferenceLiveData=new LocationLiveData(settings,User_Location,currentLocation);
}
then in my activity, I access sharedPreferenceLiveData like this
@Inject
SharedPreference sharedPreference;
...
...
LocationLiveData liveData;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
...
...
liveData=sharedPreference.getSharedPrefs();
...
...
observeMarkerLocation();
}
...
...
...
//the observer
private void observeMarkerLocation() {
if(liveData!=null){
liveData.observe(this,locationString->{
if(locationString!=null){
if(!sharedPreference.getBoolValue(SharedPreference.IS_FOLLOWING_ALERT)){
Gson gson=new Gson();
Type type=new TypeToken<Location>(){}.getType();
Location userLocation=gson.fromJson(locationString,type);
currentLocation=userLocation;
}else{
Gson gson=new Gson();
Type type=new TypeToken<VictimFollowingResponse>(){}.getType();
VictimFollowingResponse victimFollowingResponse=gson.fromJson(locationString,type);
List<Point> points=victimFollowingResponse.getPoints();
List<LatLng> latLngPoints=new ArrayList<>();
for(Point point:victimFollowingResponse.getPoints()){
latLngPoints.add(new LatLng(point.getLat(),point.getLong()));
}
int pointListSize=points.size();
if(pointListSize>0){
victimUser.setLatitude(points.get(pointListSize-1).getLat());
victimUser.setLongitude(points.get(pointListSize-1).getLong());
}
drawPolyLIne(latLngPoints);
}
}
});
}
}
yeah thats it .
in this case, the live data keeps returning null in the activity even after being set in a service.
SharedPreferences pref = PreferenceManager. getDefaultSharedPreferences(getContext()); int data = pref. getInt("key",-1); then data will be -1 if the preference value for "key" doesn't exist.
Android Shared Preferences Project Code The MainActivity. java file is used to save and retrieve the data through keys.
SharedPreferences are stored in an xml file in the app data folder, i.e. SharedPreferences added during runtime are not stored in the Eclipse project. The default shared preferences file would actually be: /data/data/<package>/shared_prefs/<package>_preferences. xml .
I think that your code is too complicated. You can simply listen for SharedPreferences changes, using registerOnSharedPreferenceChangeListener()
listener, when your app is turned on.
public class MyApplication extends Application {
private static MyApplication singleton;
public SharedPreferences preferences;
public static MyApplication getInstance() {
return singleton;
}
@Override
public void onCreate() {
super.onCreate();
singleton = this;
preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.registerOnSharedPreferenceChangeListener(listener);
}
private SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//do your code here
}
};
public void unregisterListener() {
preferences.unregisterOnSharedPreferenceChangeListener(listener);
}
}
It overrides an application class, but you can also use this in any activity, but like docs say
Caution: The preference manager does not currently store a strong reference to the listener. You must store a strong reference to the listener, or it will be susceptible to garbage collection. We recommend you keep a reference to the listener in the instance data of an object that will exist as long as you need the listener.
In my example, you should also override an application tag in manifest file
<application
android:name=".MyApplication"
>
</application>
And remember to unregister listener in any activity, before you'll exit an app
@Override
protected void onPause() {
MyApplication.getInstance().unregisterListener();
super.onPause();
}
If you have your own preference file, just change
preferences = PreferenceManager.getDefaultSharedPreferences(this);
to
preferences = getSharedPreferences("pref_filename", MODE_PRIVATE);
To access that preferences, you no need any reference to it. You can get instance of sharedpreferences file in any activity you want. That will be work, because interface will listen for any changes in preferences file. Note that, if you'll pass a key with the same value which is already contained, listener doesn't recognize that as change. So, you can change int value eg. from 2 to 3, and it will work, but from 2 to 2 won't work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With