Android SharedPreferences is reset to default values. After restarting app - java

Sometimes after restarting the app resets the sharedpreferences on devices with API level > 13.
The sharedpreferences are set at the beginning of the app (first activity of the app).
code:
Public void saveCountry(Context context, String countryCode) {
SharedPreferences settingsActivity = context.getSharedPreferences("preferences", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settingsActivity.edit();
editor.putString("key_country", countryCode);
editor.commit();
setDefaultChannels(context);
}
public String getCountry(Context mContext) {
SharedPreferences settingsActivity = mContext.getSharedPreferences("preferences", Context.MODE_PRIVATE);
String country = settingsActivity.getString("key_country", null);
return country;
}
I dont know what im doing wrong and why it is happening. I noticed this specially after receiving a push-notification to a detailactivity.

Are you calling the saving methods at the beginning of your app like this?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
saveCountry();
Because if you are, you are calling it every time at startup, so the country will be overridden with whatever data countryCode equals at startup, which could be nothing. So maybe you should have some code that only calls that on first run.
Here is how I have it implemented in my app.
boolean firstRun;
final SharedPreferences firstRunPref = getSharedPreferences(PREFS_NAME, 0);
firstRun = firstRunPref.getBoolean("firstRun", true);
if(firstRun==true){
saveCountry();
SharedPreferences.Editor editor3 = firstRunPref.edit();
editor3.putBoolean("firstRun", false);
editor3.commit();
}

Related

Problem to remove a backup - ANDROID STUDIO

Intent intent1 = new Intent(Questions.this, Questions.class);
startActivity(intent1);
Little problem in my learning.
Sorry for my frenchglish ^^
A variable changes every time, i press a button, it backs up and assigns it ++.
In the button input if the variable == in table REPONSE.Length, It restarts the activity and it REMOVE the backup.
My problem is that the backup does not remove itself while the activity restarts well.
Every time i support the activity it raises again without being able to start again at stage 0.
int REPONSE[]= new int[5]; //tableau des reponses
int Question = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.questions);
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
Question = sharedPreferences.getInt("num", 0);
cardView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Restart si Question == REPONSE.length
if (Question == REPONSE.length){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("num");
editor.apply();
Intent intent1 = new Intent(Questions.this, Questions.class);
startActivity(intent1);
}
//Sauvegarde de la variable
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("num", Question++);
editor.apply();
//Incrementation +1
Question++;
}
}); }
Thanks in advance:)
According to the documentation remove() removes a value once commit() is called. So you have to change editor.apply() to editor.commit()
//Restart si Question == REPONSE.length
if (Question == REPONSE.length){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("num");
editor.commit(); //editor.apply() won't work
There are 3 points that I wold recommend you:
Point 1:
Try giving your Shared preference a name. Example:
sharedPreferences = getSharedPreferences("sharedPrefName", MODE_PRIVATE);
If you are not giving a name to the shared preference android can fall into ambiguity and create a new Sharedpreference thus not affecting the old one.
Even you are creating a new SharedPreference inside the onClick method(this process is wrong), and there the android system is not being able to understand which Shared Preference to use thus not affecting the sharedpreference data that you want to change.
Point 2:
This not so important as the first one but to change the data of an already existing preference you need not to delete the preference instead just change the value, and it will be updated to your requirement:
sharedPreferences.edit().putInt("num", Question++).apply();
Point 3:
Create SharedPreference object once inside the class where it can
have global scope.
Initialize the SharedPreference only once in an activity inside
onCreate method.
Make your code something like this:
public class MainActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
ConstraintLayout layout;
int Question = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
layout = findViewById(R.id.layout);
sharedPreferences = getSharedPreferences("sharedPrefName", MODE_PRIVATE);
Question = sharedPreferences.getInt("num",0);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sharedPreferences.edit().putInt("num", Question++).apply();
}
});
}
}

RuntimeException when trying to store value fetched from server to sharedpreferences using Asynctask

i am using sharedpreferences to check the app is using for the first time or not.if the app is using for first time registration screen will show , and after that MainActivity will show if registration is completed succussfully or used later . Registration screen is showing when app is runnig for first time but the issue is there in Registering. while calling the shared preferences from MainActivity to insert value in it. and the issue is RuntimeException .this is what i am doing for that...
this is my MainActivity.java
SharedPreferences sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
firtst_time_check();
setContentView(R.layout.available_items);.....}
this is first_time_check()
private boolean firtst_time_check(){
sp = PreferenceManager.getDefaultSharedPreferences(this);
String first = sp.getString("first", null);
if (first == null){
Intent i = new Intent(getBaseContext(), MainActivity.class);
startActivity(i);
}
return false;
}
this is code from Registration screen where exception is throwing in this line MainActivity set = new MainActivity();
JSONArray a = o.optJSONArray("status");
JSONObject obj = a.optJSONObject(0);
String uid = obj.optString("RegistrationID");
MainActivity set = new MainActivity();
set.sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String value = set.sp.getString("RegistrationID", uid);
SharedPreferences.Editor editor = set.sp.edit();
editor.putString("first", value);
editor.commit();
this is what showing in logcat
lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
No, need to use sp from MainActivity by creating object of Activity for saving value in SharedPreferences in Registration screen because PreferenceManager.getDefaultSharedPreferences also return SharedPreferences instance which we can use for saving and key-value in it. Change :
MainActivity set = new MainActivity();
set.sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
to
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext());

Save variable in SharedPreferences based on which button is clicked

Im trying to make an EULA for my app, but there is a different EULA for the different countries we work with.
my idea was that i save a String in SharedPreferences like ZA for South Africa and KE for Kenya. So if you click the South Africa button, it will save the string in SharedPreferences as ZA and the same for Kenya. Once the button has been clicked it the new activity will then load the appropriate EULA by pulling the ZA or KE string from the SharedPreferences. This is what i have at the moment:
Country_select.java
public class country_select extends Activity {
private static final String TAG = "Logs";
public static final String PREFS_NAME = "PrefsFile";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_country_select);
final Button za_button = (Button) findViewById(R.id.btn_za);
Button ke_button = (Button) findViewById(R.id.btn_ke);
Log.i(TAG, "created buttons");
za_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("Country_Selected", "ZA");
editor.commit();
}
});
Log.i(TAG, "set button settings for ZA");
ke_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("Country_Selected", "KE");
editor.commit();
}
});
Log.i(TAG, "set button settings for KE");
}
I may have this totally incorrect but on the layout file there are 2 buttons, one for KE and one for ZA.
I would like it, when the new activity is loaded to read SharedPreferences whether it has ZA or KE? Is what i have done here correct?
Thank you
I think you're better off with using IntentExtras, in your first activity upon clicking the country button store the value inside a variable and when you want to start the new activity pass the data as an intent extra:
Intent intent= new Intent(getActivity(), NewActivity.class);
intent.putExtra("country", countryCode);
startActivity(intent);
And then inside the new activity you can retrieve the value like this:
String countryCode = getIntent().getExtras().getString("country");
In order to maintain Shared preference across the application i use it this way
, take a look
I saved a AppPrefes class as a seprate class in the package
public class AppPrefes {
private SharedPreferences appSharedPrefs;
private Editor prefsEditor;
public AppPrefes(Context context, String Preferncename) {
this.appSharedPrefs = context.getSharedPreferences(Preferncename,
Activity.MODE_PRIVATE);
this.prefsEditor = appSharedPrefs.edit();
}
/****
*
* getdata() get the value from the preference
*
* */
public String getData(String key) {
return appSharedPrefs.getString(key, "");
}
public Integer getIntData(String key) {
return appSharedPrefs.getInt(key, 0);
}
/****
*
* SaveData() save the value to the preference
*
* */
public void SaveData(String Tag, String text) {
prefsEditor.putString(Tag, text);
prefsEditor.commit();
}
public void SaveIntData(String key, int value) {
prefsEditor.putInt(key, value);
prefsEditor.commit();
}
/**
* delete all AppPreference
*/
public void deleteAll() {
this.prefsEditor = appSharedPrefs.edit();
this.prefsEditor.clear();
this.prefsEditor.commit();
}
In your Activity or Fragment were you would like to get or save data just use it like this
Decalre an object for the AppPrefes class
AppPrefes appPref;
Initialize in onCreate
appPref = new AppPrefes(getActivity(), "type name of your preference");
To save data to the preference use
appPref.SaveData("tag_name", "value to be saved);
To get data from the preference
appPref.getData("tag_name");
You can also save Integer values and clear all preference values if necessary just call the apporopriate methods.
Yes, the storing part is correct. Now you will need to access the stored value in your new activity.
Example-
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
String storedCountry = sharedpreferences.getString("Country_Selected"); // could be null value if there is no value stored with Country_Selected tag.

Storing a string into a permenant variable issue

I'am trying to store a string from a variable (NumberString) to another variable (PermenantString)
When the string is entered in to PermenantString, it should be stored permenantly in that variable, until the app is deleted or i specifically create a button to clear that PermenantString variable.
MainAvtivity
public class MainActivity extends Activity {
public final String PermenantString= "";
verified.class
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.verified);
Button VerifyCompleteButton = (Button) findViewById(R.id.VerifyCompleteButton);
VerifyCompleteButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
String NumberString;
String PermenantString;
//TextView NUMView;
TextView NUMView = (TextView) findViewById(R.id.NUMView);
Bundle bundle = getIntent().getExtras();
NumberString= bundle.getString("NumberString");
PermenantString = bundle.getString("PermenantString");
PermenantString= NumberString.toString();
//set String PermenantString= ""; permenantly
NUMView.setText(PermenantString);
//
}
});
You should use preferences or sqlite to store the data. Check the storage options #
http://developer.android.com/guide/topics/data/data-storage.html
Example:
public static final String PREFS_NAME = "MyPrefsFile";
Then
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("key", stringvalue);
editor.commit();
Then to get
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String value = settings.getString("key","defaultstring");
Note that variables are stored in volatile RAM memory. By volatile, I mean that the value is stored only as long as your app is running. This is the very opposite of the permanence that you seem to want.
In order to save a variable that will persist after your app is destroyed, you must use some storage mechanism such as SharedPreferences or a SQLite database. For more information, you should read Storage Options in the Android Developer Guides.

Save little information as setting in android (like first time that app is run)

I want to save a flag for recognizing that my app is run for the first time or not. For this simple job I don't want to create database..
Is there a simple option to do this? I want to save and read little pieces of information only.
Use sharedPreference or files to save the data but better option is sharedPreference.
For Retrieving
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
For Saving
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", true);
editor.commit();
Use SharedPreferences.
SharedPreferences preferences = getSharedPreferences("prefName", MODE_PRIVATE);
SharedPreferences.Editor edit= preferences.edit();
edit.putBoolean("isFirstRun", false);
edit.commit();
A proper way to do this is by using the Android class SharedPreferences which is used for things like this.
Storing Settings
SharedPreferences settings = getSharedPreferences(NAME_OF_PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("appPreviouslyStarted", true);
editor.apply();
Don't forget to apply or your mutations to the settings won't be saved!
You can create multiple settings by using different NAME_OF_PREFERENCES. The settings are stored on the device so will be available after closing the application.
When you try to retrieve NAME_OF_PREFERENCES that is not already created, you create a new one. See more behavior like this here.
apply() versus commit()
You can use editor.apply() as well as editor.commit(), the only difference is that apply() does not return a boolean value with if the edit was successful or not. editor.apply() is therefor faster and more commonly used.
What is MODE_PRIVATE
You can see all about the different modes here. For your case MODE_PRIVATE is fine.
Retrieving settings
SharedPreferences settings = getSharedPreferences(NAME_OF_PREFERENCES, MODE_PRIVATE);
boolean silent = settings.getBoolean("silentMode", false);
When retrieving a settings from a SharedPreferences object you always have to specify a default value which will be returned when the setting was not found. In this case that's false.
I suggest you to go for SharedPreference persistent storage. Its very easy and fast storing/retrival for small amount of information.
See the code to get the value from SharedPreference
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
and to Store value in SharedPreference
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
You can do one class for example:
(like a object for instance)
import android.content.Context;
import android.content.SharedPreferences;
public class SettingsMain {
Context context;
SharedPreferences preferences;
SharedPreferences.Editor editor;
private static final String PREFER_NAME = "settingsMain";
public static final String KEY_VIBRATE = "switchVibrate";
public SettingsMain(Context context) {
this.context = context;
setPreferences();
}
private void setPreferences(){
preferences = context.getSharedPreferences(PREFER_NAME, context.MODE_PRIVATE);
editor = preferences.edit();
}
public void cleanPreferences(){
editor.clear();
editor.commit();
}
public void setStatusVibrate(Boolean status){
editor.putBoolean(KEY_VIBRATE, status);
editor.commit();
}
public Boolean getstatusVibrate(){
return preferences.getBoolean(KEY_VIBRATE, true);
}
}
On your activity call:
public class Home extends AppCompatActivity {
private SettingsMain settings;
private SwitchCompat switchVibrate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.master);
setResources();
getSettings();
}
private void setResources(){
switchVibrate = (SwitchCompat) findViewById(R.id.master_main_body_vibrate_switch);
switchVibrate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
settings.setStatusVibrate(isChecked);
}
});
}
private void getSettings(){
settings = new SettingsMain(this);
switchVibrate.setChecked(settings.getstatusVibrate());
}
}
What about using static variables globally?
You can do this as given in this tutorial. I know handling Content providers are unnecessary just to keep some flags.
Else you can check out Shared Preferences provided by Android. Here's a good example to get started.
This would be my recommendation.

Categories