-1

I'm trying to get the longitude and the latitude through giving in a string and sending that to google geocode and getting it back with JSON. But whenever I run this code I'm getting a NetworkOnMainThreadException. Why is that? How do I solve this problem?

public class SearchAddressActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search_on_address);

        getLocationInfo("New Cross rd SE146AS London");
    }


    public JSONObject getLocationInfo(String address) {

        address = address.replaceAll(" ", "%20");
        Double lon = new Double(0);
        Double lat = new Double(0);
        HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?address="+ address + "&sensor=false");
        HttpClient client = new DefaultHttpClient();
        HttpResponse response;
        StringBuilder stringBuilder = new StringBuilder();

        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            InputStream stream = entity.getContent();
            int b;
            while ((b = stream.read()) != -1) {
                stringBuilder.append((char) b);
            }
        } catch (ClientProtocolException e) {
        } catch (IOException e) {
        }

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = new JSONObject(stringBuilder.toString());
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            lon = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lng");

            lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lat");

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Log.e("LON", String.valueOf(lon));
        Log.e("LAT", String.valueOf(lat));
        return jsonObject;
    }   
}

Logcat

06-14 00:38:21.675: E/AndroidRuntime(18999): FATAL EXCEPTION: main
06-14 00:38:21.675: E/AndroidRuntime(18999): java.lang.RuntimeException: Unable to start activity ComponentInfo{eu.mysite.www/eu.mysite.www.SearchAddressActivity}: android.os.NetworkOnMainThreadException
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread.access$600(ActivityThread.java:140)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.os.Looper.loop(Looper.java:137)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread.main(ActivityThread.java:4898)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at java.lang.reflect.Method.invokeNative(Native Method)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at java.lang.reflect.Method.invoke(Method.java:511)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at dalvik.system.NativeStart.main(Native Method)
06-14 00:38:21.675: E/AndroidRuntime(18999): Caused by: android.os.NetworkOnMainThreadException
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at eu.mysite.www.SearchAddressActivity.getLocationInfo(SearchAddressActivity.java:47)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at eu.mysite.www.SearchAddressActivity.onCreate(SearchAddressActivity.java:32)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.Activity.performCreate(Activity.java:5206)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083)
06-14 00:38:21.675: E/AndroidRuntime(18999):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
06-14 00:38:21.675: E/AndroidRuntime(18999):    ... 11 more
mXX
  • 3,595
  • 12
  • 44
  • 61

2 Answers2

2

The error says it all, you should'nt perform network actions on the main thread.
Read this page about processes and threads and how to use them
and this page about how to use the network correctly on a different thread

example: (from Android Developers)

 // Uses AsyncTask to create a task away from the main UI thread. This task takes a 
 // URL string and uses it to create an HttpUrlConnection. Once the connection
 // has been established, the AsyncTask downloads the contents of the webpage as
 // an InputStream. Finally, the InputStream is converted into a string, which is
 // displayed in the UI by the AsyncTask's onPostExecute method.
 private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {

        // params comes from the execute() call: params[0] is the url.
        try {
            return downloadUrl(urls[0]);
        } catch (IOException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        textView.setText(result);
   }
}
Victor
  • 706
  • 2
  • 7
  • 20
1

The important line in the error log is:

android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)

It says that "something" is blocking this request - specifically, the operating system (thanks Brian Roach for making that clear). You have to explicitly put the network request in a different thread than the UI thread - otherwise your UI will hang until the network responds.

See the answer by Victor Lap for an example of how to make the request properly.

I would also urge you to properly URLencode your query - "space" isn't the only character that can cause trouble...

Floris
  • 45,857
  • 6
  • 70
  • 122
  • 2
    Yeah, that "something" is *Android*. The exception says exactly what the problem is (And fiddling with the URL isn't going to help). They've made it so newbies can't shoot themselves in the foot tying up the UI thread with (blocking) network calls. – Brian Roach Jun 13 '13 at 23:00
  • 1
    @BrianRoach - thanks for your comment. Improving my answer now... – Floris Jun 13 '13 at 23:05
  • (I wasn't the downvoter, BTW, or I'd have cancelled it) – Brian Roach Jun 13 '13 at 23:11
  • @BrianRoach - that's OK :-) . The point you made was valid, and the initial answer could be considered insufficient... – Floris Jun 13 '13 at 23:13