androidandroid-sharedpreferencesandroid-livedata

LiveData with shared preferences


I have a settings screen where I am setting some values. When I set those values it gets saved in shared preferences and these values are needed in my request to the network api call as parameters.

Now I can use a listener for shared preferences in my activity then make an api call and get fresh data, but I want to use this with LiveData.

How can I listen for changes in the shared preferences using LiveData and then make the network call using the new parameters.


Solution

  • Java Code by Idish, though he commented here, but not sure, why he didn't add it as answer.

    Pasting the same code below:

    public abstract class SharedPreferenceLiveData<T> extends LiveData<T> {
    
    SharedPreferences sharedPrefs;
    String key;
    public T defValue;
    
    public SharedPreferenceLiveData(SharedPreferences prefs, String key, T defValue) {
        this.sharedPrefs = prefs;
        this.key = key;
        this.defValue = defValue;
    }
    
    private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            if (SharedPreferenceLiveData.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));
        sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
    }
    
    @Override
    protected void onInactive() {
        sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
        super.onInactive();
    }
    public SharedPreferenceLiveData<Boolean> getBooleanLiveData(String key, Boolean defaultValue) {
        return new SharedPreferenceBooleanLiveData(sharedPrefs,key, defaultValue);
    }
    }
    

    SharedPreferenceBooleanLiveData class

    public class SharedPreferenceBooleanLiveData extends SharedPreferenceLiveData<Boolean>{
    
    public SharedPreferenceBooleanLiveData(SharedPreferences prefs, String key, Boolean defValue) {
        super(prefs, key, defValue);
    }
    
    @Override
    Boolean getValueFromPreferences(String key, Boolean defValue) {
        return sharedPrefs.getBoolean(key, defValue);
    }
    
    }
    

    Calling this like the below code mentioned in this link:

     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
     SharedPreferenceStringLiveData sharedPreferenceStringLiveData = new SharedPreferenceStringLiveData(preferences, "cid", "");
     sharedPreferenceStringLiveData.getStringLiveData("cid", "").observe(this, cid -> {
                Toast.makeText(this, "Change in CID "+cid, Toast.LENGTH_SHORT).show();
     });
    

    Again if using a Preference Helper class, the class can be called as below: Just a sample:

    public class PreferenceManager {
    private SharedPreferenceBooleanLiveData sharedPreferenceLiveData;
    
    public SharedPreferenceBooleanLiveData getSharedPrefs(){
            return sharedPreferenceLiveData;
        }
    
    public void setSharedPreferences(String key, boolean value) {
    
            SharedPreferences userDetails = context.getSharedPreferences(APP_PREFERENCE,
                Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = userDetails.edit();
            editor.putBoolean(key, value);
            editor.apply();
            sharedPreferenceLiveData = new SharedPreferenceBooleanLiveData(userDetails,key,value);
        }
    }
    

    And in the activity class call it as below: Create an object:

    SharedPreferenceBooleanLiveData sharedPreferenceLiveData;
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        sharedPreferenceLiveData = preferenceManager.getSharedPrefs();
    }
    

    And observe it as follows:

    sharedPreferenceLiveData.getBooleanLiveData(PreferenceKey.KEY_LOCATION_PERMISSION,false).observe(this,check->{
            if(check){
                setPermissionGranted(check);
            }
        });