I'm making an android game with levels. I made a Button[][] Array which every Button has setEnabled(false) exept the first one which has been set true due to allow players to start the game and "unlock" other levels. I stored a global Boolean Array with the button enabling state so that every time i enter the "LevelsActivity" i can read the Boolean array and update the buttons states. And all of this works fine.
My question is about how to save this Boolean array so that i can load it after the app closing.
I read about SharedPreferences and i find out some code but i can't implement to my purpose. Furthermore i read that array aren't supported by SharedPreferences and i should convert the array to string but i still can't do it. Thanks in advance
This is my Global class if it could help:
public class Globals extends Application {
private boolean[] array = new boolean[125];
public Globals() {
for (int i = 0; i < 125; i++) {
array[i] = false;
}
array[0] = true;
}
public boolean getData(int i){
return this.array[i];
}
public void setData(int i, boolean value){
this.array[i]=value;
}
}
You can't put a boolean array directly, but you can put a boolean for each level. Something like:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences();
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("level_one", true);
editor.putBoolean("level_two", false);
...
editor.commit();
and then when you get to the activity where you need to check these values you can get them with
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences();
Boolean level_one = prefs.getBoolean("level_one", false);
Boolean level_two = prefs.getBoolean("level_two", false);
...
I'd store it as a string of 0's and 1's in one SharedPrefs, and then read that String back and populate the boolean array based in that.
SharedPreferences preferences =
getApplicationContext().getSharedPreferences("PREFS", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
// Write
boolean[] array = new boolean[125];
StringBuilder builder = new StringBuilder();
for (boolean i : array) {
builder.append(i ? '1' : '0');
}
editor.putString("BOOLEAN_ARRAY", builder.toString()).apply();
// Read
String arrayPrefs = preferences.getString("BOOLEAN_ARRAY",null);
if(!TextUtils.isEmpty(arrayPrefs)){
for(int i = 0; i < array.length;i++){
array[i] = arrayPrefs.charAt(i) == '1';
}
}
You can use gson library to serialize your data and then save it in sharedPref:
Gson gradle dependency
implementation 'com.google.code.gson:gson:2.8.6'
Serializing array
val arrayOfBooleans = arrayOf(false, true, false, true)
// or you could use hashMap which has more readable output after serialization
val mapOfBooleans = mapOf(1 to false, 5 to true)
val serializedJson1 = Gson().toJson(arrayOfBooleans) // [false,true,false,true]
val serializedJson2 = Gson().toJson(mapOfBooleans) // {"1":false,"5":true}
Saving in SharedPreferences
fun saveData(json: String) {
val prefManager = PreferenceManager.getDefaultSharedPreferences(context)
prefManager
.edit()
.putString(KEY_OF_DATA, json)
.apply()
}
companion object {
const val KEY_OF_DATA = "keyOfData"
}
Related
I am facing an issue with saving an object boolean in SharedPreferences. The object (part of ArrayList "questions") contains a boolean "recentAnswer".
If I change the boolean value and want to use it in another activity, the value is still the old one.
Here is my saveData-method from Activity 1:
private void saveData(){
SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String json = gson.toJson(questions);
editor.putString("task list", json);
editor.apply();
}
and here's where I use it in order to save the changed boolean value (Activity 1):
private void checkAnswer(Button answerButton){
if (answerButton.getText().equals(questions.get(currentQuestion).getAnswer1())){
questions.get(currentQuestion).recentAnswer = true;
}
else{
questions.get(currentQuestion).recentAnswer = false;
}
Toast.makeText(this, Boolean.toString(questions.get(currentQuestion).recentAnswer), Toast.LENGTH_SHORT).show();
saveData();
}
Firstly, I load the ArrayList in Activity 2:
private void loadData(){
SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString("task list", null);
Type type = new TypeToken<ArrayList<Question>>(){}.getType();
questions = gson.fromJson(json, type);
if(questions == null){
questions = new ArrayList<>();
}
}
And then I want to get the "recentAnswer" values (Activity 2):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_statistics);
loadData();
for (Question element : questions){
int recentWrong;
if (!element.recentAnswer){
recentWrong++;
}
}
Toast.makeText(this, Integer.toString(recentWrong), Toast.LENGTH_SHORT).show();
}
No matter, how I change the values in Activity 1, in Activity 2 "recentWrong" is always = 0, even though I am accessing the questions.
Don't do this:
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String json = gson.toJson(questions);
editor.putString("task list", json);
Do not do this ever. First off is you are not checking and do not know what the value questions may hold and you also should not save something like that in SharedPrefs.
If you have several questions, then save each question together with its response in SharedPrefs and if you need to save an answer that you want to check against later in code, use string values stored in the res->strings.xml.
If the question is too long, find a way to concat it or use the res->string-arrays.xml and keep the questions there, then reference them from there.
You need to go back a bit and take a look at how to design programs in Java, Kotlin or any language for that matter. This is what comes after you learn programming basics.
I am new to Android App Development and I am supposed to make a TodoList App for a course. But the SharedPreference in my code is not working. I dont know if I'm supposed to use it in a specific way in a specific method like onCreate or onStop.
It is saving the first input the user is entering permanently, but in the same position:
(The "task0" is what I used to track the different variable names I used as argument for "putString" in addStuff method, to avoid replacing values)
It is saving the inputs after that in the same session, but if the user ends that session, all those values after "t" are gone. If the user restarts the app and inputs something else (like "g"), it is saving "g" in that same 3rd position.
I have basic Java knowledge and I tried to understand what is going on using it, but failed. Please let me know where is the mistake and how to use SharedPreferences properly.
public class TodoActivity extends AppCompatActivity {
public ArrayList<String> items;
public ArrayAdapter<String> itemsAdapter;
public ListView list;
public String s;
public EditText taskBox;
public static final String filename = "itemsList";
public TextView text;
public static int counter = 0;//counter starting at 0 no matter what, everytime the app starts
public String newtask= "task";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_todo);
list = (ListView) findViewById(R.id.list1);text = (TextView) findViewById(R.id.text1);
taskBox = (EditText) findViewById(R.id.box);
s = taskBox.getText().toString();
items = new ArrayList<String>();
itemsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
list.setAdapter(itemsAdapter);
//add items to list
items.add("First Item");
items.add("Second Item");
//restore
SharedPreferences sp = this.getSharedPreferences("itemsList", 0);
//checking if it stores the previous values, this gives the last input but not the previous ones after restarting the app
String dummyname = "task";
text.setText(String.valueOf(counter));//since counter is again at
for(int c=0; c<=50; c++){
String num = String.valueOf(c);
dummyname = dummyname + num;
String x = sp.getString(dummyname, "not found");
if (x.equalsIgnoreCase("not found")){
counter=c-1;
break;
} else {
items.add(x);
text.setText(dummyname);
}
}
}
public void addItem(View v){
s = taskBox.getText().toString();
itemsAdapter.add(s);//adding the new task as string
String temp = String.valueOf(counter);
newtask = "task" + temp;
//trying to store the new tasks with different variable names to avoid being replaced
text.setText(newtask);
SharedPreferences sp = this.getSharedPreferences("itemsList", 0);
SharedPreferences.Editor e = sp.edit();
e.putString(newtask,s);
e.apply();
counter++;
}
}
If you have relatively small collection of key-values that you would like to save,
You should use Shared preference API
Read from the shared preference:
Pass the key and value you want to write,create a SharedPreferences.Editor by calling edit() on your SharedPreferences.
Pass key and values you want to save by using this method putInt() ,putString() ,Then call commit() to save the changes. For example:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("KeyName", newHighScore);
editor.commit();
Write from the shared preference:
To retrieve values from a shared preferences file, call methods such as getInt() and getString(),
providing the key for the value you want, and optionally a default value to return if the key isn't present. For example:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt("KeyName", defaultValue);
Two things :
1) To initialize SharedPreferences use :
sharedPreferences = getSharedPreferences("itemsList", Context.MODE_PRIVATE);
2) Where are you calling addItem() method??
The problem is about the Tag you use to save items. See this Line :
dummyname = dummyname + num;
You add item by this format :
task0
task1
task2
but you are getting values in this format
task0
task01
task012
Just change these two line of code :
//dummyname = dummyname + num;
//String x = sp.getString(dummyname, "not found");
String newDummy= dummyname + num;
String x = sp.getString(newDummy, "not found");
I am trying to save an integer value and retrieve the value using a same button using shared preferences.
To be more precise, when i click a button the value should be incremented(i++) and then it should be stored. When i close and open the application, it should retrieve the same value from where i left it. How do i do this?
I am using eclipse.
This works for me
public class OnPreferenceManager {
private SharedPreferences.Editor editor;
private SharedPreferences prefs;
private String startHour = "startHour";
private OnPreferenceManager() {}
private OnPreferenceManager(Context mContext) {
prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
editor = prefs.edit();
}
public static OnPreferenceManager getInstance(Context mContext)
{
OnPreferenceManager _app = null;
if (_app == null)
_app = new OnPreferenceManager(mContext);
return _app;
}
public void setStartHour(int hour){
editor.putInt(startHour, hour);
editor.apply();
}
public int getStartHour(){
int selectionStart = prefs.getInt(startHour, -1);
return selectionStart;
}
}
When you need to set integer just write as below
OnPreferenceManager.getInstance(this).setStartHour(theValueYouWantToStore);
And to retrieve write
OnPreferenceManager.getInstance(this).getStartHour()
You can use shared preferences as below.
//To save integer value
SharedPreferences preference = getSharedPreferences("YOUR_PREF_NAME", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("YOU_KEY",you_int_value);
editor.commit();
//To retrieve integer value
SharedPreferences settings = getSharedPreferences("YOUR_PREF_NAME", 0);
int snowDensity = settings.getInt("YOU_KEY", 0); //0 is the default value
Check this gist https://gist.github.com/john1jan/b8cb536ca51a0b2aa1da4e81566869c4
I have created a Preference Utils class that will handle all the cases.
Its Easy to Use
Storing into preference
PrefUtils.saveToPrefs(getActivity(), PrefKeys.USER_INCOME, income);
Getting from preference
Double income = (Double) PrefUtils.getFromPrefs(getActivity(), PrefKeys.USER_INCOME, new Double(10));
I am creating an app that saves that saves user's previous names. I am using Shared Preferences so when the user kills the app and reopens it the names will still show in the saved Activity. The app currently displays the saved names, but once it's closed and the life cycle is killed, and then restarted the names aren't retrieved.
Code to save the names:
protected void addToSaved(String s){
GlobalList.pref = getApplicationContext().getSharedPreferences("MyPref", Context.MODE_PRIVATE); // 0 - for private mode
SharedPreferences.Editor editor = GlobalList.pref.edit();
if(GlobalList.tagsActive.size() < 6){
GlobalList.tagsActive.addFirst(GlobalList.tagsAvail.removeFirst());
editor.putString(GlobalList.tagsActive.getFirst(), s);
}else{
editor.remove(GlobalList.tagsActive.removeLast());
GlobalList.tagsAvail.add(GlobalList.tagsActive.removeLast());
//adding shared pref
GlobalList.tagsActive.addFirst(GlobalList.tagsAvail.removeFirst());
editor.putString(GlobalList.tagsActive.getFirst(), s); // Storing string value
}
//GlobalList.editor.commit(); // commit changes into sharedpreferences file.
editor.commit();
Code to retrieve and display the names:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_names);
for (int i = 0; i < GlobalList.tagsActive.size(); i++) {
//setting martian name to screen
// getting String
nameTexts[i] = (TextView) findViewById(textId[i]);
//set conditon here so no null pointer
GlobalList.pref = getApplicationContext().getSharedPreferences("MyPref", Context.MODE_PRIVATE); // 0 - for private mode
String s =GlobalList.pref.getString(GlobalList.tagsActive.get(i), "");
nameTexts[i].setText(s);
}
}
}
Code for global list so can be edited across classes:
public class GlobalList {
static LinkedList<String> tagsAvail = new LinkedList<String>();
static LinkedList<String> tagsActive = new LinkedList<String>();
static SharedPreferences pref;
static SharedPreferences.Editor editor;
}
That happens because when the app starts up on onCreate, the length of GlobalList.tagsActive.size() is zero, so the code inside the FOR loop does not execute.
Change your FOR loop for this:
while (true) {
//setting martian name to screen
// getting String
//set conditon here so no null pointer
GlobalList.pref = getApplicationContext().getSharedPreferences("MyPref", Context.MODE_PRIVATE); // 0 - for private mode
String s =GlobalList.pref.getString(GlobalList.tagsActive.get(i), "");
if (s.equals("")){
break; //exits while loop if no more items are found in SharedPref
else{
nameTexts[i] = (TextView) findViewById(textId[i]);
nameTexts[i].setText(s);
}
}
I am using SharedPreference in my Android app to store a string value, but it always takes the defValue from .getString(String key, String defValue), despite having a set value.
Here is my code:
public class AddAlert extends Activity {
[...]
public static final String LAST_ALERT_TIME = "1414931472952";
[...]
public boolean checkIfMoreThanTenMinutesFromLastAlert() {
SharedPreferences lastAlertTimeSettings = getSharedPreferences(LAST_ALERT_TIME, 0);
String lastAlertTime = lastAlertTimeSettings.getString(LAST_ALERT_TIME, null);
double currentDate = new Date().getTime();
if (getDifference(currentDate, Double.valueOf(lastAlertTime))/1000/60>10) {
return true;
} else return false;
}
public double getDifference(double currentDate, double lastAlertDate) {
//milliseconds
double difference = currentDate - lastAlertDate;
return difference;
}
}
The problem is that LAST_ALERT_TIME has a preset value, but it always returns the defValue("null" in this case").
Is there anything wrong I am doing?
Thank you!
before you GET a preference in your app,
make sure you set the source of data
provide a real value for your key that you are getting
PreferenceManager.setDefaultValues(this, R.xml.default_values, false);
SharedPreferences.Editor ed = PreferenceManager.getDefaultSharedPreferences(this).edit();
ed.putString("LAST_ALERT_TIME", getString(R.string.db_app_id));
ed.apply(); // or commit()