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);
});
}