My object consists of five fields :
public class ConfigurationItem {
#SerializedName("show_interest")
boolean show_interest;
#SerializedName("bid_with_price")
boolean bid_with_price;
#SerializedName("anonymous_orders")
boolean anonymous_orders;
#SerializedName("orders_progress_status")
boolean orders_progress_status;
#SerializedName("orders_progress_messages")
boolean orders_progress_messages;
}
I parse this items from the web server and receive string like this :
{
"ordersProgressStatus":true,
"showInterest":false,
"anonymousOrders":true,
"bidWithPrice":true,
"ordersProgressMessages":true
}
I receive the JSON and save it to the SharedPreferences like this :
public static void saveCurrentConfiguration(Context mContext, JSONObject jsonObject ) {
SharedPreferences sharedPreferences = mContext.getApplicationContext().getSharedPreferences(Constants.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
prefsEditor.putString(Constants.SHARED_CURRENT_CONFIG, jsonObject.toString());
prefsEditor.apply();
}
But when I want to read the saved object :
public static ConfigurationItem getCurrentConfiguration(Context mContext)
{
SharedPreferences sharedPreferences = mContext.getApplicationContext().getSharedPreferences(Constants.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString(Constants.SHARED_CURRENT_CONFIG, null);
ConfigurationItem configurationItem = gson.fromJson(json, ConfigurationItem.class);
Log.i(TAG + " loaded config", configurationItem.toString());
return configurationItem;
}
in the configurationItem I get only false values. Besides, the read string from the SharedPreference is correct, but when I use Gson for deserialize, the object is filled with wrong values.
What can be the solution ?
When using the annotation #SerializedName this references the key value in the JSON string. So instead of doing #SerializedName("show_interest") to serialize the value from "showInterest" do #SerializedName("showInterest")
Using serialized name is handy when you don't want to tie the name of a JSON key to name of a field. For instance when you prefer to use the JAVA standaard convention of prefixing private field with m like private boolean mShowInterest; so when later you refactor the field name to something else you can do a easy refactor, or if the JSON key changes you on have to change the annotation.
Related
Is it any way to save ArrayList to sharedpreferences? Thank you
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(Level1Activity.class);
activityList.add(Level2Activity.class);
activityList.add(Level3Activity.class);
activityList.add(Level4Activity.class);
activityList.add(Level5Activity.class);
I already answered this to your other question but just in case, I'll re-write it here and explain it more a bit.
You can use Gson to convert your list into a Json String so that you can save it in SharedPreferences.
You will need to add implementation 'com.google.code.gson:gson:2.8.6' inside your app gradle dependencies to be able to use Gson.
But, you cannot simply parse the list using Gson to Json or viceversa when you use the Class class. In order to do so, you will need to create your own serializer and deserializer for it. Or you'll face this exception:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: com.etc.etc.Level1Activity. Forgot to register a type adapter?
So let's create a custom adapter that implements JsonSerializer and JsonDeserializer. Don't forget to put inside the angle brackets the type we're working with, which is Class.
ClassAdapter class
public class ClassAdapter implements JsonSerializer<Class>, JsonDeserializer<Class> {
#Override
public JsonElement serialize(Class src, Type typeOfSrc, JsonSerializationContext context) {
// Get our class 'src' name
return new JsonPrimitive(src.getName());
}
#Override
public Class deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
// Get class
return Class.forName(json.getAsString());
} catch (ClassNotFoundException e) {
// If class could not be found or did not exists, handle error here...
e.printStackTrace();
}
return null;
}
}
To convert our list to Json String and save it inside SharedPreferences:
// Create new GsonBuilder and register our adapter for Class objects
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Class.class, new ClassAdapter());
// Initialize our list of levels (ie. classes)
List<Class> classes = new ArrayList<>();
classes.add(Level1Activity.class);
classes.add(Level2Activity.class);
classes.add(Level3Activity.class);
classes.add(Level4Activity.class);
classes.add(Level5Activity.class);
// Create Gson from GsonBuilder and convert list to json
Gson gson = gsonBuilder.create();
String json = gson.toJson(classes);
// Save json to SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("app_name", MODE_PRIVATE);
sharedPreferences.edit().putString("levels", json).apply();
And to retrieve the list back:
// Retrieve json from SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("app_name", MODE_PRIVATE);
String json = sharedPreferences.getString("levels", null);
// Handle here if json doesn't exist yet
if (json == null) {
// ...
}
// Create new GsonBuilder and register our adapter for Class objects
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Class.class, new ClassAdapter());
// Create Gson from GsonBuilder and specify type of list
Gson gson = gsonBuilder.create();
Type type = new TypeToken<ArrayList<Class>>(){}.getType();
// Convert json to list
List<Class> classes = gson.fromJson(json, type);
Hope this helps, happy coding!
I created a simple localhost API with a JSON database on my computer. I already implemented functions where hosts can create a new profile or log in to existing one.
"hosts": [
{
"id": 1,
"login": "drey95music",
"password": "8526000Qq",
"email": "shtandrinity#gmail.com",
"eventName": "FDC Open Mic",
"latitude": 41.924676,
"longitude": -87.700266
}],
"artists": [
{
"id": 1,
"name": "MDQ",
"phone": 7738375513,
"isLocated": "true",
"userId": 1
}]
My question is what is the best way to store/remember/check if a user is logged in so he/she would have more functionality?
Thank you.
Actually you can have the implementation in a lot of different ways based on the use case that you have. Personally, I would feel, if the user information is something very small or you just have to store a token in order to pass it to the subsequent API requests, then storing that token in the SharedPreferences might be a good idea. So that this can be accessed from anywhere in the app, and also this storage is persistent - that is, even if you are closing the application and reopen it, it says in the persistent memory.
That being said, if you have to store a lot of information, I would recommend having those stored in the SQLite database. SharedPreferences is not recommended for storing large amounts of data.
I hope that helps!
Usually developer use Shared Preference to store some value behave of specific key. I've made a generic shared preference class and use it every android project without any hesitation.
public class SaveInSharedPreference {
public static final String IS_LOGIN = "isLogin";
private final SharedPreferences pref;
private final SharedPreferences.Editor editor;
// shared pref mode
private final int PRIVATE_MODE = 0;
// Shared preferences file name
private static final String PREF_NAME = "PREF_NAME";
#SuppressLint("CommitPrefEdits")
public SaveInSharedPreference(Context context) {
pref = context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = pref.edit();
}
public void setBoolean(String key, boolean value){
editor.putBoolean(key, value);
editor.commit();
}
public boolean getBoolean(String key) {
return pref.getBoolean(key, false);
}
public void setString(String key, String value) {
editor.putString(key, value);
editor.commit();
}
public String getString(String key) {
return pref.getString(key, "");
}
public void setInteger(String key, int value) {
editor.putInt(key, value);
editor.commit();
}
public Integer getInteger(String key) {
return pref.getInt(key, 0);
}
public void clearSavedInSharedPreference(){
editor.clear();
editor.commit();
}
}
After successfully authenticate a user use this line to add/update value of a key by:
new SaveInSharedPreference(this).setBoolean(IS_LOGIN, true);
And you can get the value of key by:
new SaveInSharedPreference(this).getBoolean(IS_LOGIN);
Shared preference stored only String, Boolean, Long, Float, Integer. If you want to store JsonObject in shared preference you can do it as well. But you have to change your JsonObject into string then store it and get value from shared preference in string then conert it into your JsonObject given below:
Store/Update data
new SaveInSharedPreference(this).setString("user_data", new Gson().toJson(put_your_model_here));
Get data
new Gson().fromJson(new SaveInSharedPreference(this).getString("user_data"));
You can also store your list in shared preference.
I'm trying to put an ArrayList of self-created objects in SharedPreferences. While the saving seems to work, I get the following error when getSharedPreferences() is called:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.google.gson.Gson.fromJson(java.lang.String, java.lang.reflect.Type)' on a null object reference
The code where I put it into SharedPreferences:
// FYI: gson = new Gson(); is set earlier on
// same goes for: ArrayList<MovieModel> movieModelList = new ArrayList<>();
// and: Type listType;
movieModelList.add(result);
String jsonMovieModelList = gson.toJson(movieModelList);
SharedPreferences prefs = getSharedPreferences("settings",
MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("jsonMovieModelList", jsonMovieModelList);
editor.apply();
And the SharedPreferences class:
public void getSharedPreferences() {
SharedPreferences prefs = getSharedPreferences("settings",
MODE_PRIVATE);
String jsonMovieModelList = prefs.getString("jsonMovieModelList", null);
Log.d("TAG", "Message" + jsonMovieModelList); // output is as expected
// if not filled in, no action necessary
if (jsonMovieModelList != null) {
listType = new TypeToken<ArrayList<MovieModel>>(){}.getType();
ArrayList<MovieModel> movieModelListSaved = gson.fromJson(jsonMovieModelList, listType);
MovieModel lastMovie = movieModelListSaved.get(movieModelListSaved.size() - 1);
showTitleSecond = (TextView)findViewById(R.id.show_title_2);
showTitleSecond.setText(lastMovie.getTitle());
}
}
The gson code is based on: https://google.github.io/gson/apidocs/com/google/gson/Gson.html
To be clear:
I do understand what a NullPointerException is, but I don't understand why I receive one in this situation since I check before executing that the String jsonMovieModelList is at least not null. Why is gson 'losing' the reference?
I look at this question: Android ArrayList of custom objects - Save to SharedPreferences - Serializable? and the only difference I see is that I have an ArrayList
Seems like you've not initialized variable gson before its usage in this method. Just add Gson gson = new GsonBuilder().create(); before the first usage, or in this method you're calling and that should fix it.
I was looking for this - but found only how to save an arrayList for example this code:
Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(MyObject);
prefsEditor.putString("MyObject", json);
prefsEditor.commit();
I want to store this object(point) which is LatLng in SharedPreferences, after that i will need to get it from this save. Here is what i want to save:
public void onMapClick(LatLng point) {
// TODO Auto-generated method stub
mMap.addMarker(new MarkerOptions().position(point));
**checkPoints.add(point);**
}
Instead of using preferences you can use Sqlite database. But if you insist on using SharedPreferences then I don't think you have much choice as you can only store boolean, float, int, long, String or StringSet. The only possible way I see is that you concatenate all of the values with your own separator like
1123.4456:1234.223|1123.4456:1234.1233|1123.4456:1234.223|1123.4456:1234.223
and then just parse when retrieving it.
Using GSON, how can i return a single key from a Multidimensional Json String?
Here is the Multidimensional Json String:
{"statusCode":0,"statusDescription":"OK","data":{"user":{"id":xxx,"company_id":xxx,"account_type":"5","enable_locations":true,"intuit_user_id":null,"nick_name":"xxx","is_owner":"1","enabled":"1"},"session_token":"xxx"}}
I want to return the "session_token" key value.
I'm trying this:
class app {
static class Response {
String session_token;
}
public void getSessionToken() {
String x = {"statusCode":0,"statusDescription":"OK","data":{"user":{"id":xxx,"company_id":xxx,"account_type":"5","enable_locations":true,"intuit_user_id":null,"nick_name":"xxx","is_owner":"1","enabled":"1"},"session_token":"xxx"}}
Response r = new Gson().fromJson(x, Response.class);
System.out.println(r.session_token);
}
}
But with this, my r.session_token returns null.
You would need to use Gson's JsonParser class directly and extract the data from the parse tree:
String myJsonString = "{\"name\":\"john\",\"lastname\":\"smith\"}";
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(myJsonString);
JsonObject jsonObject = element.getAsJsonObject();
String lastName = jsonObject.get("lastname").getAsString();
System.out.println(lastName);
That said, it's debatable whether this would save you any real time over:
(edited from comments below):
class App {
static class Response {
String lastname;
}
public static void main(String[] args) {
String myJsonString = "{\"name\":\"john\",\"lastname\":\"smith\"}";
Response r = new Gson().fromJson(myJsonString, Response.class);
System.out.println(r.lastname);
}
}
Gson will silently ignore the fact that there's more data in the JSON than you're interested in, and later on you might be interested in it, in which case it's trivial to add fields to your Response class.
Edit due to question changing:
You have a JSON object. It contains a field data whose value is an object. Inside that object you have a field session_token that you're interested in.
Either you have to navigate to that field through the parse tree, or you have to create Java classes that all will map to. The Java classes would resemble (at the bare minimum):
class Response {
Data data;
}
class Data {
String session_token;
}