0

Alright so I'm attempting to pull data from JSON's lists such as this:

{"code":200,"status":"OK","data":{"timings":{"Fajr":"04:17","Sunrise":"05:30","Dhuhr":"12:20","Asr":"15:42","Sunset":"19:11","Maghrib":"19:11","Isha":"20:24","Imsak":"04:07","Midnight":"00:20"},"date":{"readable":"17 Jun 2017","timestamp":"1497652236"}}}

exclusively the specific prayers. My code to find the data is as follows:

 class SaveTheFeed extends AsyncTask<Void, Void, Void>{
    String jsonString = "";
    String result = "";
    EditText chosenCity = (EditText) findViewById(R.id.editText3);
    String city = chosenCity.getText().toString();

    @Override
    protected Void doInBackground(Void... voids) {
        DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
        HttpPost httpPost = new HttpPost("http://api.aladhan.com/timingsByCity?city=" + city + "&country=AE&method=2");
        httpPost.setHeader("Content-type", "application/json");
        InputStream inputStream;

        try{
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            inputStream = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) !=null){
                builder.append(line + "\n");
            }
            jsonString = builder.toString();

            JSONObject jObject = new JSONObject(jsonString);

            JSONObject data = (JSONObject) jObject.get("data");

            JSONArray jArray = (JSONArray) data.get("timings");

            outputTimings(jArray);

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
        TextView prayerTimes = (TextView) findViewById(R.id.prayerTimes);
        prayerTimes.setText(result);
    }

    protected void outputTimings(JSONArray jsonArray){
        String[] prayers= {"Fajr", "Sunrise", "Dhuhr", "Asr", "Sunset", "Maghrib", "Isha", "Imsak", "Midnight"};
        try{
            for(int i = 0; i < jsonArray.length(); i++){
                JSONObject cityObject =
                        jsonArray.getJSONObject(i);
                result = result +  prayers[i] + " : "+
                         cityObject.getString(prayers[i]) + "\n";
            }

I get this error that points towards line 85 (the JSONObject jObject = new JSONObject(jsonString); line)

06-17 00:24:15.973 2866-2907/azanmute.android.com.azanmute W/System.err: org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject 06-17 00:24:15.973 2866-2907/azanmute.android.com.azanmute W/System.err: at org.json.JSON.typeMismatch(JSON.java:111) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at org.json.JSONObject.(JSONObject.java:160) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at org.json.JSONObject.(JSONObject.java:173) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at azanmute.android.com.azanmute.MainActivity$SaveTheFeed.doInBackground(MainActivity.java:85) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at azanmute.android.com.azanmute.MainActivity$SaveTheFeed.doInBackground(MainActivity.java:60) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:305) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at java.lang.Thread.run(Thread.java:761)

So my understanding is that Im pointing towards the data incorrectly or mixed up JSONObjects with JSONArrays. Ive already tried both this and this but still receive the same error.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Fencer300
  • 3
  • 1
  • 6
  • From the exception, I'd say the problem is your String jsonString is not a valid JSON string. Can you put a debug here and provide the exact value of jsonString just before l. 85? – Sir4ur0n Jun 16 '17 at 22:39
  • Just print what you are getting in HTTP response to be sure the URL sends you a valid json response – Zakir Jun 16 '17 at 22:40
  • So which is line 85 of `MainActivity.java`? It's *always* useful to reduce things to a [mcve] - there's a lot of irrelevant code in your question at the moment. – Jon Skeet Jun 16 '17 at 22:47
  • 1
    Aside from anything else, `timings` *isn't* an array - it's another object... – Jon Skeet Jun 16 '17 at 22:48
  • Your json string on the top is correct, but the error log is say that it's not correct. Then let's use the debugger to print out the jsonString before the `new JSONObject(jsonString);` to check it out – TuyenNTA Jun 16 '17 at 22:49
  • Bear with me please :D I'm still new at this. I added Log.d(TAG, jsonString); and it gave me this: **Method not allowed. Must be one of: GET** – Fencer300 Jun 17 '17 at 01:19
  • once try it -> JSONObject jObject = new JSONObject(jsonString.toString()); – Aashutosh Kumar Jun 17 '17 at 05:57
  • timings is not an array so parse it in an object – Aashutosh Kumar Jun 17 '17 at 06:02

1 Answers1

1

You haven't confused JSON Object and JSON Array in this case. This is definitely a JSONObject.

It's possible that you've added 'invisible' characters to your string that the JSONObject constructor doesn't like (i.e. "\n"). Try this:

JSONObject jObject = new JSONObject(jsonString.substring(jsonString.indexOf("{"), jsonString.lastIndexOf("}") + 1));

Also please note that "timings" is also a JSONObject and not a JSONArray. Example of a JSONArray, where "cars" is the JSONArray:

{"name":"John","age":30,"cars":[ "Ford", "BMW", "Fiat" ]}
Dan Carter
  • 433
  • 4
  • 14
  • I went ahead and I try adding your line. It still errors but this time its different error: `org.json.JSONException: Unterminated object at character 84 of { padding:30px; font:12px/1.5 Helvetica,Arial,Verdana,sans-serif; } h1{ margin:0; font-weight:normal; line-height:48px; }` with the issue remaining in the same line – Fencer300 Jun 17 '17 at 01:24
  • @Fencer300 could you post the error for our information? Edit: thanks – Dan Carter Jun 17 '17 at 01:26
  • @Fencer300 your HTTP request isn't returning a valid JSON, it's returning the HTML page content. – cнŝdk Jun 17 '17 at 01:28
  • Haha screw me. [This](http://api.aladhan.com/timingsByCity?city=Dubai&country=AE&method=2) is exactly what I have it requesting. Where did I go wrong? – Fencer300 Jun 17 '17 at 01:30
  • See the documentation for JSONObject here: https://stleary.github.io/JSON-java/org/json/JSONObject.html#JSONObject-java.lang.String- The issue is almost certainly with your JSON. Try printing/logging whatever comes back into your jsonString and pasting it into a tool like https://jsonlint.com/ to check it is valid. – Dan Carter Jun 17 '17 at 01:38
  • @DanCarter I did and it prints out just fine. I double checked the source of the api page and it has zero html in it so im confused why im getting an html error – Fencer300 Jun 21 '17 at 15:47