0

I'm sorry for the noob question but I'm just stumped as to how to approach this issue...

1: I am receiving this error when testing on usb attached phone but not when on AVD when search is executed.

Error parsing data org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject

2: While running in AVD, the first JSON search is successful but once backed out and attempted to access a new search the result is empty. Below is the JSON list activity that is instantiated after the search:

    package com.example.georgiahistoricalmarkers;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class MainListActivity extends ListActivity {

    // url to make request
    private static String url = "http://www.georgiaplanning.com/DCAMarkerService/dcamarkerservice.markerservice.svc/rest/Locations?SearchText=";

    // JSON Node names
    private static final String TAG_MARKERSINRANGE = "GetAllMarkersInRangeResult";
    private static final String TAG_DCAID = "DCA_ID";
    private static final String TAG_MARKERTITLE = "MarkerTitle";
    private static final String TAG_MARKERLATITUDE = "MarkerLatitude";
    private static final String TAG_MARKERLONGITUDE = "MarkerLongitude";

    // contacts JSONArray
    JSONArray markersInRange = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String value = null;
        Bundle extras = getIntent().getExtras();
        if(extras != null){
            value = extras.getString("markerSearch");
        }

        url = (url+value);

        // Hashmap for ListView
        ArrayList<HashMap<String, String>> markerList = new ArrayList<HashMap<String, String>>();

        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        try {
            // Getting Array of Contacts
            markersInRange = json.getJSONArray(TAG_MARKERSINRANGE);

            // looping through All Contacts
            for(int i = 0; i < markersInRange.length(); i++){
                JSONObject c = markersInRange.getJSONObject(i);

                // Storing each json item in variable
                int dcaid = c.getInt(TAG_DCAID);
                String markertitle = c.getString(TAG_MARKERTITLE);
                double markerlongitude = c.getDouble(TAG_MARKERLATITUDE);
                double markerlatitude = c.getDouble(TAG_MARKERLONGITUDE);

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

                // adding each child node to HashMap key => value
                map.put(TAG_DCAID, Integer.toString(dcaid));
                map.put(TAG_MARKERTITLE, markertitle);
                map.put(TAG_MARKERLONGITUDE, Double.toString(markerlongitude));
                map.put(TAG_MARKERLONGITUDE, Double.toString(markerlatitude));

                // adding HashList to ArrayList
                markerList.add(map);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        /**
         * Updating parsed JSON data into ListView
         * */
        ListAdapter adapter = new SimpleAdapter(this, markerList,
                R.layout.list_item,
                new String[] { TAG_MARKERTITLE, TAG_DCAID }, new int[] {
                        R.id.title, R.id.dcaid });

        setListAdapter(adapter);

        // selecting single ListView item
        ListView lv = getListView();

        // Launching new screen on Selecting Single ListItem
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // getting values from selected ListItem
                String passId = ((TextView) view.findViewById(R.id.dcaid)).getText().toString();

                // Starting new intent
                Intent in = new Intent(getApplicationContext(), SingleItemActivity.class);
                in.putExtra(TAG_DCAID, passId);
                startActivity(in);

            }
        });



    }

}

Below is my Manifest if that might help understand the issue:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.georgiahistoricalmarkers"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.georgiahistoricalmarkers.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".MainListActivity"
        android:label="MainListActivity" >
    </activity>
    <activity
        android:name=".SingleItemActivity"
        android:label="SingleItemActivity" >
    </activity>
</application>

  • Just to clarify: this issue is that it will create a json list but when asked to create it again (another search request) the list will not fill. AND it has the exception, stated above when running on a phone instead of a virtual device. – user2836396 Oct 10 '13 at 18:51

1 Answers1

0

we should add "application/x-www-form-urlencoded" in your http request headers.

In your case you're waiting to receive a json, so add this:

    httpost.setHeader("Content-type", "application/json;charset=utf8");
    request.setHeader("Accept", "application/json");

The problem is that you're receiving the response as html instead of json. Hope this works for you, please let me know if it does.

/* EDIT */ Use this parser:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

public JSONObject getJSONFromUrl(String url) {

    // Making HTTP request
    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        httpGet.setHeader("Content-type", "application/json;charset=utf8");
        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();

        is = httpEntity.getContent();

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

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON String
    return jObj;

}

You should also do the request in a thread or asyncthread. Else, you will be given a network exception in devices from 4.0 to above. This is how I've solved your activity:

    public class MainListActivity extends ListActivity {



// url to make request
        private static String url = "http://www.georgiaplanning.com/DCAMarkerService/dcamarkerservice.markerservice.svc/rest/Locations?SearchText=";

        // JSON Node names
        private static final String TAG_MARKERSINRANGE = "GetAllMarkersInRangeResult";
        private static final String TAG_DCAID = "DCA_ID";
        private static final String TAG_MARKERTITLE = "MarkerTitle";
        private static final String TAG_MARKERLATITUDE = "MarkerLatitude";
        private static final String TAG_MARKERLONGITUDE = "MarkerLongitude";

        // contacts JSONArray
        JSONArray markersInRange = null;

        private ArrayList<HashMap<String, String>> markerList;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            String value = null;
            Bundle extras = getIntent().getExtras();
            if (extras != null) {
                value = extras.getString("markerSearch");
            }

            url = (url + value);

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

            new DoMarkersSearchTask().execute();

        }

        class DoMarkersSearchTask extends AsyncTask<Void, Void, Void> {

            @Override
            protected Void doInBackground(Void... params) {
                // Creating JSON Parser instance
                JSONParser jParser = new JSONParser();

                // getting JSON string from URL
                JSONObject json = jParser.getJSONFromUrl(url);

                try {
                    // Getting Array of Contacts
                    markersInRange = json.getJSONArray(TAG_MARKERSINRANGE);

                    // looping through All Contacts
                    for (int i = 0; i < markersInRange.length(); i++) {
                        JSONObject c = markersInRange.getJSONObject(i);

                        // Storing each json item in variable
                        int dcaid = c.getInt(TAG_DCAID);
                        String markertitle = c.getString(TAG_MARKERTITLE);
                        double markerlongitude = c.getDouble(TAG_MARKERLATITUDE);
                        double markerlatitude = c.getDouble(TAG_MARKERLONGITUDE);

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

                        // adding each child node to HashMap key => value
                        map.put(TAG_DCAID, Integer.toString(dcaid));
                        map.put(TAG_MARKERTITLE, markertitle);
                        map.put(TAG_MARKERLONGITUDE, Double.toString(markerlongitude));
                        map.put(TAG_MARKERLONGITUDE, Double.toString(markerlatitude));

                        // adding HashList to ArrayList
                        markerList.add(map);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                /**
                 * Updating parsed JSON data into ListView
                 * */
                ListAdapter adapter = new SimpleAdapter(getApplicationContext(), markerList, R.layout.list_item,
                        new String[] { TAG_MARKERTITLE, TAG_DCAID }, new int[] { R.id.title, R.id.dcaid });

                setListAdapter(adapter);

                // selecting single ListView item
                ListView lv = getListView();

                // Launching new screen on Selecting Single ListItem
                lv.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        // getting values from selected ListItem
                        String passId = ((TextView) view.findViewById(R.id.dcaid)).getText().toString();

                        // Starting new intent
                        Intent in = new Intent(getApplicationContext(), SingleItemActivity.class);
                        in.putExtra(TAG_DCAID, passId);
                        startActivity(in);

                    }
                });
            }

        }

    }

Hope this finally works for you :)

  • Have you ever worked with http requests? I share a link where you'll be able to see how to buffer content from a url, and then parse this json String as an object. Maybe I am wrong, but what I am sure is that as you can see, in your error, it's trying to parse html content. By doing all the work "by hand" instead of calling jparser.getJsonFromUrl(url) you'll see the content of the string and adding in the httpget request of the link what I posted in the comment above, you'll ensure that you're asking specifically for a json response. http://stackoverflow.com/a/13196451/1483805 – Jonathan Fragoso Oct 10 '13 at 19:41
  • thanks for the help, in my JSONParser class i attempted to do those changes to my httpGet and httpResponse but it still did nothing. I'm not using httpPost or request. – user2836396 Oct 10 '13 at 19:45
  • I moved around my entire JSONParser to match yours and am still getting the same error. It will fill the arraylist on the first search but on subsequent searches the list is empty. – user2836396 Oct 10 '13 at 20:08
  • OK. In this case I am going to try this code and I'll let you know :) – Jonathan Fragoso Oct 12 '13 at 13:38
  • @user2836396 I've tried your code and I it's working now for me. See my edit above and let me know your thoughts :D – Jonathan Fragoso Oct 12 '13 at 15:21
  • Thank you so much for the help, I'm sure this fix will prevent any future errors but the original error still persists. It will load the first jsonarray but the second time its accessed it will be empty. I'm guessing that this is an error outside of these classes if it is working well on your testing. Thank you again for the help! – user2836396 Oct 15 '13 at 21:05
  • @user2836396 in this case it must be problem of configuration, because it's working in my device (Galaxy Nexus) and also on my emulators. So sorry the problem has not been solved :( hope you've been able at least to learn something new around this discussion :) – Jonathan Fragoso Oct 16 '13 at 14:04
  • Thank you for the help and I've learned a lot. Did you use the same manifest? – user2836396 Oct 16 '13 at 19:10
  • @user2836396 no problem, you're welcome. Yes I copied your manifest, so it's the same – Jonathan Fragoso Oct 17 '13 at 08:18