0

Seen this thread for possible solutions but it beats me.
I store a customer data object as a JSON String in shared preferences (Android) and try to retrieve the string convert back to customer object and use for validations. The conversion from object to JSON String occurs perfectly well and stores in preferences (as a key value(string) pair).
When I try to create a JSONObject or an array (Its not an array but tried anyway) using the SharedPreferences.getString(key,"") - I always get the same error "Value ... of type java.lang.String cannot be converted to JSONObject".
I am hoping a different pair of eyes catch something I could not. Error message with data (masked):
Value

{"address":{"city":"city","country":"country","customer_address_id":0,"customer_id":0,"house_number":"#123, Lane 1, Street 1","latitude":0.0,"longitude":0.0,"postcode":"12001","street":"Lane 2, Street 2"},"ageGroup":"25-45","dateOfBirth":"1537308474000","email":"abc@abc.com","firstName":"abcdefg","gender":"","id":"108","lastName":"xyz","locale":"en_us","middleName":"none","phone":"1234567890","uuid":"8c3ce2c5-600f-3c4e-bc07-727d61fae7ff"}

of type java.lang.String cannot be converted to JSONObject.
All am trying to do is (gist of code):
Saving to shared prefs using below:

jsonAdapter = moshi.adapter(RegisterUser.class);
mRegisterUser = (RegisterUser) jsonAdapter.fromJson(regisCustUser.toString());
prefs = UserPrefs.getUserPrefs(getApplicationContext());
prefs.setPrefsItem(UserPrefs.getregUserKey(), jsonAdapter.toJson(mRegisterUser));`  

where setPrefsItem does below:

JsonAdapter jsonAdapter = moshi.adapter(javaObject.getClass());
String cartJson = jsonAdapter.toJson(javaObject);
// Log.e("CartJsonreflection", cartJson);
editor.putString(prefKey, cartJson);
editor.commit();

Here is where retrieve occurs:

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

...
private static SharedPreferences settings; 

...
public static Object someMethod(String prefKey, Object javaObject) {
    String prefJson = settings.getString(prefKey, "");
    JSONObject regisCustomer = new JSONObject(prefJson);
    javaObject = (someObject) jsonAdapter.fromJson(regisCustomer.toString()); 
    // casting is redundant but added for clarity
    return javaObject;
}

Where prefJson has the above string. I have tried to validate the JSON string on two websites - https://jsoneditoronline.org/ and https://jsonlint.com/ I have even pasted the string in Notepad++ for any special characters but found none.

  • What line does the error occur on? And how do you save the object in your `SharedPreferences`? – Lars Sep 18 '18 at 17:33
  • Please see updates on the question for save details. Stranger thing is, I am able to retrieve and print the values in the same activity or the whole string in the other fragment just as above. That is the puzzle am not able to resolve. Thanks for having a look. – user2984447 Sep 18 '18 at 21:21
  • 1
    the `"address":"city":"city"` part is wrong and should rather be `"address": { ... }`. – Martin Zeitler Sep 18 '18 at 21:26
  • Apologies, it was a copy and paste error. Added the '{' before "city" attribute, end "}" was there already. – user2984447 Sep 19 '18 at 06:43

3 Answers3

0

Try below

Gson gson = new GsonBuilder().create();
public static <T> T someMethod(String prefKey, Class<T> type) {
   String prefJson = settings.getString(prefKey, "");
   return gson.fromJson(prefJson , type);
}
Krishna Sharma
  • 2,828
  • 1
  • 12
  • 23
  • We are using Moshi so will mean adding one more library or other changes. Additionally, Moshi has worked in a pattern similar to one mentioned by you. May be am trying something silly - to try and store a JSON as a string and retrieve that string to make it a JSONObject and do anything we need. Thanks for having a look. – user2984447 Sep 18 '18 at 21:44
0

Might be the case that you are trying to convert the empty string which the default string to JSONObject . Make sure you are getting a value in prefJson by , making sure that you have initialized the SharedPreferenceswith the correct key and the key for the getString() is also right.

    var s ="{\"address\":{\"city\":\"city\",\"country\":\"country\",\"customer_address_id\":0,\"customer_id\":0,\"house_number\":\"#123, Lane 1, Street 1\",\"latitude\":0.0,\"longitude\":0.0,\"postcode\":\"12001\",\"street\":\"Lane 2, Street 2\"},\"ageGroup\":\"25-45\",\"dateOfBirth\":\"1537308474000\",\"email\":\"abc@abc.com\",\"firstName\":\"abcdefg\",\"gender\":\"\",\"id\":\"108\",\"lastName\":\"xyz\",\"locale\":\"en_us\",\"middleName\":\"none\",\"phone\":\"1234567890\",\"uuid\":\"8c3ce2c5-600f-3c4e-bc07-727d61fae7ff\"}";
    val regisCustomer = JSONObject(s)
    println(regisCustomer.toString())

Since hardcoding the string with your value worked .

Kaveri
  • 1,060
  • 2
  • 12
  • 21
  • Yup, you are right - I tried that too first, hard coding the value to see if it works, it does. But for some reason it wouldn't when I pass the value directly! – user2984447 Sep 18 '18 at 21:45
0

Solution includes pieces of answers from other post. I had to do:

   prefJson= prefJson.replace("\\\"", "\"");
   prefJson = prefJson.substring(prefJson.indexOf("{"), prefJson.lastIndexOf("}") + 1);

The quirky thing was the sharedpreferences had the exact string as below (including start and end quotes('"') in the value. Not sure why that was an issue, only when passed as a parameter. The quotes and the escape characters were ignored when hard coded into the string variable:

"{\"address\":{\"city\":\"City\",\"country\":\"Country\",\"customer_address_id\":0,\"customer_id\":0,\"house_number\":\"#123, Lane 1, Street 1\",\"latitude\":0.0,\"longitude\":0.0,\"postcode\":\"PA 12345\",\"street\":\"Lane 2, Street 2\"},\"ageGroup\":\"25-45\",\"dateOfBirth\":\"1537368909000\",\"email\":\"abc@abc.com\",\"firstName\":\"First Name\",\"gender\":\"\",\"id\":\"119\",\"lastName\":\"Last Name\",\"locale\":\"en_us\",\"middleName\":\"none\",\"phone\":\"0987654321\",\"uuid\":\"8c3ce2c5-600f-3c4e-bc07-727d61fae7ff\"}"  

which had to be converted to:

{"address":{"city":"City","country":"Country","customer_address_id":0,"customer_id":0,"house_number":"#123, Lane 1, Street 1","latitude":0.0,"longitude":0.0,"postcode":"PA 12345","street":"Lane 2, Street 2"},"ageGroup":"25-45","dateOfBirth":"1537368909000","email":"abc@abc.com","firstName":"First Name","gender":"","id":"119","lastName":"Last Name","locale":"en_us","middleName":"none","phone":"0987654321","uuid":"8c3ce2c5-600f-3c4e-bc07-727d61fae7ff"}  

Note: Moderators, please feel free to remove or merge this questiont if this sounds repetitive.Thank you everyone.