I have parsed the JSON Data in a listview
and now I want to make it available offline.
Is there a way to save the JSON data at the phone so that you can see th
You have two ways. Either you create a database and save all of the data there and retrieve it back when you want to. Or if the data you have is not that much and you don't want to deal with databases, then you write the json string to a text file in the memory card and read it later when you are offline.
And for the second case, every time you go online, you can retrieve the same json from your web service and over write it to the old one. This way you can be sure that you have the latest json saved to the device.
this class will help you cache strings in files with a key to retrieve later on. the string can be a json string and key can be the url you requested and also an identifier for the url if you are using post method.
public class CacheHelper {
static int cacheLifeHour = 7 * 24;
public static String getCacheDirectory(Context context){
return context.getCacheDir().getPath();
}
public static void save(Context context, String key, String value) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(cache));
out.writeUTF(value);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void save(Context context, String key, String value, String identifier) {
save(context, key + identifier, value);
}
public static String retrieve(Context context, String key, String identifier) {
return retrieve(context, key + identifier);
}
public static String retrieve(Context context, String key) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
if (cache.exists()) {
Date lastModDate = new Date(cache.lastModified());
Date now = new Date();
long diffInMillisec = now.getTime() - lastModDate.getTime();
long diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMillisec);
diffInSec /= 60;
diffInSec /= 60;
long hours = diffInSec % 24;
if (hours > cacheLifeHour) {
cache.delete();
return "";
}
ObjectInputStream in = new ObjectInputStream(new FileInputStream(cache));
String value = in.readUTF();
in.close();
return value;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
how to use it :
String string = "cache me!";
String key = "cache1";
CacheHelper.save(context, key, string);
String getCache = CacheHelper.retrieve(context, key); // will return 'cache me!'
Once you download the data you could persist the data on the mobile, using a database or a system of your preference.
You can check the different options here: data-storage
You can cache your Retrofit responses, so when you make the same request second time, Retrofit will take it from it's cache: https://medium.com/@coreflodev/understand-offline-first-and-offline-last-in-android-71191e92b426, https://futurestud.io/tutorials/retrofit-2-activate-response-caching-etag-last-modified. After that you'l need to parse that json again
How to Cache Json data to be available offline?
You can use gson to parse JSON data more easily. In your build.gradle file add this dependency.
compile 'com.google.code.gson:gson:2.8.0'
Then create a POJO class to parse JSON data.
Example POJO class:
public class AppGeneralSettings {
@SerializedName("key1")
String data;
public String getData() {
return data;
}
}
To parse a json string from internet use this snippet
AppGeneralSettings data=new Gson().fromJson(jsonString, AppGeneralSettings.class);
Then add a helper class to store and retrieve JSON data to and from preferences.
Example: Helper class to store data
public class AppPreference {
private static final String FILE_NAME = BuildConfig.APPLICATION_ID + ".apppreference";
private static final String APP_GENERAL_SETTINGS = "app_general_settings";
private final SharedPreferences preferences;
public AppPreference(Context context) {
preferences = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
}
public SharedPreferences.Editor setGeneralSettings(AppGeneralSettings appGeneralSettings) {
return preferences.edit().putString(APP_GENERAL_SETTINGS, new Gson().toJson(appGeneralSettings));
}
public AppGeneralSettings getGeneralSettings() {
return new Gson().fromJson(preferences.getString(APP_GENERAL_SETTINGS, "{}"), AppGeneralSettings.class);
}
}
To save data
new AppPreference().setGeneralSettings(appGeneralSettings).commit();
To retrieve data
AppGeneralSettings appGeneralSettings = new AppPreference().getGeneralSettings();
You can use those two methods two store you JSON
file as a string in your SharedPreferences
and retrieve it back:
public String getStringProperty(String key) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
String res = null;
if (sharedPreferences != null) {
res = sharedPreferences.getString(key, null);
}
return res;
}
public void setStringProperty(String key, String value) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
if (sharedPreferences != null) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
CupsLog.i(TAG, "Set " + key + " property = " + value);
}
}
Just use setStringProperty("json", "yourJsonString")
to save and getStringProperty("json")
to retrieve.