Home > Software engineering >  Saving settings data with shared preferences and using in another activity
Saving settings data with shared preferences and using in another activity

Time:06-25

I'm currently building a quiz app and trying to add Settings activity in which the user will be able to manage some game parameters like sound(using a toggle button) or game time. I tried implementing it using shared preferences but something went wrong: The state of toggle button is not saved after exiting the activity and seems that the shared preferences functionality isn't working correctly either. Will be really happy if someone knows how to fix this, or how to build this correctly. Here is my code:

Settings activity:

SwitchCompat switchButton;
    ImageView imageViewOn;
    private Context mContext;

public Settings(){}

public Settings(Context mContext) {
    this.mContext = mContext;
}


private String soundState;

public static final String PREFERRENCE = "shared_prefrence";
//public static final boolean TOGGLE_STATE = false;
public static final String SOUND_STATE = "sound state";
public static final String PREFERRENCE_SOUND_ON = "sound_on";
public static final String PREFERENCE_SOUND_OFF = "sound_of";

public String getSoundState() {
    return soundState;
}

public void setSoundState(String soundState) {
    this.soundState = soundState;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_settings);

    switchButton = findViewById(R.id.switchButton);
    imageViewOn = findViewById(R.id.sound_on);
    loadSound();
            
switchButton.setOnCheckedChangeListener((compoundButton, b) -> {
if(compoundButton.isChecked()){
            soundState = PREFERENCE_SOUND_OFF;
            updateSoundState(soundState);
            imageViewOn.setImageResource(R.drawable.sound_off);


    }
    else{
        soundState = PREFERRENCE_SOUND_ON;
        updateSoundState(soundState);
        imageViewOn.setImageResource(R.drawable.sound_on);
    }
});
}

private void updateSoundState(String soundState) {
    SharedPreferences sharedPreferences = getSharedPreferences(PREFERRENCE,MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(SOUND_STATE,soundState);
    editor.apply();
}

private void loadSound() {
    SharedPreferences sharedPreferences = getSharedPreferences(PREFERRENCE,MODE_PRIVATE);
    sharedPreferences.getString(SOUND_STATE, PREFERRENCE_SOUND_ON);
}

Quiz activity (where sound cues are triggered) adding the relevant code, otherwise it will be extremely long. If something is missing please comment, I'll add:

 private  Settings settings; 
 private PlayAudioForAnswers playAudioForAnswers;// class which plays audio


protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quiz);
        setupUI();

        loadPreferences();

        playAudioForAnswers = new PlayAudioForAnswers(this);

    }

private void setupUI(){
            settings = new Settings(this);
    }


`private void loadPreferences()`
{
    
SharedPreferences sharedPreferences = getSharedPreferences(settings.PREFERRENCE, MODE_PRIVATE);
                String sound = sharedPreferences.getString(settings.SOUND_STATE,settings.PREFERRENCE_SOUND_ON);
settings.setSoundState(sound);
 }

if(settings.getSoundState().equals(settings.PREFERRENCE_SOUND_ON))
            playAudioForAnswers.setAudioforAnswer(FLAG);
 // playing the sound cue if the state is on

CodePudding user response:

There is wrong order in your code. First, you should change the sound state and next save it.

    soundState = PREFERENCE_SOUND_OFF;
    updateSoundState(soundState);

instead

    updateSoundState(soundState);
    soundState = PREFERENCE_SOUND_OFF;

Also you didn't invoke after

    soundState = PREFERRENCE_SOUND_ON;;

CodePudding user response:

Another Working Good Practice

You can separate Pref from an activity :

1- SharedPrefsHelper

import android.content.Context;
import android.content.SharedPreferences;    
import static android.content.Context.MODE_PRIVATE;

/**
 * @author Islam
 * @date 10/11/2018
 */

public class SharedPrefsHelper {

    SharedPreferences mSharedPreferences;

    private static final String MY_PREFS = "YOUR_APP";
    
    public SharedPrefsHelper(Context context) {
        mSharedPreferences = context.getSharedPreferences(MY_PREFS, MODE_PRIVATE);
    }

    private static SharedPreferences getPref(Context context) {
        return context.getSharedPreferences(MY_PREFS, Context.MODE_PRIVATE);
    }

    public void clear(Context context) {
        getPref(context).edit().clear().apply();
    }
    
    /**
     * set Load all tasks
     *
     * @param isLoadAllTasks
     */
    public void setIsLoadAllTasks( boolean isLoadAllTasks) {
        mSharedPreferences.edit().putBoolean(Constants.LOAD_ALL_TASKS, isLoadAllTasks).apply();
    }

    /**
     * get Scanner Scanning
     *
     * @return
     */
    public boolean getIsLoadAllTasks() {
        return mSharedPreferences.getBoolean(Constants.LOAD_ALL_TASKS,false);

    }
    
    //endregion

}

Then create DataManger Class to be a layer between view and data source (DB || Pref) .

2- DataManager

/**
 * @author Islam
 * @date 14/2/2020
 */
public class DataManager {

    private static final String TAG = "DataManager";

    private SharedPrefsHelper mSharedPrefsHelper;

    public DataManager(SharedPrefsHelper sharedPrefsHelper) {
        mSharedPrefsHelper = sharedPrefsHelper;
    }

    //region Settings

    /**
     * set Is Load Tasks
     *
     * @param isLoadTasks
     */
    public void setIsLoadAllTasks( boolean isLoadTasks) {
        mSharedPrefsHelper.setIsLoadAllTasks(isLoadTasks);
    }

    /**
     * get Is Load Tasks
     *
     * @return
     */
    public boolean getIsLoadAllTasks() {
        return mSharedPrefsHelper.getIsLoadAllTasks();
    }
    
    //endregion

}

3- Setting Activity

call this in OnCreate

 @Override
    protected void initUIAndActions() {
        // fetch current status 
        binding.switchLoadAll.setChecked(dataManager.getIsLoadAllTasks());
        // checking Listener
        binding.switchLoadAll.setOnCheckedChangeListener((buttonView, isChecked) -> {
            //save is Load all Tasks to Prefs
            dataManager.setIsLoadAllTasks(isChecked);
        });

    }
  • Related