I have a shopping cart where I want to remove a product there, but I'm facing an issue. I can add product to the shopping cart and I save to shared preferences, but when I want to remove it but doesn't work. Here what I did:
holder.removeProduct.setOnClickListener(v -> {
SharedPreferences preferences = mContext.getSharedPreferences(ITEMS_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = preferences.edit();
Gson gson = new Gson();
String json = preferences.getString("artikujtShporta", "");
ArrayList<Artikujt> artikullObject = gson
.fromJson(json, new TypeToken<ArrayList<Artikujt>>(){}.getType());
if (artikullObject != null) {
artikullObject.remove(artikulli);
String jsonString = gson.toJson(artikullObject);
mEditor.putString("artikujtShporta", jsonString);
mEditor.apply();
} else {
ArrayList<Artikujt> arrayArtikuj = new ArrayList<>();
arrayArtikuj.remove(artikulli);
Type listOfTestObject = new TypeToken<ArrayList<Artikujt>>(){}.getType();
String s = gson.toJson(arrayArtikuj, listOfTestObject);
mEditor.putString("artikujtShporta", s);
mEditor.apply();
}
});
The same thing I did for adding the product, with the difference that here I call
artikullObject.remove(artikulli);
What i'm missing?
What is the problem?
The problem here will be that the instance of your class Artikujt which you want to delete from the Array is not the same as you have read out of the Preferences.
As soon as you use Gson to make your String to a new Array it will generate completely new instances of your class and obviously these will not be the same as you had before. Maybe they are equal, but they are not the same instances.
What can you do to solve this?
I am assuming that you want to have each Artikujt only once. What means you could also use a HashSet. The advantage of this is it would would use the hashCode() function to determine which instance in the set you want to remove. So you just need to override this hashCode() function in your model class and use all of its properties to calculate the hashcode. You can find a example here: https://www.sitepoint.com/how-to-implement-javas-hashcode-correctly/
Sidenote
Your else block is unnecessary. It doesn't make a lot of sense. You are creating a empty ArrayList, then you remove sth from this empty list and then you save this empty List into the shared preferences. The logic of your code wouldn't change if you would just remove this else block.
Related
i create app where when user added new data , there is new label
I have tried and it worked, but I wonder how can I make the json that I store in SharedPreferences
do not over write
so I can add 2 or more user json to adapter
Here is my put string file the json variable contain user that added
SharedPreferences sharedPreferences = getSharedPreferences("newUser", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("listNewUser",json)
editor.apply();
Here is how I can get json from shared preference
try{
String listNewUserAdd = sh.getString("listNewUser","");
JSONObject object = new JSONObject(listNewUserAdd);
for (int i=0; i<object.length(); i++) {
CustomerNew customer = new CustomerNew();
customer.setCustomerName(object.getString("receiverName"));
customer.setAccountId(object.getString("customerReference"));
customer.setId(object.getLong("customerId"));
System.out.println("### GET CUSTOMER NAME "+customer.getCustomerName());
listSortNew.add(customer);
if (listSortNew == null) {
// if the array list is empty
// creating a new array list.
listSortNew = new ArrayList<>();
}
}
I think there are two ways to realize it. One way is when you put data you have to check if it exists.
SharedPreferences sharedPreferences = getSharedPreferences("newUser", MODE_PRIVATE);
String listNewUser = sharedPreferences.getString("listNewUser","");
if(!TextUtils.isEmpty(listNewUser)){
//covert it the list object
//then add the all new item to it
//finally convert it to json string
}
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("listNewUser",json)
editor.apply();
the other way is to change the SharedPreferences MODE_APPEND
but you must know, it doesn't mean that you add multiple values for each key. It means that if the file already exists it is appended to and not erased. We usually used MODE_PRIVATE
In the end I suggest you firstly get the data from it, then check if you need change, you can change the data, then save it again.
I have an myArrayList which is to be stored and restored back in its saved sorted order. But the code does not do that. Why?
ArrayList<String> myArrayList
// save:
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor edit;
edit = prefs.edit();
edit.putStringSet("mydata", new LinkedHashSet<String>(myArrayList));
edit.commit();
// read:
myArrayList = new ArrayList<String>(PreferenceManager
.getDefaultSharedPreferences(getBaseContext()).getStringSet(
"mydata", new LinkedHashSet<String>()));
adapterAppList = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
myArrayList);
Is there any better way I can store the value of myArrayList and restored back to its original saved sorted order?
HashSet is not keeping orders, it is ordering for quickest find to it. You can convert list to json and save as string.
When you need to it, you can convert it to ArrayList from json with keeped ordering.
Example:
String listAsString = new Gson().toJson(arrayList); //list to string
List<String> arrayList = Arrays.asList(new Gson().fromJson(listAsString,String[].class)) //string to list
dont forget add library to build.gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
You can serialize arrayList like string:
1 with gson
public ArrayList<String> convertToArrayList(String json) {
if (TextUtils.isEmpty(json)){
return null; // or new ArrayList<>()
}
Type type = new TypeToken<ArrayList<String>>(){}.getType();
return new Gson().fromJson(json, type);
}
public String convertFromArrayList(ArrayList<String> list) {
if (list == null){
return null;
}
return new Gson().toJson(list);
}
2 without gson
public ArrayList<String> convertToArrayList(String st) {
if (!TextUtils.isEmpty(st)){
String[] str = st.split(",");
if (str.length > 0){
return new ArrayList<>(Arrays.asList(str));
}
}
return null;
}
public String convertFromArrayList(ArrayList<String> list) {
if (list!=null && !list.isEmpty()){
return TextUtils.join(",", list);
}
return null;
}
Yes, you are right, the order is not stored in string set, coz it is a set (duh).
When I was bugged with this, I got the serializing solution where, you can serialize your string.
Read this only if you haven't read about serializing, else go down and read my hack
In order to store array items in order, we can serialize the array into a single string (by making a new class ObjectSerializer (copy the code from – www.androiddevcourse.com/objectserializer.html , replace everything except the package name))
Entering data in Shared preference :
the rest of the code on line 38 -
Put the next arg as this, so that if data is not retrieved it will return empty array(we cant put empty string coz the container/variable is an array not string)
Coming to my Hack :-
Merge contents of array into a single string by having some symbol in between each item and then split it using that symbol when retrieving it.
If you are worried about splitting just look up "splitting a string in java".
[Note: This works fine if the contents of your array is of primitive kind like string, int, float, etc. It will work for complex arrays which have its own structure, suppose a phone book, but the merging and splitting would become a bit complex. ]
PS: I am new to android, so don't know if it is a good hack, so lemme know if you find better hacks.
In my app, I need some data that I do not want to request every time from the server.
This dat includes the userId and some array string.
I think I can store the user id in the SharedPreferences,
but what about the array?
Is it OK to use static variables?
You also can serialize your array to save a array as string in preferences, but keep in mind that if it was big, use Sqllite...
Or you can use the firebase with offline function.
You can use Gson parse Array to String and save to shared preferences.
When you read String from shared preferences you can use Gson to convert String to Array.
Gson library
ArrayList<String> yourArrayStr = convertArrayToString(yourArray);
SharedPreferences prefs = context.getSharedPreferences("PREFERENCE_NAME",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("array_key_name", yourArrayStr);
editor.apply();
function: convertArrayToString
private String convertArrayToString(ArrayList<String> yourArray){
Gson gson = new Gson();
return gson.toJson(yourArray);
}
function convertStringToArray when you read String from shared preferences
private ArrayList<String> convertStringToArray(String yourArrayStr){
Gson gson = new Gson();
return gson.fromJson(yourArrayStr , new TypeToken<ArrayList<String>>(){}.getType());
}
Good luck!
First of all create a class model. like this
public class User implements Serializable {
#SerializedName("id")
private int id;
#SerializedName("array")
private ArrayList<String> array;
//your get/set are here too
}
I use gson to make my life easier.
Than on your server response save the Json on your SharedPreference
SharedPreferencesUtils.write(Constants.Preferences.Keys.USER_DATA, userJson);
And finally everytime you need to read this information you use
String json = SharedPreferencesUtils.read(Constants.Preferences.Keys.USER_DATA, null);
User user = new Gson().fromJson(json, User.class);
I would load this information on your singleton to use everywhere i need it in the application :)
If you need to update it.. just get the response and save again on your SharedPreference.
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, "" );