I have a Listview and I need to get the String values of each row when I click the List view.
This is my code
public void ListDrwaer() {
List<Map<String, String>> employeeList = new ArrayList<Map<String, String>>();
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("lectureraccount");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("lecturerName");
String code = jsonChildNode.optString("lecturerCode");
String outPut = name + " --- " + code;
employeeList.add(createEmployee("lecturer", outPut));
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, employeeList,android.R.layout.simple_list_item_1,new String[] { "lecturer" }, new int[] { android.R.id.text1 });
listView.setAdapter(simpleAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
String str = parent.getAdapter().getItem(position).toString();
System.out.println(str);
}});
}
I Managed to get output like this.
{lecturer=MAGESWARY A/P MUNIANDI --- C-MAGESWARY}
My Question is how to get output like this
C-MAGESWARY
Thats all. I am new in programming and not know much. Do i need to change my code completly. If it is, How?
Thank you.
You can do this using split in your onItemClick method as below:
String str = parent.getAdapter().getItem(position).toString();
String[] parts = str.split("---");
String part1 = parts[0];
String part2 = parts[1]; // This is the part you want
String output = part2.replaceAll("\\s+","") //trim whitespace
String output2 = output.replace("}", ""); // remove the "}" character
System.out.println(output2);
Output:
C-MAGESWARY
This is a Java question. Look at link Class String Oracle. Besides the previous answer, look at methods substring, indexOf, and lastIndexof.
You can make it easy on yourself since you have control of the string format in your ListView. Simply add unique characters before your example "C-MAGESWARY", like "!#" . Then you can search the string for those characters. Remember this technique for future apps.
Related
When exporting my array list item, Im getting this error. In the first place it works but when updating my code adding data on my array it crashed my app and this error appear, do you have any idea why this happening?
java.lang.ClassCastException: android.text.SpannableStringBuilder
cannot be cast to java.lang.String
I'm getting error in this line 312 after if statement -
mEdit1.putString("Status_" + i,list_items.get(i));
I've already tried put empty string on my list like this
""+list_items.get(i));
but it's not working :(
ArrayList<String> list_items = new ArrayList<String>(); //declared global
ArrayAdapter arrayAdapter; //declared global
public boolean export_data()
{
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor mEdit1 = sp.edit();
mEdit1.putString("Status_","");
mEdit1.apply();
mEdit1.putInt("Status_size", list_items.size());
for(int i=0;i<list_items.size();i++)
{
mEdit1.remove("Status_" + i);
if (list_items.get(i) !=null){
mEdit1.putString("Status_" + i,list_items.get(i));
String[] separated = list_items.get(i).split(":");
mEdit1.putString("Status_" + i, separated[0]);
}
else{
Toast.makeText(getApplicationContext(), "List is Empty", Toast.LENGTH_SHORT).show();
}
}
return mEdit1.commit();
}
Adding item on ArrayAdapter
public void refreshInbox(){
arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list_items);
ContentResolver cResolver = getContentResolver();
Cursor smsInboxCursor = cResolver.query(Uri.parse("content://sms/inbox"),null,null,null,"date desc");
int indexBody = smsInboxCursor.getColumnIndex("body");
if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
do{
String strbody = smsInboxCursor.getString( smsInboxCursor.getColumnIndex("body") );
if(strbody.contains("Notifier,") && strbody.contains(":")){
System.out.println ( strbody );
String str = strbody;
String[] separated = str.split(",");
String separate = separated[1];
String[] sep = separate.split(" : ");
String sep1 = sep[1];
String finals = separate.replace(sep1, "<u>"+"<b>" + sep1 +"<b>"+ "</u>");
arrayAdapter.add(Html.fromHtml(finals));
}
else if(strbody.contains("Notifier,") && !strbody.contains(":")){
System.out.println ( strbody );
String str = strbody;
String[] separated = str.split(",");
String separate = separated[1];
arrayAdapter.add(separate);
}
}while (smsInboxCursor.moveToNext());
}
Assuming you want to keep displaying HTML in your list view, the problem is that the objects that ArrayAdapter is adding list_items are not Strings. That means, you have to change how you define the list_items variable from String to a more generic character sequence type:
ArrayList<CharSequence> list_items = new ArrayList<>();
The CharSequence interface does not have a "split" method though. To be able to use "split", you'll need to call toString to get a regular string:
String[] separated = list_items.get(i).toString().split(":");
It would also help if you used the type parameter with your ArrayAdapter. Using the type parameter would have made it harder (if not impossible) to make this mistake.
ArrayAdapter<CharSequence> arrayAdapter;
... inside the method ...
arrayAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, list_items);
list_items.get(i));
Looks like you might be attempting to put an unusual type of string into the list...
see: java.lang.ClassCastException: android.text.SpannableString cannot be cast to java.lang.String
I'm not an android dev but I suspect there are some "useful" shortcuts it provides in an attempt to make your life easier, that would probably trip you up.
Groovy's default string was a GString rather than a String. That tripped me up a number of times before I got used to it.
The error is with this line in refreshInbox()
arrayAdapter.add(Html.fromHtml(finals));
Html.fromHtml does't return String but instead it retuns Spanned
But you need to pass String to add() on adapter
To fix this convert it to String
adapter.add(Html.fromHtml(finals).toString()); // this will return plain text without html tags
or
adapter.add(finals); // this will be having HTML tags from this you can set text on views later
I'm trying to add a href to Arraylist and this adds nicely to the Arraylist, but the link is broken. Everything after the question mark (?) in the URL is not included in the link.
Is there anything that I'm missing, code below:
private String processUpdate(Database dbCurrent) throws NotesException {
int intCountSuccessful = 0;
View vwLookup = dbCurrent.getView("DocsDistribution");
ArrayList<String> listArray = new ArrayList<String>();
Document doc = vwLookup.getFirstDocument();
while (doc != null) {
String paperDistro = doc.getItemValueString("DistroRecords");
if (paperDistro.equals("")) {
String ref = doc.getItemValueString("ref");
String unid = doc.getUniversalID();
// the link generated when adding to Arraylist is broken
listArray.add("" + ref + "");
}
Document tmppmDoc = vwLookup.getNextDocument(doc);
doc.recycle();
doc = tmppmDoc;
}
Collections.sort(listArray);
String listString = "";
for (String s : listArray) {
listString += s + ", \t";
}
return listString;
}
You have a problem with " escaping around unid value due to which you URL becomes gandhi.w3schools.com/testbox.nsf/distro.xsp?documentId="+ unid + "&action=openDocument.
It would be easier to read if you use String.format() and single quotes to generate the a tag:
listArray.add(String.format(
"<a href='gandhi.w3schools.com/testbox.nsf/distro.xsp?documentId=%s&action=openDocument'>%s</a>",
unid, ref));
I have an array of data sent from my database - Once received, I save it in shared preferences - here is my getter:
public List getAnswerStringEdit() {
return answer_edit;
}
I save it as so:
editor.putString(Constants.ANSWER_EDIT,resp.getAnswer().getAnswerStringEdit().toString().trim());
Then retrieve it here:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
answerString = answerString.substring(1, answerString.length() - 1).trim();
String[] array = answerString.split(",");
Finally, I access the array as so:
et_answer1_edit.append(array[0]);
My problem is this - Say I add a questions which has a comma in the middle of it, like -
Question 1- "Why is this broke, I don't know?"
Currently, when I retrieve my question, the string is getting split, even though there are quotation marks around the whole question/answer- So in the example above, in position 0 in the array, I should have:
"Why is this broke, I don't know?"
However, instead I am getting in position 0:
Why is this broke - then position 1 as: I don't know
I know this sounds daft because clearly, I am calling for the split to happen on the comma, but I expect that at the end of the whole string object, not in the middle of it.
The retrieved JSON is as follows:
{
"result": "success",
"message": "Answer Has Been Selected",
"answer": {
"answer_edit": ["Why is this broke, I don't know?", "What is your favorite song, because I want to know"]
}
}
Any help/advice that can help me to understand what is causing this, would be really appreciated.
Dont split the string using ',' use this
JSONObject jsonObject = new JSONObject(answerString );
JSONArray jsonArray = jsonObject.getJSONObject("answer").getJSONArray("answer_edit");
Log.e("Json Array elements are","First Element : "+jsonArray.get(0)+"\nSecond Element : "+jsonArray.get(1));
String QuestionString1 = jsonArray.get(0).toString();
String QuestionString2 = jsonArray.get(1).toString();
try this one
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject answer= jsonObject.getJSONObject("answer");
JSONArray jsonArrayAnswerEdit = answer.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArrayAnswerEdit);
for (int i = 0; i < jsonArrayAnswerEdit.length(); i++){
String que= jsonArrayAnswerEdit.getString(i);
Log.e("json", i + "=" + que);
}
} catch (JSONException e) {
e.printStackTrace();
}
Try this
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject data = jsonObject.getJSONObject("answer");
JSONArray jsonArray = data.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++)
{
String value = jsonArray.getString(i);
String[] parts = value.split(Pattern.quote(","));
for (int j=0; j<parts.length; j++)
{
Log.e("Answer String ", "=" + parts[j]);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
OUTPUT
E/=>: ["Why is this broke, I don't know?","What is your favorite song, because I want to know"]
E/Answer String: =Why is this broke
E/Answer String: = I don't know?
E/Answer String: =What is your favorite song
E/Answer String: = because I want to know
After reading all the suggest answers, figured out a simple solution:
First I stored my answers sent from my external database as so -
final String jsonAnswers = gson.toJson (resp.getAnswer().getAnswerStringEdit());
Then saved in shared pref -
editor.putString(Constants.ANSWER_EDIT,jsonAnswers);
Next to read the answer back out:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
final String[] array = gson.fromJson (answerString, String[].class);
Finally, I could set my Edittext with data from the array:
et_answer1_edit.append(array[0].trim());
et_answer2_edit.append(array[1].trim());
I'm having some real problems passing a single string from my main activity to my db helper class. Here is my main activity method which I am returning a string 'answerSetId':
public String showNextRandomQuestion3() {
SQLDatabaseHelper db = new SQLDatabaseHelper(this);
//get the data from the database
List<List<String>> listList = db.getAllAnswersByQuestion1();
//Get the question/text/answer Strings
List<String> questionStrings = listList.get(0); //question Strings
List<String> answerSetIds = listList.get(4);
//Generate random index
Random r = new Random();
int rand = Math.abs((r.nextInt() % questionStrings.size()));
//get answer description for randomly selected question
String questionString = questionStrings.get(rand);
String answerSetId = answerSetIds.get(rand);
questionView.setText(questionString);
return answerSetId;
}
I specifically want to use this 'answerSetId' in one method in my db helper class (as part of a query). Here is my current code - but it is capturing an empty string '[]':
public List<List<String>> getAnswers(String answerSetId) {
List<String> array1 = new ArrayList<String>();
List<String> array2 = new ArrayList<String>();
System.out.println(answerSetId);
SQLiteDatabase db = this.getReadableDatabase();
String[] columns = new String[]{TDESCR, ADESCR};
String selection = ASID+"=?";
String[] selectionArgs = new String[]{String.valueOf(answerSetId)};
Cursor c = db.query(TABLE_ANSWERS, columns, selection, selectionArgs, null, null, null);
if (c.moveToFirst()) {
do {
String textdescr = c.getString(c.getColumnIndex(TDESCR));
String answersdescr = c.getString(c.getColumnIndex(ADESCR));
array1.add(textdescr);
array2.add(answersdescr);
} while (c.moveToNext());
}
List< List<String> > listArray2 = new ArrayList< List<String> >();
listArray2.add(array1);
listArray2.add(array2);
return listArray2;
}
You can see that I want to use this method to retrun some more array data based on the query using the 'answerSetId' string - you'll also see where I have added a system print out which gives the empty value '[]'. But am only bothered about actually capturing the 'answerSetId' value from my main activity at this point.
How best to achieve this?
the arrays of data I will then pass onto my 'showNextAnswer()' method:
public String showNextAnswers() {
SQLDatabaseHelper db = new SQLDatabaseHelper(this);
//get the data from the database
List<List<String>> listList = db.getAnswers(answerSetId);
//Get the question/text/answer Strings
List<String> textDescrs = listList.get(0); //question Strings
// List<String> answerDescrs = listList.get(1); //text strings
// System.out.println(answerSetId);
answerView3.setText(textDescrs.toString());
String textDescriptions = textDescrs.toString();
// String regex = "\\[|\\]";
// textDescriptions = textDescriptions.replaceAll(regex, "");
//Separate out the question/answer of text description associated with the randomly selected question
StringTokenizer textDescr = new StringTokenizer(textDescriptions, ",");
String first = textDescr.nextToken();
// String second = textDescr.nextToken();
// String third = textDescr.nextToken();
// String fourth = textDescr.nextToken();
subQuestionView1.setText(first);
// subQuestionView2.setText(second);
// subQuestionView3.setText(third);
// answerView3.setText(fourth);
// System.out.println(textDescr);
return null;
}
FYI - I call 'showNextRandomQuestion3()' from an onClick method when user clicks to go to a next question - a new random question and the related answers to that new question will appear each click:
NextQuestionButton.setOnClickListener(new OnClickListener(){;
#Override
public void onClick(View v) {
showNextRandomQuestion3();
showNextAnswers();
countQuestions();
}});
It looks like the solution is very simple. You just capture the return value of showNextRandomQuestion3(), since it returns answerSetId.
You will need to add a String parameter to the showNextAnswers() method to take the String that was returned from showNextRandomQuestion3().
So in your click event, you would do this:
NextQuestionButton.setOnClickListener(new OnClickListener(){;
#Override
public void onClick(View v) {
String answerSetId = showNextRandomQuestion3(); //get return value
showNextAnswers(answerSetId); //give the ID here
countQuestions();
}});
Then, just add the parameter to showNextAnswers(), and you're done!
public String showNextAnswers(String answerSetId) {
SQLDatabaseHelper db = new SQLDatabaseHelper(this);
//get the data from the database
List<List<String>> listList = db.getAnswers(answerSetId); //This will work now!
//.................
This question already has answers here:
JSON parsing using Gson for Java
(11 answers)
How do I parse JSON in Android? [duplicate]
(3 answers)
How to parse JSON in Java
(36 answers)
Sending and Parsing JSON Objects in Android [closed]
(11 answers)
How to Parse a JSON Object In Android
(4 answers)
Closed 2 years ago.
I have a rather specific question about JSON parsing in Android.
I have a requirement to download a single JSON array containing information in the format shown below, the number of JSON objects in the array is variable. I need to retrieve all the JSON values in the array so each JSON value has to be stored as an android list named after the common JSON keys because there are many instances of each, e.g. a list for placenames keys [place1,place2,place3 = placename list], a list for questions key, etc. A caveat to this is I cannot use an android array to store these JSON key values since each time my app runs this download task I don't know how many JSON objects will be in the single array. Users can submit as much as they want at any time to the database.
[
{
"placename": "place1",
"latitude": "50",
"longitude": "-0.5",
"question": "place1 existed when?",
"answer1": "1800",
"answer2": "1900",
"answer3": "1950",
"answer4": "2000",
"correctanswer": "1900"
},
{
"placename": "place2",
"latitude": "51",
"longitude": "-0.5",
"question": "place2 existed when?",
"answer1": "800",
"answer2": "1000",
"answer3": "1200",
"answer4": "1400",
"correctanswer": "800"
},
{
"placename": "place3",
"latitude": "52",
"longitude": "-1",
"question": "place 3 was established when?",
"answer1": "2001",
"answer2": "2005",
"answer3": "2007",
"answer4": "2009",
"correctanswer": "2009"
}
]
Below is my code for mainactivity which I managed to get working but had a derp moment and realised I'd simply gone through and parsed out the values for each JSON key in each object as a single string value for each JSON key. Since the loop iterates it merely overwrites at each stage - the placename string is "place1", then "place2", then "place3" by the end of the loop, rather than ["place1","place2", "place3"] which is what I want. My question now is how would I go about parsing the JSONArray to extract all instances of each JSON value and output as a string list for each JSON key, the length of the list is determined by the number of Objects?
I've already got the template for a string list that stores all the JSON key values (commented out in the below code) but I'm not sure how to fill that String list from the JSON parsing process.
I've had a good look around and couldn't find anything specifically about JSON Array to Android List so help would be greatly appreciated. I'd also like to know if there is a way of maintaining association between each list (e.g. questions & answers for specific placenames) if I bundle the data out to different activities (e.g. q&a to a quiz and placenames/lat/lon to GPS). Can I do this by referencing the same index in the list? Or would I need to store these lists in local storage? an SQL lite database?
Thanks for your time and sorry for the overwhelmingly long post!
public class MainActivity extends Activity {
// The JSON REST Service I will pull from
static String dlquiz = "http://www.example.php";
// Will hold the values I pull from the JSON
//static List<String> placename = new ArrayList<String>();
static String placename = "";
static String latitude = "";
static String longitude = "";
static String question = "";
static String answer1 = "";
static String answer2 = "";
static String answer3 = "";
static String answer4 = "";
static String correctanswer = "";
#Override
public void onCreate(Bundle savedInstanceState) {
// Get any saved data
super.onCreate(savedInstanceState);
// Point to the name for the layout xml file used
setContentView(R.layout.main);
// Call for doInBackground() in MyAsyncTask to be executed
new MyAsyncTask().execute();
}
// Use AsyncTask if you need to perform background tasks, but also need
// to change components on the GUI. Put the background operations in
// doInBackground. Put the GUI manipulation code in onPostExecute
private class MyAsyncTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... arg0) {
// HTTP Client that supports streaming uploads and downloads
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
// Define that I want to use the POST method to grab data from
// the provided URL
HttpPost httppost = new HttpPost(dlquiz);
// Web service used is defined
httppost.setHeader("Content-type", "application/json");
// Used to read data from the URL
InputStream inputStream = null;
// Will hold the whole all the data gathered from the URL
String result = null;
try {
// Get a response if any from the web service
HttpResponse response = httpclient.execute(httppost);
// The content from the requested URL along with headers, etc.
HttpEntity entity = response.getEntity();
// Get the main content from the URL
inputStream = entity.getContent();
// JSON is UTF-8 by default
// BufferedReader reads data from the InputStream until the Buffer is full
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
// Will store the data
StringBuilder theStringBuilder = new StringBuilder();
String line = null;
// Read in the data from the Buffer untilnothing is left
while ((line = reader.readLine()) != null)
{
// Add data from the buffer to the StringBuilder
theStringBuilder.append(line + "\n");
}
// Store the complete data in result
result = theStringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
}
finally {
// Close the InputStream when you're done with it
try{if(inputStream != null)inputStream.close();}
catch(Exception e){}
}
//Log.v("JSONParser RESULT ", result);
try {
JSONArray array = new JSONArray(result);
for(int i = 0; i < array.length(); i++)
{
JSONObject obj = array.getJSONObject(i);
//now, get whatever value you need from the object:
placename = obj.getString("placename");
latitude = obj.getString("latitude");
longitude = obj.getString("longitude");
question = obj.getString("question");
answer1 = obj.getString("answer1");
answer2 = obj.getString("answer2");
answer3 = obj.getString("answer3");
answer4 = obj.getString("answer4");
correctanswer = obj.getString("correctanswer");
}
} catch (JSONException e){
e.printStackTrace();
}
return result;
}
protected void onPostExecute(String result){
// Gain access so I can change the TextViews
TextView line1 = (TextView)findViewById(R.id.line1);
TextView line2 = (TextView)findViewById(R.id.line2);
TextView line3 = (TextView)findViewById(R.id.line3);
// Change the values for all the TextViews
line1.setText("Place Name: " + placename);
line2.setText("Question: " + question);
line3.setText("Correct Answer: " + correctanswer);
}
}
}
Instead of keeping variables:
static String placename = "";
static String latitude = "";
static String longitude = "";
static String question = "";
static String answer1 = "";
static String answer2 = "";
static String answer3 = "";
static String answer4 = "";
static String correctanswer = "";
make Bean Class having all these variables. Make array list of bean and during parsing make bean objects and add to list.
Bean Class:
public class ModelClass{
private String latitude = "";
private String longitude = "";
private String question = "";
private String answer1 = "";
private String answer2 = "";
private String answer3 = "";
private String answer4 = "";
private String correctanswer = "";
// ....
// Getter Setters and constructors
// .......
}
ArrayList<ModelClass> mList=new ArrayList<ModelClass>();
In for loop of json parsing:
JSONObject obj = array.getJSONObject(i);
ModelObject object=new ModelObject();
// parse and make ModelObject
list.add(object);
Try using this approach. It will work.
you should divide your objects into classes, and use the GSON json parser.
look at this answer on how to parse a json array into objects:
JSON parsing using Gson for Java
a good approach would be a class question that contains a list of subclasses called possibleanswers, those have a boolean attribute ( correct : true, incorrect: false) to check if the user has clicked the correct one.
if you want to store the data, you will have to use sqllite or any of the many libraries like ActiveAndroid.
I see that you are accessing this JSON file form a Remote Service. On that basis, you will need to structure your code in a manner that will work around how many instances are in the physical JSON file.
Your issue is here:
JSONArray array = new JSONArray(result);
for(int i = 0; i < array.length(); i++)
{
JSONObject obj = array.getJSONObject(i);
You are telling it that the entire JSON file has an array, which contains a length, which is incorrect.
Curly Brackets ("{") represent a JSONObject, and Square Brackets ("[") represent a JSON Array.
Based on your JSON file:
[
{
"placename": "place1",
"latitude": "50",
"longitude": "-0.5",
"question": "place1 existed when?",
"answer1": "1800",
"answer2": "1900",
"answer3": "1950",
"answer4": "2000",
"correctanswer": "1900"
},
You are dealing with one JSONArray, and this array has to no reference name give to it, rather a place index.
Heres what you need to try:
public class ListCreator{
private List<String> placename;
public ListCreator() {
placename = new ArrayList<String>();
}
public void addPlaceName(String s)
{
answers.add(s);
}
public String[] getAnswers()
{
return placename.toArray(new String[1]);
}
}
Bear in mind that is just a snippet of what the class will look like only for the "placename" fields.
Now to your JSON:
You will need to initialize a Vector Variable for each List you want to create:
private Vector<ListCreator> placeNameVec;
Next you will need to set a method for each part of the JSONArray:
public Vector getPlaceNames(){
return placeNameVector;
}
JSONArray array = new JSONArray(result);
for(int x = 0; x < 3; x++){
JSONObject thisSet = array.getJSONObject(x);
ListCreator placeNames = new ListCreator();
placeNames.addPlaceName(thisSet.getString("placename"));
}
placeNameVec.add(placeNames);
That should get you going on what you are trying to answer.
So basically bear in mind that you you can't specify the "array.length()".
Hope this helps!
Please let me know of the outcome :)
If you get into any further difficulty, this Tutorial on JSONParsing really did help me when I was confused.
All the best