Android Activity not saving preferences? - java

I have a Settings activity in my android application which purpose is to save preferences upon an item selection. My problem is, my settings don't get saved. The following method is called every time a user selection is made:
public void savePreferences()
{
defaultVolumeUnit = MySingleton.getInstance().getDefaultVolumeUnit();
defaultPressureUnit = MySingleton.getInstance().getDefaultPressureUnit();
defaultTempUnit = MySingleton.getInstance().getDefaultTempUnit();
settings = getSharedPreferences(SettingsTAG, 0);
Editor editor = settings.edit();
editor.putInt("selectVolume", defaultVolumeUnit);
editor.putInt("selectPressure", defaultPressureUnit);
editor.putInt("selectTemperature", defaultTempUnit);
editor.commit();
}
I also use the following code in my MAIN activity where all the settings get restored upon start up:
public void restoreValues()
{
settings = getSharedPreferences(SettingsTAG, 0);
int SelectedVolume = settings.getInt("selectVolume", 0);
int SelectedPressure = settings.getInt("selectPressure", 0);
int SelectedTemperature = settings.getInt("selectTemperature", 0);
// Necessary assignments here...
}
I use global variables throughout my whole application and those get saved but the settings do not. I'm positive that both savePreferences() and restoreValues() method gets called but whatever the user had selected doesn't get saved.
In other words, nothing gets saved/restored. I don't know what I'm doing wrong but this issue has been driving me nuts. This used to work for me before but I'm doing a Settings UI revamp and the same code suddenly isn't working...
Any help please?

Think you should be doing this in your activity:
private SharedPreferences prefSettings;
public void restoreValues()
{
prefSettings = PreferenceManager.getDefaultSharedPreferences(this);
int SelectedVolume = prefSettings.getInt("selectVolume", 0);
int SelectedPressure = prefSettings.getInt("selectPressure", 0);
int SelectedTemperature = prefSettings.getInt("selectTemperature", 0);
// Necessary assignments here...
}
In your method that I've noticed, your parameters do not look right actually...why are you using SettingsTAG, with 0 as parameters to the getSharedPreference method? Is your activity extending PreferenceActivity? You should be using the context.
public void savePreferences()
{
defaultVolumeUnit = MySingleton.getInstance().getDefaultVolumeUnit();
defaultPressureUnit = MySingleton.getInstance().getDefaultPressureUnit();
defaultTempUnit = MySingleton.getInstance().getDefaultTempUnit();
//settings = getSharedPreferences(SettingsTAG, 0);
settings = PreferenceManager.getDefaultSharedPreferences(context); // Notice CONTEXT!
Editor editor = settings.edit();
editor.putInt("selectVolume", defaultVolumeUnit);
editor.putInt("selectPressure", defaultPressureUnit);
editor.putInt("selectTemperature", defaultTempUnit);
editor.commit();
}
Edit:
If you want to debug it, it might be better to do it this way:
public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener{
private static final String TAG = "PreferencesActivity";
///.... code....
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
Log.d(TAG, "onSharedPreferenceChanged() - key = " + key);
// Yup! The key within the shared preferences was changed... inspect 'em via Log!
}
The reason: you're "listening" on the changes whenever its made to confirm that you are indeed saving the preferences. When you're done with debugging, be sure to take out the Log calls so that it does not appear in the logcat.

Related

Save string/EditText in memory android studio

I have a problem with save the value of string or editText in java android. When I redirect from FirstActivity to Second and return after it to First, I need that a String that i fill earlier stay in the place that I wrote it. (Like a cookies in js).
You could use shared preferences for this process.
In that case, Best practise to create SharedPreference and for global usage, you need to create a global class like below:
public class PreferenceHelper {
private final SharedPreferences mPrefs;
public PreferenceHelperDemo(Context context) {
mPrefs = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 -for private mode
}
private String PREF_Key= "Key";
public String getKey() { // To retrieve data
String str = mPrefs.getString(PREF_Key, null);
return str;
}
public void setKey(String pREF_Key) { // To store and edit Data
Editor mEditor = mPrefs.edit();
mEditor.putString(PREF_Key, pREF_Key);
mEditor.commit();
}
public void clearData(string pREF_Key){ // To delete data
editor.remove(pREF_Key);
editor.commit();
}
}
Then you could use these functions with global class in your activity class to store, retrieve and delete the shared preference data.
Hope this will solve your problem!

How to save a highScore on libGDX

I want to save a highScore in my game made with libGDX.
I tried to use this tutorial :
http://niklasnson.com/programming/network/tips%20and%20tricks/2017/09/15/libgdx-save-and-load-game-data.html
There is my code :
GameData.class :
public class GameData {
private static double highScore;
public static double getHighScore() {
return highScore;
}
public static void setHighScore(double hs) {
highScore = hs;
}
}
PlayState.class :
#Override
public void render(SpriteBatch sb) {
[...]
if(GameData.getHighScore() < score) {
GameData.setHighScore(score);
}
[...]
sb.end();
}
MenuState.class :
public class MenuState extends State {
private BitmapFont font = new BitmapFont();
private String HS = String.valueOf(GameData.getHighScore());
DecimalFormat df = new DecimalFormat("#.#");
#Override
public void render(SpriteBatch sb) {
sb.begin();
[...]
font.draw(sb, "Score : " + HS, 20, 400);
sb.end();
}
}
Unfortunately, my highscore is reset each time a start a new game.
Where is my mistake ? I hope my question is not too stupid and I not forget something in my code here. Please forgive me in that case.
Thank you very much in advance.
Best regards,
Tenecifer
You are never saving the highscore, you just store it inside of a variable.
You are using a static variable but these are not saved after restarting your program.
I think LibGDX Preferences is that what you're searching for.
You can read about it here in their wiki.
Update your setHighscoreMethod:
First put in this line:
Preferences prefs = Gdx.app.getPreferences("My Preferences");
After that you can start storing your highscore, e.g.:
prefs.putInteger("highscore", 10);
After editing make sure to save:
prefs.flush();
You will also have to update the getHighscore method.
To read the saved highscore just call:
prefs.getInteger("highscore", 0);
Then 0 is the value that should be returned when no highscore is saved yet.
Actually you are not persisting highScore anywhere outside of your application instance context. Such private field as in your GameData will be destroyed as soon as you will close the game. Think about Word document window on your PC and what will happen if you will suddenly turn off your computer - it will dissapear, with the content, after reboot unless you will save it to the HDD
To save object to the persistent memory in LibGDX you can use Preferences
Preferences prefs = Gdx.app.getPreferences("My Preferences");
// Persist some value
prefs.putString("name", "Donald Duck");
prefs.flush();
// And load it after application restart (or event without restart)
String name = prefs.getString("name", "No name stored"); // 'No name stored' is default value in case such key does not exist
You can also implement some cloud service to keep your game state (and even share it between devices) like Saved Games from Google Services or App42 API from Shephertz (creators od AppWarp)

SharedPreferences does not return the default value

I have a sharedpreferences and I have created a method for it to be checked if it is the user's first time in the app. But it always returns the opposite of the default value.
My code:
public static Boolean getFirstOnApp(Context context) {
SharedPreferences pref = context.getSharedPreferences(LOGIN_PREFS_NAME, Context.MODE_PRIVATE);
return pref.getBoolean(KEY_FIRST_TIME_ON_APP, true);
}
Is always returns false.
I call it on my controller:
if (SaveSharedPreferences.getFirstOnApp(context)) {
fabAtivaMapeamento.performClick();
SaveSharedPreferences.setFirstOnApp(context, false);
}
SaveSharedPreferences.setFirstOnApp(context, false); has never been called before. It is only changed within this If
I already uninstalled the app, forced it to stop, cleared data and cache.
How to solve?
use like this to check if it's first time or not
SharedPreferences pref = getSharedPreferences(LOGIN_PREFS_NAME, Context.MODE_PRIVATE);
if (pref.getBoolean(KEY_FIRST_TIME_ON_APP, false)) {
//in here it's not for first time
} else {
//in here it's first time
}
Edit - Check if the following works.
public static Boolean getFirstOnApp(Context context) {
SharedPreferences pref = context.getSharedPreferences(LOGIN_PREFS_NAME, Context.MODE_PRIVATE);
//Check if the shared preference key exists.
//This way, you can determine if the fault is here or elsewhere.
if (pref.contains(KEY_FIRST_TIME_ON_APP)) {
return pref.getBoolean(KEY_FIRST_TIME_ON_APP, true);
} else {
return true;
}
}
Check if you've set your application to allow backup in the manifest android:allowBackup="true".
Set it as false, uninstall and then reinstall the app.
android:allowBackup=“false”
In case that doesn't fix the issue, then try setting the following in your manifest, uninstalling the app and then reinstalling it.
android:fullBackupContent="false"

SharedPreferences, Singleton Class - What should you use for calling, editing, saving and recalling two integer values

My app will carry two scores the entire time, calling them, adding to them, saving them, and later calling them back again for other functions and editing. What is the best method for this? These will be the only numbers needed throughout the app.
All I am looking for is the most efficient option I should implement. And if possible a simple example of making, editing, saving and recalling. Thank you.
I suggest using SharePreferences because you are only need to store very small data.
Hint:
synchronized void saveScores(final Context contex, final String scoreOneKey, final String scoreTwoKey, final Integer scoreOne, final Integer scoreTwo){
final SharedPreferences sharedPreferences = context.getSharedPreferences("user.score.key", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS)
final SharedPreferences.Editor preferencesEditor = sharedPreferences.edit();
preferencesEditor.putInt(scoreOneKey, scoreOne);
preferencesEditor.putInt(scoreTwoKey, scoreTwo);
preferencesEditor.commit();
}
Things to Note here are:
You are method must synchronized as multiple threads can access the game score.
Notice the sharedPreference access controls (MODE_PRIVATE | MODE_MUTI_PROCESS) that tells the OS that this sharedPreference is not accessible by other apps but at same time it is possible to access it from multiple process of your app ( if you can even encrypt the scores before saving them.)
UpdatedYou can use SharedPreferences To save Scores When you will call getFirstScore() first Time it will return 0 as the variable is not yet created and then you can call setFirstScore() to save it.
public class ScoreDatabase{
private Context context;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
public ScoreDatabase(Context context){
this.context=context;
pref = context.getSharedPreferences("MY_PREFS", Context.MODE_PRIVATE);
editor = pref.edit();
}
public int getFirstScore() {
return pref.getInt("FIRST_SCORE", 0);
}
public int getSecondScore() {
return pref.getInt("SECOND_SCORE", 0);
}
public void setFirstScore(int score) {
editor.putInt("FIRST_SCORE", score);
editor.commit();
}
public void setSecondScore(int score) {
editor.putInt("SECOND_SCORE", score);
editor.commit();
}
}
Now make instance of this class and use anywhere you want just pass getApplicationContext() in the constructor
//In your MainActivity class
ScoreDatabase scoreDatabase=new ScoreDatabase(getApplicationContext());
//call set function when you want to set score
scoreDatabase.setFirstScore(10);
scoreDatabase.setSecondScore(20);
//Call get function when you want to get score
int firstScore=scoreDatabase.getFirstScore();
int secondScore=scoreDatabase.getSecondScore();

Unable to fetch SharedPreferences

I'm trying to get familiar with using SharedPreferences, by building a simple test app where I store and retrieve user preferences by using a class that extends 'PreferenceActivity'.
The problem is that every time I shut down the app and start it again I'm unable to load the SharedPreferences values that I earlier selected.
In the MainActivity's onCreate method I am first calling a method 'loadPreferences', then creating an ImageView and a button.
I assigned onclick listener to the button that creates and starts a new intent.
...onClick(View v){
Intent intent = new Intent(MainActivity.this, MyPrefsActivity.class);
startActivity(intent);
}
In MyPrefsActivity class I have a ListPreference that has a 'Preference.OnPreferenceChangeListener'.
... {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
imageNumber = Integer.parseInt(newValue.toString());
return true;
}
};
Upon return from MyPrefsActivity to MainActivity in the 'onResume':
protected void onResume() {
super.onResume();
savePreferences();
loadPreferences();
}
private void savePreferences(){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("imageNumber", MyPrefsActivity.imageNumber);
editor.apply();
}
private void loadPreferences (){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
int imageNumb = prefs.getInt("imageNumber", 0);
switch (imageNumb){
case 0:
imageView.setImageResource(R.mipmap.image1);
break;
case 1:
imageView.setImageResource(R.mipmap.image2);
break;
case 2:
imageView.setImageResource(R.mipmap.image3);
break;
default:
imageView.setImageResource(R.mipmap.image4);
}
}
When 'loadPreferences' is called for the first time upon startup, 'imageNumb' allways has a value 0, instaed of the value that I assigned to on previous run in method 'savePreferences'.
I noticed that after startup when I enter 'MyPreferencesAction' for the first time and open the ListPreferences, the checkbox that I selected on the last run is already selected for me. It seems like my selection is saved but when I try to load SharedPreferences am I messing up something???
You have to save your preferences in onPause event. Right now you are saving it in onResume when values you want are no longer there.
#Override
protected void onPause(){
super.onPause();
savePreferences();
}
#Override
protected void onResume() {
super.onResume();
loadPreferences();
}
There is another issue with your code. You are saving preferences in MainActivity, but you are changing them in MyPrefsActivity. That will not work. You have to save changes to the preferences in MyPrefsActivity, use above load/save pattern in there too. If you don't have any preference changes happening in MainActivity, you can safely omit calling savePreferences from it.
Depending on MyPrefsActivity declaration calling MyPrefsActivity.imageNumber from MainActivity may not be safe, you will have to change that code too. Like I said, most likely you don't need it at all in MainActivity (if you saving are only preferences values that are set in MyPrefsActivity) and that should be part of MyPrefsActivity.
Also Preference.OnPreferenceChangeListener is probably redundant since it's main usage is to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value.
I realized there was a lot of needless complexity in my code. So I got completely rid of the method savePreferences(). Instead i simplified the PreferenceChangeListeners method onPreferenceChange(...):
This seems to me to be the most simplest way to update SharedPreferences when using PreferenceActivity.
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.getEditor().
putInt("imageNumber", Integer.parseInt(newValue.toString())).apply();
return true;
}
Now I save the SharedPreferences manually, only when 'onPreferenceChange' is called. Not on 'onResume', 'onStop', 'onRestart' or on 'onPause'.
Please inform me if this is a bad way to change SharedPreferences.
Quoting Dalija Prasnikar: "reference.OnPreferenceChangeListener is probably redundant since it's main usage is to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value."
If you understood you correctly Dalija, there is a 'onPreferenceChange(...)' like method that does the job but does not have a boolean return value but void? I was not able to find any examples, could you please show or point to an examle?

Categories