How to make onPostExecute() or Json parsing work? - android

I am a beginner in Android, and I am writing a short program to download a JSON feed from URL and parse it. I use AsyncTask to do the downloading.
The doInBackground() part seems to work well. Then I set my breakpoint to onPostExecute(), it can even stop at parseJSON(result), and 'result' is showing the correct json string downloaded. But when I try to step into parseJSON(result), it will NOT step into the function correctly(either throw JSONException directly or go to some random lines within parseJSON(result)).
From DDMS log it's not showing any valuable information as well.
How might I find what the problem is? Is it because I used onPostExecute() incorrectly, or parseJSON() has some problem?
public class MainActivity extends Activity {
private listItem[] items;
public class listItem {
String title;
String description;
String imageHref;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
items = new listItem[50];
new DownloadJsonFeed().execute("http://dl.dropbox.com/u/10168342/facts.json");
}
private class DownloadJsonFeed extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
return downloadUrl(params[0]);
} catch (IOException e) {
return "Unable to retrieve json feed. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
try {
parseJSON(result); // Here !!!!!!
} catch (JSONException e) {
}
}
}
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
is = conn.getInputStream();
// Convert the InputStream into a string
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
return sb.toString();
} finally {
if (is != null) {
is.close();
}
}
}
private void parseJSON(String feed) throws JSONException {
JSONObject json_obj = new JSONObject(feed);
title = json_obj.getString("title");
String rows = json_obj.getString("rows");
JSONArray jArray = new JSONArray(rows);
for (int i = 0; i < jArray.length(); i++) {
JSONObject tmp = jArray.getJSONObject(i);
items[i].title = tmp.getString("title");
items[i].description = tmp.getString("description");
items[i].imageHref = tmp.getString("imageHref");
}
}

JSONObject.getString() will try to get String type value, but what you want is array type.

I think you didn't get the JSON array right. The json_obj.getString will give you an String instead an array.
Try to change as follows:
private void parseJSON(String feed) throws JSONException {
JSONObject json_obj = new JSONObject(feed);
title = json_obj.getString("title");
String rows = json_obj.getString("rows");
JSONArray jArray = json_obj.getJSONArray("rows"); //<---- change this line
for (int i = 0; i < jArray.length(); i++) {
JSONObject tmp = jArray.getJSONObject(i);
items[i].title = tmp.getString("title");
items[i].description = tmp.getString("description");
items[i].imageHref = tmp.getString("imageHref");
}
}

Related

JSONObject can't be correctly created

I want to get images from server into my Android app.
My first steps are:
I have this JSON string array from server
{"results":"[{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara1.jpg\"},{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara2.jpg\"},{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara3.jpg\"}]"}
I got urls in my App from server with code below and working fine.
private void getURLs() {
class GetURLs extends AsyncTask<String, Void, String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(GalleryTargets.this, "Loading...", "Please Wait...", true, true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(GalleryTargets.this,s,Toast.LENGTH_LONG).show();
imageJSON = s;
Log.e(LOGTAG, "Succeed Read url" + imageJSON);
extractJSON(imageJSON);
}
#Override
protected String doInBackground(String... strings) {
String uri = strings[0];
BufferedReader bufferedReader = null;
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json);
}
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
GetURLs gu = new GetURLs();
gu.execute(newurl);
}
But, i want to extract json into a new JSON Object with this method below but throws the exception, Json object not created.
Any ideas why this exception happens?
Thank you in advance!
private void extractJSON(String jsonString){
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jArray = jsonObject.getJSONArray("results");
for (int i = 0; i < jArray.length(); i++) {
JSONObject oneObject = jArray.getJSONObject(i);
oneObject.getString("url");//
}
Log.e(LOGTAG, "JsonArray Succeed" );
} catch (JSONException e) {
e.printStackTrace();
Log.e(LOGTAG, "JsonArray exception");
}
}
Instead of JSONArray jArray = jsonObject.getJSONArray("results");
Try JSONArray jArray = new JSONArray (jsonObject.getString("results"));
You're asking for a json array but it is a string.
There is an error on the json.. after "results": there must not be
quotes
This is correct
{"results":[{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara1.jpg\"},{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara2.jpg\"},{\"url\":\"https:\\\/\\\/augmentedandroidapp.000webhostapp.com\\\/images\\\/kamara3.jpg\"}]}

How to retreive data from background thread to UI thread in aysnctask?

i have fetched data from my api but i don't know how to assign this fetched data to my adapter?
Issue:
how to set fetched data to array defined above?
how to set an adapter ?
public class FetchLists extends AsyncTask<>{
public List<MailChimpList> listTitles = new ArrayList<>();
#Override
protected List<MailChimpList> doInBackground(Integer... params) {
int count = params[0];
int offset = params[1];
String urlString = "https://us14.api.mailchimp.com/lists?apikey=efb918ee8791215bac4c8a3a8a77-us14"
urlString = urlString + "&count=" + count + "&offset=" + offset;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream stream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line = reader.readLine();
String response = "";
while (line != null) {
response += line;
line = reader.readLine();
}
JSONObject object = new JSONObject(response);
JSONArray lists = object.getJSONArray("lists");
for (int i = 0; i < lists.length(); i++) {
JSONObject listData = (JSONObject) lists.get(i);
MailChimpList mailChimpList = new MailChimpList();
mailChimpList.id = listData.getString("id");
mailChimpList.title = listData.getString("name");
String id = listData.getString("id");
String title = listData.getString("name");
Log.d("ashutosh","id are: "+id);
Log.d("ashutosh","list name are: "+title);
listTitles.add(mailChimpList);
}
} catch (Exception e) {
e.printStackTrace();
}
return listTitles;
}
#Override
protected void onPostExecute(List<MailChimpList> mailChimpLists) {
}
}
#Override
protected void onPostExecute(List<MailChimpList> mailChimpLists) {
MyCustomAdapter adapter = new MyCustomAdapter(context, mailChimpLists);
myListView.setAdapter(adapter);
}
As your list is customized list you need to write a customer adapter
You can declare your ListView as global variable and it can be accessed in post execute.

android jsonObject Null Pointer Exception [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am new to JSON. I need help. My android studio keeps on telling me that my jsonobject is NULL. I can parse and display my jsonarray into a listview. But when i click the page where i displayed it, my app crashes.
Parser
class BgTask extends AsyncTask<Void, Void, String> {
String json_url;
#Override
protected void onPreExecute() {
json_url = "http://10.0.2.2/result/hehe.php";
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputstream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputstream));
StringBuilder stringBuilder = new StringBuilder();
while ((JSON_STRING = bufferedReader.readLine()) != null) {
stringBuilder.append(JSON_STRING + "\n");
}
bufferedReader.close();
inputstream.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
json_string = result;
}
}
public void publishGame(View view)
{
if(json_string == null)
{
Toast.makeText(getApplicationContext(), "Get Data First",Toast.LENGTH_SHORT).show();
}
else
{
Intent intent = new Intent(this, Games.class);
intent.putExtra("json_data", json_string);
startActivity(intent);
}
}
}
code that posts
Bundle intent=getIntent().getExtras();
if(intent !=null) {
json_string = intent.getString("json_data");
json_string = getIntent().getExtras().getString("json_data");
}
try {
jsonObject = new JSONObject(json_string);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String team1, score1, team2, score2, Type;
while (count < jsonArray.length()) {
JSONObject JO = jsonArray.getJSONObject(count);
team1 = JO.getString("team1");
score1 = JO.getString("score1");
team2 = JO.getString("team2");
score2 = JO.getString("score2");
Type = JO.getString("Type");
Downloader downloader = new Downloader(team1, score1, team2, score2, Type);
gamesAdapter.add(downloader);
count++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
The error pointing is here try {
jsonObject = new JSONObject(json_string);
The error is because you are trying to parse "json_data" to JSONObject which is not a valid json. Perhaps you are having server response in a variable called json_data which is of String type if that is the case you need to pass that variable instead of passing String literal into JSONObject constructor.

how to fetch json object from url in android

I want to fetch json data from json object.
My json data is:{"avg":2.5} and my android code is
public class AsyncTaskParseJson extends AsyncTask < String, String, String > {
final String TAG = "AsyncTaskParseJson.java";
// set your json string url here
String yourJsonStringUrl = "http://www.bsservicess.com/photoUpload/star_avg.php?bookName=" + book_name;
// contacts JSONArray
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String...arg0) {
try {
JSONParser jParser = new JSONParser();
// get json string from url
JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);
// get the array of users
JSONObject dataJsonArr = json.getJSONObject(str);
String c = dataJsonArr.getString("avg");
na = c;
starts = Float.parseFloat(c);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
super.onPostExecute(strFromDoInBg);
netRate.setRating(starts);
Toast.makeText(mybookview.this, Float.toString(starts), Toast.LENGTH_SHORT).show();
}
But somehow its not working.I have trie every tutorial and evrything but nothing works.plz help me
your getting the json data in response is as {"avg":2.5}
simple remove the below code
JSONObject dataJsonArr = json.getJSONObject(str);
String c = dataJsonArr.getString("avg");
with below line
String c = json.getString("avg");
this is for simple get data from url example:
Parse JSON from HttpURLConnection object
and if you want use library then try Volley:
tutorial link:
http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
A very simple solution to your problem
String str = "{ \"avg\" :0 }";
JsonParser parser = new JsonParser();
JsonObject object = (JsonObject) parser.parse(str);
String value = object.get("avg").getAsString();
But first of all you have to correct the warning in your backend.
EDIT the complete solution
public class AsyncTaskParseJson extends AsyncTask < String, String, String > {
HttpURLConnection urlConnection;
#Override
protected String doInBackground(String...args) {
StringBuilder result = new StringBuilder();
try {
URL url = new URL("http://www.bsservicess.com/photoUpload/star_avg.php?bookName=" + book_name);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader( in ));
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
return result.toString();
}
#Override
protected void onPostExecute(String result) {
JsonParser parser = new JsonParser();
JsonObject object = (JsonObject) parser.parse(result);
String value = object.get("avg").getAsString();
}
}
But first of all remove the warning from the web response!

get the value of AsyncTask method

i have create an android application on where the user can select the start and end point of the location.
This application will use the Google-Direction web service and make the HTTPRequest.
I will make this as short, I want to call the asynctask method in the JSONParser class from the main_activity.
The issue is, I don't know how to display the result in the main_activtiy method
here is the asynctask method
public class JSONParser {
InputStream is = null;
JSONObject jObj = null;
String json = "";
public JSONParser() {
}
public void getJSONFromUrl(final String url, final responseListener target) {
new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... params) {
HttpURLConnection httpURLConnection = null;
StringBuilder stringBuilder = new StringBuilder();
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
int read;
char[] buff = new char[1024];
while ((read = inputStreamReader.read(buff)) != -1) {
stringBuilder.append(buff, 0, read);
}
return stringBuilder.toString();
} catch (MalformedURLException localMalformedURLException) {
return "";
} catch (IOException localIOException) {
return "";
} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();
}
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
target.onResponseComplete(result);
}
}.execute();
}
here is how the main method is calling the method
new JSONParser().getJSONFromUrl(url, new responseListener() {
#Override
public void onResponseComplete(String response) {
try {
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
JSONArray step = new JSONObject(response).getJSONArray("routes").getJSONObject(0).getJSONArray("legs")
.getJSONObject(0).getJSONArray("steps");
for (int i = 0; i < step.length(); i++) {
HashMap<String,Object> row = new HashMap<String,Object>();
row.put("Distance", step.getJSONObject(i).getJSONObject("distance").getString("text"));
list.add(row);
}
}catch (Exception e){
e.printStackTrace();
}
}
});
}
the issue right know is how i want to display the Arraylist List value and put it into the TextView call jarak
You can change your List to be
ArrayList<HashMap<String, String>>
as you are getting a string from
step.getJSONObject(i).getJSONObject("distance").getString("text")
To get it out you can use (assuming your textview is called jarak)
for(HashMap<String,String> map : list) {
for(Entry<String, String> entry : map.entrySet()) {
jarak.setText(entry.getKey() + ", " + entry.getValue());
}
}
Hope that helps

Categories

Resources