I want to save and read List<MyObj> to sharedPreferences using Gson.
This is my write method:
private static final String GAS_STATIONS_LIST_KEY = "gasStationsListKey";
#Override
public void save(#NonNull List<MyObj> gasStations) {
saveStr(GAS_STATIONS_LIST_KEY, gson.toJson(gasStations));
}
private void saveStr(#NonNull String key, #Nullable String value) {
sharedPreferences
.edit()
.putString(key, value)
.apply();
}
And this is my read method:
#Override
public List<MyObj> getGasStationList() {
final Type type = new TypeToken<List<MyObj>>() {
}.getClass();
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type); // here null
if (gasStations != null && !gasStations.isEmpty()) {
return gasStations;
} else {
return new ArrayList<>();
}
}
But when I try read data I get null (comment in last code part).
How to fix it?
You are not getting the saved json content from shared prefences. You are trying to deserialize the key to a list, not the json content which is saved with that key.
Change this:
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type);
To this:
String savedJsonContent = sharedPreferences.getString(GAS_STATIONS_LIST_KEY, null);
final List<MyObj> gasStations = gson.fromJson(savedJsonContent , type);
SharedPreferences only store primitive data Types.
Related
So, I've been saving some coordinates into a SharedPreferences, but when I try to get them back, the latitude returns fine like :44.374736436, but the longitude returns only 26, even though when I save it, I store it like: 26.24343343.
Where I save it:
PunctSalvat_SP punct = new PunctSalvat_SP(
String.valueOf(latitudine_start),
String.valueOf(longitudine_start),
id_alerta
);
SharedPrefManager.getInstance(getApplicationContext()).SalvarePunct(punct);
SharedPreferences.SalvarePunct():
public void SalvarePunct(PunctSalvat_SP punctSalvat) {
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_PUNCT, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(KEY_latitudine, punctSalvat.getLatitudine());
editor.putString(KEY_longitudine, punctSalvat.getLongitudine());
editor.putString(KEY_id_marker, punctSalvat.getid());
editor.apply();
}
PunctSalvat_SP class:
public class PunctSalvat_SP {
private String latitudine, longitudine, id;
public PunctSalvat_SP(String latitudine, String longitudine, String id) {
this.latitudine = latitudine;
this.longitudine = longitudine;
this.id = id;
}
public String getLatitudine() {
return latitudine;
}
public String getLongitudine() {
return longitudine;
}
public String getid() {
return id;
}
}
Where I try to get it back:
if (SharedPrefManager.getInstance(this).ExistaPunct()) {
ArrayList<String> punct_ramas_in_memorie = new ArrayList<String>();
PunctSalvat_SP punct = SharedPrefManager.getInstance(this).getPunct();
punct_ramas_in_memorie.add(punct.getLatitudine());
punct_ramas_in_memorie.add(punct.getLongitudine());
ruta_pentru_o_problema_id.add(punct.getid());
CrearePunctDinRuta(punct_ramas_in_memorie);
}
SharedPreferences.ExistaPunct() and SharedPreferences.getPunct():
public boolean ExistaPunct() {
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_PUNCT, Context.MODE_PRIVATE);
return (sharedPreferences.getString(KEY_latitudine, null) != null && sharedPreferences.getString(KEY_longitudine, null) != null);
}
public PunctSalvat_SP getPunct() {
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_PUNCT, Context.MODE_PRIVATE);
return new PunctSalvat_SP(
sharedPreferences.getString(KEY_latitudine, null),
sharedPreferences.getString(KEY_longitudine, null),
sharedPreferences.getString(KEY_id_marker, null)
);
}
Debuggind the code, I observed the following:
When I save it, the punct has the right value (Ex: punct = (44.3432432423, 26.1323232, 26)), but when I try to get it back, the arraylist punct_ramas_in_memorie returns 2 elements, the 1st being the right latitude, but the 2nd one returns only 26, instead of 26.242423432.
Verify preference key values for KEY_longitudine and KEY_id_marker, if they are same.
If both key are same the value of id will overridden on longitude. and while retrieving value of longitude you will get value of id(what was written lastly on that key).
I have a RecyclerView in which the views/data in the ViewHolders (image, title, description) are retrieved with the getter methods of a custom object Challenge.
I also have an ArrayList of type Challenge (ArrayList<Challenge> mChallenges) where I add all the challenges and I later pass this ArrayList as a parameter of my RecyclerView.Adapter subclass when I initialize it.
The ViewHolders of my RecyclerView also have a checkbox so users can select the challenges they want, and these chosen challenges are saved on a different ArrayList<Challenge> named currentSelectedChallenges. This is how they get added.
#Override
public void onChallengeChecked(int position) { // method of interface
if (!currentSelectedChallenges.contains(mChallenges.get(position))){
currentSelectedChallenges.add(mChallenges.get(position));
}
}
When the user leaves the fragment where the RecyclerView is contained, either with the back button or closing the app, I save the selected challenges ArrayList<Challenge> currentSelectedChallenges with a SharedPreferences using Gson like this:
#Override
public void onPause() {
super.onPause();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Challenge>>(){}.getType();
String json = gson.toJson(currentSelectedChallenges, type);
editor.putString("selected challenges", json);
editor.apply();
}
And I restore currentSelectedChallenges on the onRestore method of the fragment in the following way:
#Override
public void onResume() {
super.onResume();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
Gson gson = new Gson();
String json = sharedPreferences.getString("selected challenges", null);
Type type = new TypeToken<ArrayList<Challenge>>() {
}.getType();
currentSelectedChallenges = gson.fromJson(json, type);
if (currentSelectedChallenges == null) {
currentSelectedChallenges = new ArrayList<>();
} else
{
for (int i = 0; i < currentSelectedChallenges.size(); i++) {
int index = mChallenges.indexOf(currentSelectedChallenges.get(i));
mChallenges.get(index).setChecked(true);
}
mChallengesAdapter.notifyDataSetChanged();
}
}
When I try to restore the checked state of the CheckBox in the ViewHolder I get an ArrayIndexOutOfBoundsExceptions because currentSelectedChallenges.get(i) is not found inside mChallenges, so it returns -1. I have logged the challenges and the objects have different ids even though I can use the setter methods and will retrieve the same data.
I tried to trick Android and used this:
for (int i=0; i < currentSelectedChallenges.size(); i++) {
for (Challenge challenge : mChallenges) {
if (challenge.getName().equals(currentSelectedChallenges.get(i).getName())){
challenge.setChecked(true);
}
}
mChallengesAdapter.notifyDataSetChanged();
And it does tick in the UI the challenges that were checked by the user but then when I click again on the CheckBox it doesn't detect my click, so I know this is not the proper solution.
Could anyone explain how should I tackle this correctly?
mChallenges.indexOf(currentSelectedChallenges.get(i))
returns -1 because it compares reference instead of your interested data.
you should override equals and hashCode of Challenge class:
class Challenge{
// your current code
#Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Challenge)) {
return false;
}
Challenge challenge = (Challenge) o;
return challenge.name.equals(name) /*&& compare other values for equality*/;
// also check for null name if it is necessary
}
#Override
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
//result = 31 * result + age; // other property
//result = 31 * result + passport.hashCode();// other property
return result;
}
}
Is there a way to save the JSON data at the phone so that you can see the data if your phone is offline?
And what would be the best option to cache data ? SharedPreferences or SQLite database
Here is my code, which i am using to Parse JSON:
if (InternetConnection.checkConnection(getApplicationContext()))
new GetDataTask().execute();
class GetDataTask extends AsyncTask<Void, Void, Void> {
private static final String KEY_ICONURL ="http://droid.hol.es/images/"; ;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(Exit_View_Activity.this);
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
jsonObject = JSONParser.getDataFromWeb();
try {
if (jsonObject != null) {
if(jsonObject.length() > 0) {
JSONArray array = jsonObject.getJSONArray(Keys.KEY_INFO);
int lenArray = array.length();
if(lenArray > 0) {
for(int jIndex = 0; jIndex < lenArray; jIndex++) {
MyDataModel model = new MyDataModel();
JSONObject innerObject = array.getJSONObject(jIndex);
String name = innerObject.getString(Keys.KEY_NAME);
String viewtype = innerObject.getString(Keys.KEY_VIEWTYPE);
String image = innerObject.getString(Keys.KEY_ICON);
String Constantfilter = cat_id.replaceAll("[^0-9,]","");
Log.i("CONSTANT :",Constantfilter);
String[] numbers = Constantfilter.split(",");
for (int i=0;i<numbers.length;i++) {
Log.i("Number: ", numbers[i]);
if(numbers[i].equals(Keys.CONSTANT_CAT)) {
if (innerObject.getString(Keys.KEY_VIEWTYPE).equals("exit") || innerObject.getString(Keys.KEY_VIEWTYPE).equals("grid,exit")) {
model.setName(name);
model.setView_type(viewtype);
model.setId(id);
model.setImage(KEY_ICONURL + image);
model.setCat_id(cat_id);
model.setGrid_order_id(grid_order_id);
list.add(model);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
if (list.size() > 0) {
try {
adapter.notifyDataSetChanged();
dataPath = objectToFile(list);
editor.putString("key_name5",dataPath); // Saving string
// Save the changes in SharedPreferences
editor.commit(); // commit changes
// pref.getString("key_name5", null);
// list = (ArrayList<MyDataModel>)objectFromFile(dataPath);
Snackbar.make(findViewById(R.id.parentLayout), pref.getString("key_name5", null), Snackbar.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
If your data is structured and you want to access it in parts, you should better use SQLite.
If you just want to cache this data and you will use it completely in future better use SharedPref as you won't create schema for it hence SQLite will be a waste of resource and time both.
Hi You can create a class with any name for example I have created "LocalSharedPrefrences"
public class LocalSharedPrefrences {
private static final String strSharedPrefName = "AppPrefrence";
private static final String homePageJosn = "homePageJosn";
public static void saveHomePageJosnData(Context context, String JsonData) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(homePageJosn, JsonData);
editor.commit();
}
public static String getHomePageJosnData(Context context) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
String JsonData = pref.getString(homePageJosn, "");
return JsonData;
}
}
And then you can use these functions to save and get json data as below:
LocalSharedPrefrences.saveHomePageJosnData(Context,JsonDataToSave);
String getJsonData = LocalSharedPrefrences.getHomePageJosnData(Context)
Yes, You can save your json data and and you can use it in offline by using SharedPreferences in android.
First you need to java class i.e. pojo class using Json, Convert that json into above class object.
To save that json -->
private SharedPreferences preferences;
preferences = context.getSharedPreferences("Name", Context.MODE_PRIVATE);
editor = preferences.edit();
editor.putString("your Key String", gson.toJson(here will be your json class object));
editor.commit();
To retrieve That Json-->
gson.fromJson(preferences.getString("your same Key String", null), your json class.class);
In this you will get object of that pojo class i.e. converted json class object.
I want to save a list of strings to a SharedPreferences object. I use these methods but if a set is (2,1,3) when I read it the list is (1,2,3). I don't want to sort the set when I read the array.
EDIT: When I use getSharedPreferences the set is already sorted inside the sharedPreferences object.
private List<String> load() {
Set<String> values = sharedPreferences.getStringSet(PREF_KEY, null);
return new ArrayList<String>(values);
}
private void save(List<String> values) {
//values = (2,1,3)
Set<String> valuesSet = new HashSet<String>(values);
//valuesSet = (1,2,3)
sharedPreferences.edit()
.putStringSet(PREF_KEY, valuesSet).commit();
}
Use serialisation:
private void save(List<String> values) {
String serialisedString = ObjectSerializer.serialize(values);
sharedPreferences.edit()
.putString(PREF_KEY, serialisedString).commit();
}
private List<String> load() {
String serialisedString = sharedPreferences.getString(PREF_KEY, ObjectSerializer.serialize(new ArrayList<String>()));
ArrayList<String> retrievedValues = (ArrayList<String>) ObjectSerializer.deserialize();
return retrievedValues;
}
This question already has answers here:
Save Bundle to SharedPreferences [duplicate]
(3 answers)
Closed 10 years ago.
I want to store a custom object (let's call it MyObject) permanently so that if it is deleted from memory, I can reload it in my Activity/Fragment onResume() method when the app starts again.
How can I do that? SharedPreferences doesn't seem to have a method for storing parcelable objects.
If you need to store it in SharedPreferences, you can parse your object to a json string and store the string.
private Context context;
private MyObject savedObject;
private static final String PREF_MY_OBJECT = "pref_my_object";
private SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
private Gson gson = new GsonBuilder().create();
public MyObject getMyObject() {
if (savedObject == null) {
String savedValue = prefs.getString(PREF_MY_OBJECT, "");
if (savedValue.equals("")) {
savedObject = null;
} else {
savedObject = gson.fromJson(savedValue, MyObject.class);
}
}
return savedObject;
}
public void setMyObject(MyObject obj) {
if (obj == null) {
prefs.edit().putString(PREF_MY_OBJECT, "").commit();
} else {
prefs.edit().putString(PREF_MY_OBJECT, gson.toJson(obj)).commit();
}
savedObject = obj;
}
class MyObject {
}
You can write your Bundle as a parcel to disk, then get the Parcel later and use the Parcel.readBundle() method to get your Bundle back.