You can represent the data storage needs of your application as a root level java object. Then use GSON to convert it to a JSON string. Once available as a string you can store it either in the shared preferences or in the private storage. Details, links, and code snippets follow.

homepage

userguide

Deepaks notes on gson

gson API

How to add external jar files to android apk files?

Search for: How to add external jar files to android apk files?

Use this link from SOF


create a lib subdirectory
copy your jar file there
add your jar file as a library dependency 
  on build/library tab
go to build properties again
go to order/export tab
choose your new library as one of the exportable entries

I will post some pictures when i get a chance.

it seem to convert xml nodes into encoded characters. Perhaps that is a requirement of JSON!! need to check.

escape characters in JSON

Search for: escape characters in JSON

Here is a discussion on SOF

gson escape characters

Search for: gson escape characters

There is some discussion about this on gson here

if needed, looks like this behavior can be turned off. Actually I find this very useful for shared preferences of Android which uses XML envelopes.


public class ChildObject {
   public String name;
   public int age;
   public boolean likesVeggies = false;
   
   public ChildObject(String inName, int inAge)
   {
      name = inName;
      age = inAge;
   }
}

public class MainObject 
{
   public int intValue = 5;
   public String strinValue = "st<ri>\"ng\"Value<node1>test</node2>";
   public String[] stringArray;
   public ArrayList<ChildObject> childList = new ArrayList<ChildObject>();
   
   public void addChild(ChildObject co)
   {
      childList.add(co);
   }
   
   public void populateStringArray()
   {
      stringArray = new String[2];
      stringArray[0] = "first";
      stringArray[1] = "second";
   }
   public static MainObject createTestMainObject()
   {
      MainObject mo = new MainObject();
      mo.populateStringArray();
      mo.addChild(new ChildObject("Eve",30));
      mo.addChild(new ChildObject("Adam",28));
      return mo;
   }
   public static String checkTestMainObject(MainObject mo)
   {
      MainObject moCopy = createTestMainObject();
      if (!(mo.strinValue.equals(moCopy.strinValue)))
      {
         return "String values don't match:" + mo.strinValue;
      }
      if (mo.childList.size() != moCopy.childList.size())
      {
         return "array list size doesn't match";
      }
      //get first child
      ChildObject firstChild = mo.childList.get(0);
      ChildObject firstChildCopy = moCopy.childList.get(0);
      if (!firstChild.name.equals(firstChildCopy.name))
      {
         return "first child name doesnt match";
      }
      return "everything matches";
   }
   
}

public class MainObject 
{
   public int intValue = 5;
   public String strinValue = "st<ri>\"ng\"Value<node1>test</node2>";
   public String[] stringArray;
   public ArrayList<ChildObject> childList = new ArrayList<ChildObject>();
...
}

public void testJSON()
{
   MainObject mo = MainObject.createTestMainObject();
   Gson gson = new Gson();

   //Convert to string
   String jsonString = gson.toJson(mo);
 
   //Convert it back to object
   MainObject mo1 = gson.fromJson(jsonString, MainObject.class);
}

Notice how the type information is nicely preserved because of java generics with out resorting to annotations.

Read up on gson userguide for a variety of other uses of GSON.


public void storeJSON()
{
    MainObject mo = MainObject.createTestMainObject();
    //
    Gson gson = new Gson();
    String jsonString = gson.toJson(mo);
    this.mReportTo.reportBack(tag, jsonString);
    MainObject mo1 = gson.fromJson(jsonString, MainObject.class);
    this.mReportTo.reportBack(tag, jsonString);
    
    SharedPreferences sp = getSharedPreferences();
    SharedPreferences.Editor spe = sp.edit();
    spe.putString("json", jsonString);
    spe.commit();
}

public void retrieveJSON()
{
    SharedPreferences sp = getSharedPreferences();
    String jsonString = sp.getString("json", null);
    if (jsonString == null)
    {
        mReportTo.reportBack(tag,"Not able to read the preference");
        return;
    }
    Gson gson = new Gson();
    MainObject mo = gson.fromJson(jsonString, MainObject.class);
    mReportTo.reportBack(tag,"Object successfully retrieved");
    String compareResult = MainObject.checkTestMainObject(mo);
    if (compareResult != null)
    {
        //there is an error
        mReportTo.reportBack(tag,compareResult);
        return;
    }
    //compareReesult is null
    mReportTo.reportBack(tag,"Retrieved object matches");
    return;
}

private String readFromInternalFile()
{
    FileInputStream fis = null;
    try {
        Context appContext = MyApplication.s_applicationContext; 
        fis = appContext.openFileInput("datastore-json.txt");
        String jsonString = readStreamAsString(fis);
        return jsonString;
    }
    catch(IOException x)
    {
        mReportTo.reportBack(tag,"Cannot create or write to file");
        return null;
    }
    finally
    {
        closeStreamSilently(fis);
    }
}
private void saveToInternalFile(String ins)
{
    
    FileOutputStream fos = null;
    try {
        Context appContext = MyApplication.s_applicationContext; 
        fos = appContext.openFileOutput("datastore-json.txt"
                                ,Context.MODE_PRIVATE);
        fos.write(ins.getBytes());
    }
    catch(IOException x)
    {
        mReportTo.reportBack(tag,"Cannot create or write to file");
    }
    finally
    {
        closeStreamSilently(fos);
    }
}

A note on working with shared preferences

A note on various data storage options in Android

Because typically the data you would represent as JSON is very specific to your application it doesn't make sense to make this available as external storage which is typically used for music files, video files or files that are common in format that is understandable by other applications.

Because external storage such as an SDCard can be in various states (available, not mounted, full, etc) it is harder to program this for simple apps when the data is small enough.

So I don't foresee for now the application state as being maintained on external storage.

May be a hybrid approach is meaningful if the application requires music and photos and those can go on the external storage while keeping the core state data in JSON and internal.


data/data/<your-pkg-name>/files/<your-internal-filename>

{"childList":[{"name":"Adam","likesVeggies":false,"age":30},
{"name":"Eve","likesVeggies":false,"age":28}],"stringArray":["first","second"],
"strinValue":"st\u003cri\u003e\"ng\"Value\u003cnode1\u003etest\u003c/node2\u003e",
"intValue":5}

Search for: extreme protoyping article satya komatineni

Here is that article

This article helps you to design your service layer in such a way that it can be perfected over time. This allows you to migrate from JSON to more granular storage in later releases without disturbing the entire app.

Working with external files is documented here

A number of external file methods are available on the android.os.Environment class