0

I have a jsonArray which I want to parse in my android app.

The array:-

[
   {
      "id": 96905,
      "category": "topup",
      "detail": "Full talktime of Rs.55 + 1 local airtel SMS free for 1 day",
      "price": 55,
      "keywords": "topup",
      "updated": "2016-01-07 00:16:23.0",
      "validity": "7 days",
      "service": "Airtel",
      "sourceUri": "https://pay.airtel.com/online-payments/recharge.jsp",
      "circle": "Assam",
      "talktime": 55
   },

   {
      "id": 90397,
      "category": "topup",
      "price": 510,
      "keywords": "topup",
      "updated": "2016-01-07 00:16:23.0",
      "service": "Airtel",
      "sourceUri": "https://pay.airtel.com/online-payments/recharge.jsp",
      "circle": "Assam",
      "talktime": 520
   },
   {
      "id": 90399,
      "category": "topup",
      "price": 1000,
      "keywords": "topup",
      "updated": "2016-01-07 00:16:23.0",
      "service": "Airtel",
      "sourceUri": "https://pay.airtel.com/online-payments/recharge.jsp",
      "circle": "Assam",
      "talktime": 1020
   }]

My android Code:-

Asynctask:-

private class DownloadJSON extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setTitle("Android JSON Parse Tutorial");
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            arraylist = new ArrayList<HashMap<String, String>>();
            try {
                JSONObject jo;
               JSONArray ja2 = JSONfunctions.getJSONfromURL("http://app.ireff.in:9090/IreffWeb/android?service=airtel&circle=assam");

                for (int i = 0; i < ja2.length(); i++) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    jo = ja2.getJSONObject(i);   
                    map.put("rank", jo.getString("price"));
                    map.put("country", jo.getString("validity"));
                    map.put("population", jo.getString("talktime"));
                    arraylist.add(map);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            listview = (ListView) findViewById(R.id.listview);
            adapter = new ListViewAdapter(MainActivity.this, arraylist);
            listview.setAdapter(adapter);
            mProgressDialog.dismiss();
        }
    }

JsonFunctions.java

public class JSONfunctions {

    public static JSONArray getJSONfromURL(String url) {
        InputStream is = null;
        String result = "";
        JSONArray jArray = null;

        // Download JSON data from URL
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();

        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }

        // Convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }

        try {

            jArray = new JSONArray(result);
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }

        return jArray;
    }
}

The error I get:-

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
at com.androidbegin.jsonparsetutorial.MainActivity$DownloadJSON.doInBackground(MainActivity.java:67)
at com.androidbegin.jsonparsetutorial.MainActivity$DownloadJSON.doInBackground(MainActivity.java:39)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 

The json is hosted here

I was following this tutorial for learning json parsing, but this tutorial uses jsonObject and I am not able to parse the json array.

Not a duplicate to this :-Sending and Parsing JSON Objects or this How to parse this JSON Array in android?

24
  • 3
    You can learn about NullPointerException => stackoverflow.com/questions/218384/… Commented Jan 7, 2016 at 9:52
  • validity is not in second object Commented Jan 7, 2016 at 9:52
  • Also httpclient is deprecated. Use httpurlconnection instead Commented Jan 7, 2016 at 9:55
  • 3
    Are you check this value result = sb.toString(); , it not null ??? Commented Jan 7, 2016 at 10:01
  • 1
    @Sleez look around stackoverflow with key android httpclient unauthorized , i think have many solution can help you Commented Jan 7, 2016 at 10:39

3 Answers 3

2

Let me offer an alternate solution (of sorts). A much simpler version of your existing code would be:

Updated code:

private class DownloadJSON extends AsyncTask<Void, Void, Void> {

    ProgressDialog mProgressDialog;

    ArrayList<HashMap<String, String>> arraylist = new ArrayList<>();

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        mProgressDialog = new ProgressDialog(TestListActivity.this);
        mProgressDialog.setTitle("Android JSON Parse Tutorial");
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {

        String url = "http://app.ireff.in:9090/IreffWeb/android?service=airtel&circle=assam";

        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
        okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
        okHttpClient.setRetryOnConnectionFailure(true);

        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);

        try {
            Response response = call.execute();
            String strResult = response.body().string();
            JSONArray JARoot = new JSONArray(strResult);

            for (int i = 0; i < JARoot.length(); i++) {
                JSONObject JORoot = JARoot.getJSONObject(i);

                HashMap<String, String> map = new HashMap<>();

                if (JORoot.has("category") && JORoot.getString("category").equals("topup"))   {

                    if (JORoot.has("id")) {
                        map.put("id", JORoot.getString("id"));
                    }

                    if (JORoot.has("category")) {
                        map.put("category", JORoot.getString("category"));
                    }

                    if (JORoot.has("detail")) {
                        map.put("detail", JORoot.getString("detail"));
                    } else {
                        map.put("detail", null);
                    }

                    if (JORoot.has("price")) {
                        map.put("price", JORoot.getString("price"));
                    }

                    /** ADD THE COLLECTED DATA TO THE ARRAY LIST **/
                    arraylist.add(map); /* THE DATA WILL ONLY BE ADDED IF THE CATEGORY = "topup" */
                }
            }
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        ListView testList = (ListView) findViewById(R.id.testList);
        TestListAdapter adapter = new TestListAdapter(TestListActivity.this, arraylist);
        testList.setAdapter(adapter);

        mProgressDialog.dismiss();
    }
}

private class TestListAdapter extends BaseAdapter {

    Activity activity;

    // LAYOUTINFLATER TO USE A CUSTOM LAYOUT
    LayoutInflater inflater = null;

    // ARRAYLIST TO GET DATA FROM THE ACTIVITY
    ArrayList<HashMap<String, String>> arrItem;

    public TestListAdapter(Activity activity, ArrayList<HashMap<String, String>> arrItem) {

        this.activity = activity;

        // CAST THE CONTENTS OF THE ARRAYLIST IN THE METHOD TO THE LOCAL INSTANCE
        this.arrItem = arrItem;

        // INSTANTIATE THE LAYOUTINFLATER
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return arrItem.size();
    }

    @Override
    public Object getItem(int position) {
        return arrItem.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        // A VIEWHOLDER INSTANCE
        ViewHolder holder;

        // CAST THE CONVERTVIEW IN A VIEW INSTANCE
        View vi = convertView;

        // CHECK CONVERTVIEW STATUS
        if (convertView == null)    {
            // CAST THE CONVERTVIEW INTO THE VIEW INSTANCE vi
            vi = inflater.inflate(R.layout.test_item, null);

            // INSTANTIATE THE VIEWHOLDER INSTANCE
            holder = new ViewHolder();

            /*****  CAST THE LAYOUT ELEMENTS    *****/

            /* TOP (PRIMARY) ELEMENTS */
            holder.txtPrice = (TextView) vi.findViewById(R.id.txtPrice);
            holder.txtDetail = (TextView) vi.findViewById(R.id.txtDetail);

            // SET THE TAG TO "vi"
            vi.setTag(holder);
        } else {
            // CAST THE VIEWHOLDER INSTANCE
            holder = (ViewHolder) vi.getTag();
        }

        if (arrItem.get(position).get("price") != null)    {
            String strPrice = arrItem.get(position).get("price");
            holder.txtPrice.setText("PRICE:  " + strPrice);
        }

        if (arrItem.get(position).get("detail") != null)   {
            String strDetail = arrItem.get(position).get("detail");
            holder.txtDetail.setText("DETAIL: " + strDetail);
        } else {
            holder.txtDetail.setText("DETAIL: NA");
        }

        return vi;
    }

    private class ViewHolder    {

        /* TOP (PRIMARY) ELEMENTS */
        TextView txtPrice;
        TextView txtDetail;
    }
}

For the sake of completeness, I am also including the code for the adapter. It is a simple implementation. Do clean it up / optimize it / customize as per your requirement.

  1. This piece of code has been tested prior to being posted (see screenshot of Logs at the bottom)
  2. This uses the OkHttp library. Add this compile statement to the dependencies section of the module's gradle file: compile 'com.squareup.okhttp:okhttp:2.5.0'. Check the link for an updated version.
  3. The example code uses if statements considering that not every record has the same set of nodes.

enter image description here

enter image description here

Sign up to request clarification or add additional context in comments.

15 Comments

what is okhttp ? a dependency ?
@Sleez: Use the version in the updated and post. The 3.0.0 might have changed something. Change that bit to compile 'com.squareup.okhttp:okhttp:2.5.0'
@Sleez: Give me a couple of minutes while I cook up a full working solution.
@Sleez: You are welcome. For your first question, that's actually a Xiaomi Redmi 2 Prime with the MIUI ROM on it. And second, OkHttp is faster as against the standard HTTP. It has compression, low latency and several of the good things. I have always preferred it over stock HTTP for a couple of years now.
Dude, this question should be given oscar, i was using if(JORoot.getString("category")=="topup"), nvm, we all learn, dhanyavaad so much
|
1

You BufferReader is not working as expected in your class JSONfunctions , do some changes in your class and it should looks like

JSONfunctions.java

public class JSONfunctions {

public static JSONArray getJSONfromURL(String url) {
    InputStream is = null;
    String result = "";
    JSONArray jArray = null;

    // Download JSON data from URL
    try {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        is = entity.getContent();

    } catch (Exception e) {
        Log.e("log_tag", "Error in http connection " + e.toString());
    }


       StringBuffer sb = new StringBuffer("");
    try {
        URL urls = new URL(url);
        URLConnection urlConnection;
        urlConnection = urls.openConnection();
        InputStream in = urlConnection.getInputStream();
        BufferedReader br=new BufferedReader(new InputStreamReader(in));
         String line = "";
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            System.out.println(sb);
            result=sb.toString();
    } catch (IOException e) {}
      catch (Exception e) {}
    try {

        jArray = new JSONArray(result);
    } catch (JSONException e) {
        Log.e("log_tag", "Error parsing data " + e.toString());
    }

    return jArray;
   }
  }

and to avoid Exception check if JSONArray is not null then only it goes to run for loop like this :

 JSONArray ja2 =   JSONfunctions.getJSONfromURL("http://app.ireff.in:9090/IreffWeb/android?  service=airtel&circle=assam");
 if(ja2!=null)
            for (int i = 0; i < ja2.length(); i++) {}

4 Comments

what is the difference between my JsonFunctions class and your class ? It worked...I am checking everything now
@Sleez i think your is = entity.getContent(); returning blank or null that's why your BufferedReader cant read blank inputStream
It is showing only 4 json values, not all json values
Ok, i got it, there is a field not available in All places, Thanks, it fixed my code :-)
1
jsonResponse="";
for(int i = 0; i<response.length(); i++) {
    JSONObject person = (JSONObject) response.get(i);

    String id = person.getString("id");
    String category = person.getString("category");
}

2 Comments

Some explanation would be useful
http is deprecated so use volley library and in volley u can get the response and from reponse u can use JsonArray and JsonObject to extract it from response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.