I have a probleme here.
I don't know how to read all values of a SharedPreferences for one particular key.
Actually I'm trying to write an Arraylist in preferences , then read it.
Let me explain with some code, Here is my methods for write in preferences :
fun writeArrayOnPreferences(key: String?, array: ArrayList<String>, c:Context) {
val preferences = c.getSharedPreferences(
c.getString(key), Context.MODE_PRIVATE)
with(preferences.edit()) {
for (value in array) {
putString(key, value)
}
commit()
}
}
My writing code works , it's persistent , but I don't really understand how to READ this Arraylist from preferences.
I tried a lot of things to read this but it show me only the last element wrote in preferences
I really want you to understand that I want multiple values for a specific key
This is a quick example based on Nabin Bhandari's answer
fun writeArrayOnPreferences(key: String, array: ArrayList<String>, c:Context) {
val jsonString = Gson().toJson(array)
pref.edit().putString(key, jsonString).commit()
}
fun readArrayFromPreferences(key: String, c: Context): ArrayList<String> {
val jsonString = pref.getString(key)
val array = Gson().fromJson(jsonString, ArrayList<String>()::class.java)
return array
}
ok here how it is! If you want multiple data against one key in share pref editor then SET is your solution as After API 11 the SharedPreferences Editor accept Sets. You could convert your List into a HashSet or something similar and store it like that When your read it back, convert it into an ArrayList, sort it if needed and you're good to go.
//Set the values
val yourSet = HashSet<String>()
set.addAll(listOfExistingScores)
yourPrefEditor.putStringSet("key", yourSet)
yourPrefEditor.commit()
//Retrieve the values
val yourSet = yourPref.getStringSet("key", null)
SOLUTION NUMBER 2
would be like serializing the ArrayList and passing it! but there can be a catch if any value in your array does posses any rule that can't be Parced it will crash!
For More check this Thread this is in java but it will help tell you more!
You cannot simply loop values in an ArrayList put them in the preferences using same key for all values and expect to retrieve the ArrayList back.
You can convert the 'ArrayList' in JSON format and store it in SharedPreferences. Then to parse the JSON string to get the ArrayList.
You can make this process easier with the help of a library called Gson.
Try this:
with(preferences.edit()) {
var s = ""
for (value in array) {
s = s + value + ","
}
putString(key, value)
commit()
}
your array will be saved like comma separated values which when read back in a string, by using the split function will become an array.
Related
I was trying to store a MutableMap in shared preferences so I could retrieve it later, but my app is crashing when retrieving and casting the mutableMap.
First I initialized the map and filled it with values
val mapYearMonths: MutableMap<Int, Map<Int, Map<Int, Map<Map<String, Int>, Int>>>> =
HashMap<Int, Map<Int, Map<Int, Map<Map<String, Int>, Int>>>>()
Then I stored it, which seems to work correctly:
val stepsRecord: String = Gson().toJson(mapYearMonths)
val editor = sharedPreferences.edit();
editor.putString("stepsRecord", stepsRecord);
editor.commit();
And finally I retrieved it, which crashes at line 3
val mapYearMonthsString: String = sharedPreferences.getString("stepsRecord", "0")!!
val mapYearMonthsAny: MutableMap<*, *>? =
Gson().fromJson(mapYearMonthsString, MutableMap::class.java)
return mapYearMonthsAny as MutableMap<Int, Map<Int, Map<Int, Map<Map<String, Int>, Int>>>>
This is the error I get:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.walker/com.example.walker.MainActivity}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 2 path $
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3308)
Any clue on what I could be doing wrong? I tried looking up but couldn't find anything on this. What am I doing something wrong? Should I use another method to store the data? Thanks everyone for the help in advance!
"0" is not a JSON object and cannot be parsed as a MutableMap. Use a default value that can be parsed as a MutableMap, such as "{}" for an empty map.
Should I use another method to store the data?
Possibly, but we do not know how you are using this data, how big this Map is, why you chose SharedPreferences in the first place, etc.
how can i change item's data type in arrays or lists in kotlin ?
i found a usual way but i need an easier and faster and better way to change data type of an array :)
fun typeChanger (data:MutableList<Number>): DoubleArray {
val result = mutableListOf<Double>()
for (i in data.iterator()){
result.add(i.toDouble())
}
return result.toDoubleArray()
}
val x = mutableListOf<Number>(+1,+1,-1,-1)
val xx:DoubleArray = typeChanger(x) // It works but i need an easier and faster and better way :)
Array map is your friend. You could keep your function and simplify, or remove it completely as below:-
val xx = x.map { it.toDouble() }
Once it's a list of doubles, you can then leave as a list or use .toDoubleArray() if you need an array.
I have an array of EditTexts that I would like to get converted into an Array of Strings containing the input values of each of the EditTexts. Here is my code:
val textFields = arrayOf<EditText>(dialogView.findViewById(R.id.et_name),
dialogView.findViewById(R.id.et_address), dialogView.findViewById(R.id.et_phoneNo),
dialogView.findViewById(R.id.et_amount), dialogView.findViewById(R.id.et_remark))
How do I get a String Array of the values of the EditTexts with minimal code?
Edit: Basically I want to fit the code as an argument in a function. I would prefer to have it done without using a for-loop. Perhaps an inline function that would give out an array transforming (as given in the function block) each element (EditText) of the original one to a string. I couldn't find any method so far (although it might turn out to be something obvious).
I also need to use it as a vararg parameter.
Todo this you have to map it into a string array by doing the following:
val newTextFieldStringArray = textFields.map { it.text.toString() }
Log.e("TEST", newTextFieldStringArray.toString()) // print it out
Note:
The map function returns a List. If you'd like to use it as a vararg parameter, you can achieve that using toTypedArray() and a spread operator *. Code As follows:
val varargArray = textFields.map { it.text.toString() }.toTypedArray()
myFunction(*varargArray)
private fun myFunction(vararg list: String) {}
I want to store an ArrayList<class> in shared preference. But the error showed up in editor3.putString("Array", nama);. I guess the error caused by putString. What sould i do?
Should I used another method to storing arraylist ?
ArrayList<Class> nama = new ArrayList<Class>(9);
nama.add(dragsandal.class);nama.add(Terimakasih.class);
nama.add(Ludah.class);
nama.add(Permisi.class);
nama.add(Tolong.class);
nama.add(Maaf.class);
SharedPreferences pref3 = getApplicationContext().getSharedPreferences("Array", MODE_PRIVATE);
SharedPreferences.Editor editor3 = pref3.edit();
editor3.putString("Array", nama);
editor3.apply();
You should use putStringSet(Set<String>) to store sets (Lists with unique elements). SharedPreferences do not provide a method to store lists directly.
You can easily convert your list to a set using e.g. new HashSet<String>(yourList);
If you need to store a list, you can serialize your list to a String, e.g. by using Gson and storing the json value. Then putString(json) would be correct.
First I don't think there is a way to store lists in Shared preferences. Second it is not a good idea. In your case,I would consider using Sqlite database. It would make things easier.
You can't store a Class type object in SharedPreferences. Also you can't store Lists. If you really need to, you can store the full name of the class object as a String. Then when you read the value back you, you can use Class.forName() to convert that string back to a class. It seems weird, but you can do it.
You could try this to save and restore a set of class names:
Set<String> set = new HashSet<String>();
set.put(Terimakasih.class.getName());
set.put(Ludah.class.getName());
set.put(Permisi.class.getName());
set.put(Tolong.class.getName());
set.put(Maaf.class.getName());
SharedPreferences pref3 = getApplicationContext().getSharedPreferences("set", MODE_PRIVATE);
SharedPreferences.Editor editor3 = pref3.edit();
editor3.putStringSet("set", set);
editor3.apply();
Set<String> strings = pref3.getStringSet("set", Collections.emptySet());
Set<Class> classes = new HashSet<Class>();
for (String s : strings) {
classes.put(Class.forName(s));
}
I have my own Objects which I need to store for later use. The User saves this object, it is turned into a JSON String, then when the User is connected to a network, the JSON String is turned back into the object operations are performed on it.
My problem is that, at run time, how do I know how to store the object?
i.e
Gson gson= new Gson();
String pointOfInterest = gson.toJson(point);
SharedPreferences.Editor sharedprefEditor = application_shared_preferences.edit();
sharedprefEditor.putString(?KEY?,pointOfInterest);
What can I use for the value of KEY? If I use an index, it will get reset every time I open or close the app, and this will replace my Objects.
Edit
Sorry I didn't make this clear enough, the method that the above code is in can be run an arbitrary number of times and there could be several pointsOfInterest to store.
First of all, if you use an index, the Preference will stay forever:
For instance:
sharedprefEditor.putString("JSON569",pointOfInterest);
You can also save the index in an other preference; for instance separated by a column:
sharedprefEditor.putString("indexes","569;789;852");
You can, easily check if an instance exists:
myPreference.getString("JSON789","").contentEquals("");
Or get all your instances:
for (int anIndex:indexes)
Log.i("TAG","Current value: "+myPreference.getString("JSON"+anIndex,""));
Please xplain a little bit more your question, I see no difficulties there/
You can name the key whatever you want, just make it consistent. One way to do it is make a constant in your class for it:
public class MyClass {
private static final String OBJECT_KEY = "myObjectKey";
...
Then when you save your object:
Gson gson= new Gson();
String pointOfInterest = gson.toJson(point);
SharedPreferences.Editor sharedprefEditor = application_shared_preferences.edit();
sharedprefEditor.putString(OBJECT_KEY,pointOfInterest);
When you load it, just use OBJECT_KEY to get a string out of the shared preferences:
String objectString = sharedPrefs.getString( OBJECT_KEY, "" );