1

Im get from my server an array of objects like this:

 Log.i(TAG, "Destinos obtenidos: "+ destinosRuta);   

Value of log -

Destinos obtenidos [{"Latitud":41.40404,"nombreDestino":"Barcelona","IDR":5,"IDD":6,"Longitud":2.168679},{"Latitud":37.408424,"nombreDestino":"Sevilla","IDR":5,"IDD":7,"Longitud":-5.9681},{"Latitud":38.92298,"nombreDestino":"Mérida","IDR":5,"IDD":4,"Longitud":-6.363121}]

which I want to stock on SharedPreferences, I have used the code from this answer:

putStringSet and getStringSet

But I don't know if i need to use an array of object, or I need to convert in an array of String, this is my code:

private Emitter.Listener onNuevaRuta = new Emitter.Listener() {

  @Override
  public void call(Object... args) {
    runOnUiThread(new Runnable() {
    @Override
    public void run() {


           JSONObject data = (JSONObject) args[0];
           String destinosRuta = "";


           try {
               destinosRuta = data.getString("destinosRuta");
            }catch (JSONException e) {
                 return;
            }

            //destinosRuta has the previous value
            ArrayList<String> listaDestinos = new ArrayList<String>(Arrays.asList(destinosRuta));

            setStringArrayPref(getApplicationContext(), "listaDestinos", listaDestinos);

             listaDestinos = getStringArrayPref(getApplicationContext(), "listaDestinos");

            String origen = listaDestinos.remove(0);
            String destino = listaDestinos.remove(0);

            setStringArrayPref(getApplicationContext(), "listaDestinos", listaDestinos);
    ...

And, like the previous link, I have used his function:

public static void setStringArrayPref(Context context, String key, ArrayList<String> values) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = prefs.edit();
    JSONArray a = new JSONArray();
    for (int i = 0; i < values.size(); i++) {
        a.put(values.get(i));
    }
    if (!values.isEmpty()) {
        editor.putString(key, a.toString());
    } else {
        editor.putString(key, null);
    }
    editor.commit();
}
public static ArrayList<String> getStringArrayPref(Context context, String key) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    String json = prefs.getString(key, null);
    ArrayList<String> destinos = new ArrayList<String>();
    if (json != null) {
        try {
            JSONArray a = new JSONArray(json);
            for (int i = 0; i < a.length(); i++) {
                String destino = a.optString(i);
                destinos.add(destino);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return destinos;
}

And i get an error when I'm tring to removed the first element of listaDestinos here:

String origen = listaDestinos.remove(0);

String destino = listaDestinos.remove(0); <--Error

FATAL EXCEPTION: main Process: tfg.clienteandroid, PID: 17276 java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) at java.util.ArrayList.remove(ArrayList.java:403) at tfg.clienteandroid.mapaActivity$3$1.run(mapaActivity.java:320)

Any idea? I want to remove twice and be able to use both objects from my array.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
ElíasMarNev
  • 124
  • 1
  • 14
  • Because I need to save the array to be perdurable, as I have searched and say it is the best option – ElíasMarNev Aug 25 '17 at 03:01
  • The better option would be to use Realm database, which natively stores JSON. Plus, you're using Socket.io, which continues to send you data. SharedPreferences can only store one object at the same key value pair, so you'd overwrite data on each message – OneCricketeer Aug 25 '17 at 04:06

2 Answers2

3

You don't need to store a list object. If you have your server already returning JSON, you can directly store that.

JSONObject data = (JSONObject) args[0];
String response = String.valueOf(data);
//... Or parse out the data you need 
sharedPrefs.putString("response", response);

Convert the string into a JSON object or whatever on the way out and optionally parse it into actual Java objects (you can use Jackson or Gson to help you with that)

Anyway, not sure why you think you need to remove an object from a list in order to extract a value; besides, it looks like you only added one value to your list, not two. The Arrays.asList() method is creating you a list of one string. You can't remove two objects from that list


So, try to debug your code better with some breakpoints and more log statements.

In other words, you seem to have a problem parsing your data, not just using SharedPreferences

For example,

data.getString("destinosRuta");

Is that actually a string? Or an array? If an array, use the according method of the JSONObject class to get an array.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
2

Save your json to preference like this

SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
Editor prefsEditor = appSharedPrefs.edit();
prefsEditor.putString("MyObject", destinosRuta);
prefsEditor.commit();

And get it when to use and convert to ArrayList or List as below

SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
Gson gson = new Gson();
String json = appSharedPrefs.getString("MyObject", "");
Type type = new TypeToken<List<Object>>(){}.getType();
List<Object> objects= gson.fromJson(json, type);
Ankit Kumar
  • 3,663
  • 2
  • 26
  • 38