0

I have successfully managed to save data entered by the user in my application into a JSON file in the application data folder.

Now, I am trying to load the data (if it exists) back into the application after the application has been destroyed.

This is the code I am using to save it into a JSON

This is my JSON saving and loading class:

public class CriminalIntentJSONSerializer {

private Context mContext;
private String mFilename;

public CriminalIntentJSONSerializer(Context c, String f) {
    this.mContext = c;
    this.mFilename = f;
}

public void saveCrimes(ArrayList<Crime> crimes) throws JSONException, IOException {
    // Build an array in JSON
    JSONArray array = new JSONArray();
    for (Crime c: crimes) {
        array.put(c.toJSON());
    }
    //Write the file to disk
    Writer writer = null;
    try {
        OutputStream out = mContext.openFileOutput(mFilename, Context.MODE_PRIVATE);
        writer = new OutputStreamWriter(out);
        writer.write(array.toString());
    } finally {
        if (writer != null) {
            writer.close();
        }
    }
}

public ArrayList<Crime> loadCrimes() throws IOException, JSONException {
    ArrayList<Crime> crimes = new ArrayList<Crime>();
    BufferedReader reader = null;
    try {
        // open and read the file into a StringBuilder
        InputStream in = mContext.openFileInput(mFilename);
        reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder jsonString = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            // line breaks are omitted and irrelevant
            jsonString.append(line);
        }
        // parse the JSON using JSONTokener
        JSONArray array = (JSONArray) new JSONTokener(jsonString.toString()).nextValue();
        // build the array of crimes from JSONObjects
        for (int i = 0; i < array.length(); i++) {
            crimes.add(new Crime(array.getJSONObject(i)));
        }
    } catch (FileNotFoundException e) {
        // we will ignore this one, since it happens when we start fresh
    } finally {
        if (reader != null)
            reader.close();
    }
    return crimes;
}
}

It seems there is something wrong with loadCrimes. I've tried debugging it and it seems that it successfully finds the json file, I manage to see the json content in the debugger window:

enter image description here enter image description here enter image description here

It also saves the data into the JSONArray array but when it adds it to the crimes array it doesn't work. The size of the array stays at 0, hence no data is actually loading. It doesn't throw any error either.

This is my Crime class:

public class Crime {

private static final String JSON_ID = "id";
private static final String JSON_TITLE = "title";
private static final String JSON_SOLVED = "solved";
private static final String JSON_DATE = "date";


private UUID mID;
private String mTitle;
private Date mDate;
private boolean mSolved;

public Crime() {
    // Generate unique identifier
    this.mID = UUID.randomUUID();
    this.mDate = new Date();
}

public Crime(JSONObject json) throws JSONException {
    mID = UUID.fromString(json.getString(JSON_ID));
    if (json.has(JSON_TITLE)) {
        mTitle = json.getString(JSON_TITLE);
    }
    mSolved = json.getBoolean(JSON_SOLVED);
    mDate = new Date(json.getLong(JSON_DATE));
}

public String getmTitle() {
    return mTitle;
}

public void setmTitle(String mTitle) {
    this.mTitle = mTitle;
}

public UUID getmID() {
    return mID;
}

public Date getmDate() {
    return mDate;
}

public void setmDate(Date mDate) {
    this.mDate = mDate;
}

public boolean ismSolved() {
    return mSolved;
}

public void setmSolved(boolean mSolved) {
    this.mSolved = mSolved;
}

@Override
public String toString() {
    return mTitle;
}

public JSONObject toJSON() throws JSONException {
    JSONObject json = new JSONObject();
    json.put(JSON_ID, getmID().toString());
    json.put(JSON_TITLE, getmTitle());
    json.put(JSON_SOLVED, ismSolved());
    json.put(JSON_DATE, getmDate());

    return json;
}
}

I'm running the app on ICS 4.4.2 API 19 using Genymotion Emulator. Coding on Android Studio 0.8.6.

Can anyone pinpoint what exactly I am doing wrong here?

EDIT. After restarting Android Studio, it is now showing me errors. This is the stacktrace. I've figured out it was a simple data type issue. Solved!:

08-20 15:34:13.019    2835-2835/? E/CrimeLab﹕ Error loading crimes:
org.json.JSONException: Value Wed Aug 20 15:26:15 GMT+00:00 2014 at date of type java.lang.String cannot be converted to long
        at org.json.JSON.typeMismatch(JSON.java:100)
        at org.json.JSONObject.getLong(JSONObject.java:482)
        at com.apps.criminalintent.Crime.<init>(Crime.java:35)
        at com.apps.criminalintent.CriminalIntentJSONSerializer.loadCrimes(CriminalIntentJSONSerializer.java:68)
        at com.apps.criminalintent.CrimeLab.<init>(CrimeLab.java:28)
        at com.apps.criminalintent.CrimeLab.get(CrimeLab.java:61)
        at com.apps.criminalintent.CrimeListFragment.onCreate(CrimeListFragment.java:37)
        at android.app.Fragment.performCreate(Fragment.java:1678)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:859)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
        at android.app.BackStackRecord.run(BackStackRecord.java:684)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
        at android.app.Activity.performStart(Activity.java:5240)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)
orange
  • 5,297
  • 12
  • 50
  • 71
  • You can consider using [Gson](https://code.google.com/p/google-gson/) to do the serialization/desiralization for you. – Joris Aug 20 '14 at 15:33
  • 1
    Thanks but I don't need a library at the moment, I'm learning how to do the basics first. I just want to figure out my problem at the moment. – orange Aug 20 '14 at 15:35
  • can you check `array.length()` before `for` loop? is not `0`? – mmlooloo Aug 20 '14 at 15:37
  • @orange ah ok. In that case, check if your Crime constructor is called and if the correct data is passed there. – Joris Aug 20 '14 at 15:39
  • @mmlooloo It is not 0. – orange Aug 20 '14 at 15:43
  • @Joris Yep, it is called correctly and the data is being passed. I think it has to do with creating the object. Am I using the correct formats? – orange Aug 20 '14 at 15:44
  • I've never used this tokener before, but usually to generate the JsonArray is as simple as `JsonArray array = new JsonArray(jsonString);` Also as debug mechanism you should put a breakpoint after your `while` look, copy the content (ctrl+c) of `line` and test it in this http://jsonviewer.stack.hu/ – Budius Aug 20 '14 at 15:45
  • 1
    @orange the trace should tell you your problem : -) Seems like Addrallyn Wigolath has the right answer for you – Joris Aug 20 '14 at 15:48

1 Answers1

1

I think your problem come from your Crime constructor:

mDate = new Date(json.getLong(JSON_DATE));

A Date can't be parsed like a Long. I think you have a JSONException.

Edit: You can solve your problem by saving the time in milliseconds:

json.put(JSON_DATE, getmDate().getTime());
Brtle
  • 2,297
  • 1
  • 19
  • 26
  • Thanks! I also found this answer useful too - http://stackoverflow.com/questions/7487460/java-convert-long-to-date – orange Aug 20 '14 at 15:51