Retrieving String[] from JSONObject from sharedPreferences - android

I was following Micers Answer store and retrieve a class object in shared preference
But how do I retrieve back STring[] from JSOnObject
my class is :
public class AppearExamState implements Serializable{
private static final long serialVersionUID = 1L;
Boolean flag = false;
int questionId;
int subjectId;
String[] storedAnswers;
public AppearExamState(int q, int subjId, String[] ans, boolean flg){
questionId = q;
subjectId = subjId;
storedAnswers = ans;
flag = flg;
} .......
.........getters and setters.....
.......
//-----------------------------------------------------------------
// Here I convert myObject to JsonObject
//-----------------------------------------------------------------
public JSONObject getJSONObject() {
JSONObject obj = new JSONObject();
try {
obj.put("Qid", this.questionId);
obj.put("Stored_Ans", this.storedAnswers);// is this RIGHT??
obj.put("subj_id", this.subjectId);
obj.put("Flag", this.flag);
} catch (JSONException e) {
e.printStackTrace();
}
return obj;
}
Now when I store in sharepref I followed micers answer and did this:
//--------------------------------------------------------------------------------------
public void sendSharedPreference(ArrayList<AppearExamState> arrayl){
SharedPreferences mPrefs = this.getSharedPreferences("aimmds_state", 0);
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Set<String> set= new HashSet<String>();
for (int i = 0; i < arrayl.size(); i++) {
set.add(arrayl.get(i).getJSONObject().toString());
}
prefsEditor.putStringSet("aimmds_state", set);
prefsEditor.commit();
}
//--------------------------------------------------------------------------------------
and I am stuck here with no clue how to do this
public ArrayList<AppearExamState> loadFromStorage(Context c) {
SharedPreferences mPrefs = c.getSharedPreferences("aimmds_state", 0);
ArrayList<AppearExamState> items = new ArrayList<AppearExamState>();
Set<String> set = mPrefs.getStringSet("aimmds_state", null);
for (String s : set) {
try {
JSONObject jsonObject = new JSONObject(s);
int Quesid = jsonObject.getInt("Qid");
int SubjId = jsonObject.getInt("subj_id");
Boolean flag = jsonObject.getBoolean("Flag");
String[] StoAnswer = ????? ;
AppearExamState myclass = new AppearExamState(Quesid, SubjId, StoAnswer, flag );
items.add(myclass);
} catch (JSONException e) {
e.printStackTrace();
}
}
return items;
}

You cannot put an array to JSON, but you can put a Collection, which is represented by a JSONArray (http://www.json.org/javadoc/org/json/JSONObject.html#put%28java.lang.String,%20java.util.Collection%29). So the correct way to put your array to JSONObject is:
obj.put("Stored_Ans", new JSONArray(this.storedAnswers));
and to get:
JSONArray jsonArray = jsonObject.getJSONArray("Stored_Ans");
String[] StoAnswer = new String[jsonArray.length()];
for(i = 0; i < jsonArray.length(); i++){
StoAnswer[i] = jsonArray.getString(i);
}

Related

how to resolve error in reading json?

Below is my json, which I am trying to read (code Log.i("callinfo", callInfo + ""); onwards, but getting error. My code to read and error message are also mentioned.
{
"CallInfo":[
{
"ItemInfo":[
{
"chargeable":"True",
"itemID":"B13984350K"
},
{
"chargeable":"True",
"itemID":"B13984351A"
}
],
"numberOfCopies":2
}
],
"ISBN":[
""
],
"TitleAvailabilityInfo":null,
"author":"Chief Army Medical Officer.",
"baseCallNumber":"RC87.1 PRE",
"publisherName":"HQ Army Medical Services,",
"title":"Preventing heat injuries : the commanders' guide",
"titleID":9206,
"yearOfPublication":"2000"
}
Code:
public void readBarCode(String response, String scannedBarcode) {
final CountDownLatch latch = new CountDownLatch(1);
final String[] names = new String[4];
JSONArray mArray, mArray1, mArray2;
int totalCount = 0;
int avail = 0;
String author, title, publisherName;
try {
JSONObject obj = new JSONObject(response);
//Results
if (obj.getJSONObject("Results") != null) {
JSONObject obj1 = obj.getJSONObject("Results");
//LookupTitleInfoResponse
if (obj1.getJSONObject("LookupTitleInfoResponse") != null) {
JSONObject obj2 = obj1.getJSONObject("LookupTitleInfoResponse");
//TitleInfo
if (obj2.getJSONArray("TitleInfo") != null) {
mArray = obj2.getJSONArray("TitleInfo");
JSONObject callInfo = mArray.getJSONObject(0);
Log.i("callinfo", callInfo + "");
mArray2 = callInfo.getJSONArray("ItemInfo");
for (int i = 0; i <= mArray2.length(); i++) {
if (mArray2.getJSONObject(i).getString("chargeable").equals("False")) {
totalCount++;
}
if (mArray2.getJSONObject(i).getString("itemID").equals(scannedBarcode)) {
avail = 1;
}
}
author = mArray.getJSONObject(0).getString("author");
publisherName = mArray.getJSONObject(0).getString("publisherName");
title = mArray.getJSONObject(0).getString("title");
TitleTxt.setText(title);
PublisherTxt.setText(publisherName);
CreatorTxt.setText(author);
BookBarcode.setText(scannedBarcode);
AvailabiltyTxt.setText(totalCount);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Getting error on below line:
mArray2 = callInfo.getJSONArray("ItemInfo");
Error:
org.json.JSONException: No value for ItemInfo
03-28 16:33:09.953 17229-17229/com.androidatc.customviewindrawer W/System.err: at org.json.JSONObject.get(JSONObject.java:389)
03-28 16:33:09.953 17229-17229/com.androidatc.customviewindrawer W/System.err: at org.json.JSONObject.getJSONArray(JSONObject.java:584)
Here we can clearly see that ItemInfo got value.
Can anyone tell me - how to resolve above error?
Many thanks in advance.
Try with below code
mArray = obj2.getJSONArray("TitleInfo");
JSONObject titleInfo = mArray.getJSONObject(0);
JSONArray arr1 = titleInfo.getJSONArray("CallInfo");
JSONObject callInfo = arr1.getJSONObject(0);
JSONArray arr2 = callInfo.getJSONArray("ItemInfo");
Log.i("ItemInfo", arr2 + "");
Here is full method
public void readBarCode(String response, String scannedBarcode) {
final CountDownLatch latch = new CountDownLatch(1);
final String[] names = new String[4];
JSONArray mArray, mArray1, mArray2;
int totalCount = 0;
int avail = 0;
String author, title, publisherName;
try {
JSONObject obj = new JSONObject(response);
//Results
if (obj.getJSONObject("Results") != null) {
JSONObject obj1 = obj.getJSONObject("Results");
//LookupTitleInfoResponse
if (obj1.getJSONObject("LookupTitleInfoResponse") != null) {
JSONObject obj2 = obj1.getJSONObject("LookupTitleInfoResponse");
//TitleInfo
if (obj2.getJSONArray("TitleInfo") != null) {
mArray = obj2.getJSONArray("TitleInfo");
JSONObject titleInfo = mArray.getJSONObject(0);
JSONArray arr1 = titleInfo.getJSONArray("CallInfo");
JSONObject callInfo = arr1.getJSONObject(0);
JSONArray arr2 = callInfo.getJSONArray("ItemInfo");
Log.i("ItemInfo", arr2 + "");
for (int i = 0; i < arr2.length(); i++) {
if (arr2.getJSONObject(i).getString("chargeable").equals("False")) {
totalCount++;
}
if (arr2.getJSONObject(i).getString("itemID").equals(scannedBarcode)) {
avail = 1;
}
}
author = mArray.getJSONObject(0).getString("author");
publisherName = mArray.getJSONObject(0).getString("publisherName");
title = mArray.getJSONObject(0).getString("title");
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

Sorting with Comparator not working

I have to store and manage a volume list in the format:
"100 ml", "200 ml", "300 ml"...
I'm using the SharedPreferences with JSON to store this everytime the list is changed.
I want the list to be ordered, so 100 < 1000, but it is showing like 1000 and 2000 before 300.
Here is my comparator:
mVolumeComparator = new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
int volume1 = Integer.parseInt(s1.replace(" ml", ""));
int volume2 = Integer.parseInt(s2.replace(" ml", ""));
if (volume1 > volume2) {
return 1;
} else if (volume2 > volume1) {
return -1;
} else {
return 0;
}
}
};
And here is my get method:
public static ArrayList<String> getVolumesFromPreference(Context ctx) {
if (!ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).contains(KEY_VOLUMES_BUNDLE)) {
startDefaultVolumes(ctx, KEY_VOLUMES_BUNDLE);
}
try {
JSONArray jsonArray = new JSONArray(ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY_VOLUMES_BUNDLE, null));
ArrayList<String> lista = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
lista.add(jsonArray.getString(i));
}
Collections.sort(lista, mVolumeComparator);
return lista;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
private static void startDefaultVolumes(Context ctx, String key_bundle) {
JSONArray jsonArray = new JSONArray();
jsonArray.put("269 ml");
jsonArray.put("350 ml");
jsonArray.put("473 ml");
jsonArray.put("550 ml");
jsonArray.put("600 ml");
SharedPreferences.Editor editor = ctx.getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE).edit();
editor.putString(key_bundle, jsonArray.toString());
editor.commit();
}
use Integer.valueOf() method instead Integer.parceInt()
I will recommend you to store only the value "100", "1000", "300" and UNIT if you have more than unit available.
SO, you can order it just with a normal Integer comparator, and then apply the "ml" suffix at runtime
Try this code for sorting arraylist in ascending order.
ArrayList<int> lista = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
lista.add(Integer.parseInt(jsonArray.getString(i)));
}
Collections.sort(lista , new Comparator<Integer >() {
#Override
public int compare(Integer lhs, Integer rhs) {
return Integer.valueOf(lhs).compareTo(Integer.valueOf(rhs));
}
});

can't fill array NewsData[] NewsData_data

write Custom ArrayAdapter by example: http://www.ezzylearning.com/tutorial.aspx?tid=1763429&q=customizing-android-listview-items-with-custom-arrayadapter
i can't fill array in cycle.
working example:
Weather weather_data[] = new Weather[]
{ new Weather("http://www.ezzylearning.com/images/ImagesNew/net_framework.png", "Cloudy"),
new Weather("http://www.ezzylearning.com/images/ImagesNew/net_framework.png", "Showers")
};
my code:
NewsData[] NewsData_data;
// build hash set for list view
public void ListDrwaer() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("news");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String header = jsonChildNode.optString("header");
String short_text = jsonChildNode.optString("short_text");
String team = jsonChildNode.optString("team");
String datatime = jsonChildNode.optString("datatime");
String photo_url = jsonChildNode.optString("photo_url");
NewsData_data[i] = new NewsData(header, short_text, team, datatime, photo_url);
}
} catch (JSONException e) {
Toast.makeText(getActivity(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
NewsDataAdapter adapter = new NewsDataAdapter(getActivity(),
R.layout.news_details, NewsData_data);
listView.setAdapter(adapter);
}
You need to initialize this array:
NewsData[] NewsData_data;
// build hash set for list view
public void ListDrwaer() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("news");
NewsData_data=new NewsData[jsonMainNode.length()];//<------------HERE
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String header = jsonChildNode.optString("header");
String short_text = jsonChildNode.optString("short_text");
String team = jsonChildNode.optString("team");
String datatime = jsonChildNode.optString("datatime");
String photo_url = jsonChildNode.optString("photo_url");
NewsData_data[i] = new NewsData(header, short_text, team, datatime, photo_url);
}
} catch (JSONException e) {
Toast.makeText(getActivity(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
NewsDataAdapter adapter = new NewsDataAdapter(getActivity(),
R.layout.news_details, NewsData_data);
listView.setAdapter(adapter);
}
Simplified answer: your array is not initialized. Longer answer, you have to know how big it is going to be, then initialize it to that size. A simple example:
NewsData[] NewsData_data;
ArrayList<NewsData> newsDataArray = new ArrayList<NewsData>();
String header = "header";
String short_text = "short_text";
String team = "team";
String datatime = "datatime";
String photo_url = "photo_url";
newsDataArray.add(new NewsData(header, short_text, team, datatime, photo_url));
newsDataArray.add(new NewsData(header, short_text, team, datatime, photo_url));
NewsData_data = new NewsData[newsDataArray.size()];
newsDataArray.toArray(NewsData_data);
System.out.println(NewsData_data);

Saving Android Preferences

Hi, I have a listview and i'm wanting it so that when you press on an item it stores your selection in shared preferences. The purpose for this is so that next time I open the app it skips the selection process.
So what I'm wanting to know is how do I incorporate this function into my code?
Here is my code so far:
public class SelectTeamActivity extends ListActivity {
public String fulldata = null;
public String position = null;
public String divisionName= null;
public List<String> teamsList = null;
public String divName = null;
protected void loadData() {
fulldata = getIntent().getStringExtra("fullData");
position = getIntent().getStringExtra("itemIndex");
Log.v("lc", "selectteamActivity:" + fulldata);
Log.v("lc", "position:" + position);
int positionInt = Integer.parseInt(position);
try{
JSONObject obj = new JSONObject(fulldata);
teamsList = new ArrayList<String>();
JSONObject objData = obj.getJSONObject("data");
JSONArray teamInfoArray = objData.getJSONArray("structure");
for(int r = 0; r < teamInfoArray.length(); r++ ){
JSONObject teamFeedStructureDict = teamInfoArray.getJSONObject(r);
JSONArray teamStructureArray =
(JSONArray) teamFeedStructureDict.get("divisions");
JSONObject teamFeedDivisionsDictionary =
teamStructureArray.getJSONObject(positionInt);
divName = teamFeedDivisionsDictionary.getString("name");
JSONArray teamNamesArray =
(JSONArray) teamFeedDivisionsDictionary.get("teams");
for(int t = 0; t < teamNamesArray.length(); t++){
JSONObject teamNamesDict = teamNamesArray.getJSONObject(t);
teamsList.add(teamNamesDict.getString("name"));
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.selectact);
loadData();
TextView headerText = (TextView) findViewById(R.id.header_text);
headerText.setText(divName);
TextView redHeaderText = (TextView) findViewById(R.id.redheadertext);
redHeaderText.setText("Please select your team:");
setListAdapter( new ArrayAdapter<String>(this, R.layout.single_item,
teamsList));
ListView list = getListView();
list.setTextFilterEnabled(true);
}
#Override
protected void onListItemClick (ListView l, View v, int position, long id) {
Intent intent = new Intent(this, HomeActivity.class);
String curPos = Integer.toString(position);
//or just use the position:
intent.putExtra("itemIndex", curPos);
intent.putExtra("fullData", fulldata); //or just the part you want
startActivity(intent);
}
}
In your Activity's onCreate():
SharedPreferences preferences = getSharedPreferences("preferences", MODE_WORLD_WRITEABLE);
In your onListItemClick():
preferences.edit().putInt("KEY", position).commit();
Everywhere in your project:
int position = preferences.getInt("KEY", -1);
(-1 is a default value that means when there is no value with the given key, return this value)

How can I store an integer array in SharedPreferences?

I want to save/recall an integer array using SharedPreferences. Is this possible?
You can try to do it this way:
Put your integers into a string, delimiting every int by a character, for example a comma, and then save them as a string:
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int[] list = new int[10];
StringBuilder str = new StringBuilder();
for (int i = 0; i < list.length; i++) {
str.append(list[i]).append(",");
}
prefs.edit().putString("string", str.toString());
Get the string and parse it using StringTokenizer:
String savedString = prefs.getString("string", "");
StringTokenizer st = new StringTokenizer(savedString, ",");
int[] savedList = new int[10];
for (int i = 0; i < 10; i++) {
savedList[i] = Integer.parseInt(st.nextToken());
}
You can't put Arrays in SharedPreferences, but you can workaround:
private static final String LEN_PREFIX = "Count_";
private static final String VAL_PREFIX = "IntValue_";
public void storeIntArray(String name, int[] array){
SharedPreferences.Editor edit= mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE).edit();
edit.putInt(LEN_PREFIX + name, array.length);
int count = 0;
for (int i: array){
edit.putInt(VAL_PREFIX + name + count++, i);
}
edit.commit();
}
public int[] getFromPrefs(String name){
int[] ret;
SharedPreferences prefs = mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE);
int count = prefs.getInt(LEN_PREFIX + name, 0);
ret = new int[count];
for (int i = 0; i < count; i++){
ret[i] = prefs.getInt(VAL_PREFIX+ name + i, i);
}
return ret;
}
Here's my version, based on Egor's answer. I prefer not to use StringBuilder unless I'm building an enourmous string, but thanks to Egor for using StringTokenizer -- haven't made much use of this in the past, but it's very handy! FYI, this went in my Utility class:
public static void saveIntListPrefs(
String name, Activity activity, List<Integer> list)
{
String s = "";
for (Integer i : list) {
s += i + ",";
}
Editor editor = activity.getPreferences(Context.MODE_PRIVATE).edit();
editor.putString(name, s);
editor.commit();
}
public static ArrayList<Integer> readIntArrayPrefs(String name, Activity activity)
{
SharedPreferences prefs = activity.getPreferences(Context.MODE_PRIVATE);
String s = prefs.getString(name, "");
StringTokenizer st = new StringTokenizer(s, ",");
ArrayList<Integer> result = new ArrayList<Integer>();
while (st.hasMoreTokens()) {
result.add(Integer.parseInt(st.nextToken()));
}
return result;
}
I like to use JSON, which can be stored and retrieved as a string, to represent any complex data in SharedPreferences.
So, in the case of an int array:
public void setPrefIntArray(String tag, int[] value)
{
SharedPreferences.Editor prefEditor = PreferenceManager.getDefaultSharedPreferences(context)
.edit();
String s;
try
{
JSONArray jsonArr = new JSONArray();
for (int i : value)
jsonArr.put(i);
JSONObject json = new JSONObject();
json.put(tag, jsonArr);
s = json.toString();
}
catch(JSONException excp)
{
s = "";
}
prefEditor.putString(tag, s);
prefEditor.commit();
}
public int[] getPrefIntArray(String tag, int[] defaultValue)
{
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
String s = pref.getString(tag, "");
try
{
JSONObject json = new JSONObject(new JSONTokener(s));
JSONArray jsonArr = json.getJSONArray(tag);
int[] result = new int[jsonArr.length()];
for (int i = 0; i < jsonArr.length(); i++)
result[i] = jsonArr.getInt(i);
return result;
}
catch(JSONException excp)
{
return defaultValue;
}
}
The beauty is that the same idea can be applied to any other complex data representable as a JSON.
Two solutions:
(1) Use http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
It has split/join functions that let you join and split the integers in one liners:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.split("1;2;3", ';') = ["1", "2", "3"]
You'd still have to convert the strings back to integers, though.
Actually, for splitting java.lang.String.split() will work just as fine:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
(2) Use the SharedPreferences.putStringSet() (API 11):
SharedPreferences.Editor editor = preferences.edit();
int count = this.intSet.size();
if (count > 0) {
Set<String> theSet = new HashSet<String>();
for (Long l : this.intSet) {
theSet.add(String.valueOf(l));
}
editor.putStringSet(PREFS_KEY, theSet);
} else {
editor.remove(PREFS_KEY);
}
editor.commit();
And to get it back:
Set<String> theSet = this.preferences.getStringSet(PREFS_KEY, null);
if (theSet != null && !theSet.isEmpty()) {
this.intSet.clear();
for (String s : theSet) {
this.intSet.add(Integer.valueOf(s));
}
}
This code does not catch the NPEs or NumberFormatExceptions because the intSet is otherwise assured to not contain any nulls. But of course, if you cannot assure that in your code you should surround this with a try/catch.
Here is how the "convert to comma-separated String" solution could look in Kotlin, implemented as extension functions:
fun SharedPreferences.Editor.putIntArray(key: String, value: IntArray): SharedPreferences.Editor {
return putString(key, value.joinToString(
separator = ",",
transform = { it.toString() }))
}
fun SharedPreferences.getIntArray(key: String): IntArray {
with(getString(key, "")) {
with(if(isNotEmpty()) split(',') else return intArrayOf()) {
return IntArray(count(), { this[it].toInt() })
}
}
}
That way you can use putIntArray(String, IntArray) and getIntArray(String) just like the other put and set methods:
val prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
prefs.edit().putIntArray(INT_ARRAY_TEST_KEY, intArrayOf(1, 2, 3)).apply()
val intArray = prefs.getIntArray(INT_ARRAY_TEST_KEY)
I went for the below solution, it's the least verbose of what I could see in this thread (in my case I wanted to have a set as a collection). "value" is the of type Set<Int>.
Save:
sharedPreferences.edit {
if (value.isNotEmpty()) {
putStringSet(key, hashSetOf(*value.map { it.toString() }.toTypedArray()))
} else {
remove(key)
}
}
Retrieve:
val stringSet = sharedPreferences.getStringSet(key, null)
if (stringSet.isNullOrEmpty()) return emptySet()
return setOf<Int>(*stringSet.map { Integer.valueOf(it) }.toTypedArray())
You can only save primitive values in sharedPreference. Use Sqlite instead.

Categories

Resources