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:
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)