2013-06-13 7 views
-1

J'essaie d'obtenir la longitude et la latitude en donnant une chaîne et en l'envoyant à google geocode et en la récupérant avec JSON. Mais chaque fois que je cours ce code, je reçois un NetworkOnMainThreadException. Pourquoi donc? Comment puis-je résoudre ce problème?Obtenir la latitude et la longitude me donne NetworkOnMainThreadException

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 

Répondre

2

L'erreur dit tout, vous should'nt effectuer des actions de réseau sur le fil principal.
Lire this page sur les processus et les fils et comment les utiliser
et this page sur la façon d'utiliser le réseau correctement sur un autre fil

exemple: (de 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); 
    } 
} 
1

La ligne importante dans le journal d'erreur est:

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

Il dit que "quelque chose" bloque cette demande - en particulier, le système d'exploitation (merci Brian Roach d'avoir rendu cela clair). Vous devez explicitement mettre la requête réseau dans un thread différent de celui de l'interface utilisateur. Dans le cas contraire, votre interface utilisateur se bloquera jusqu'à ce que le réseau réponde.

Voir la réponse de Victor Lap pour un exemple de la façon de faire la demande correctement.

Je vous invite aussi à bien UrlEncode votre requête - « l'espace » est pas le seul personnage qui peut causer des problèmes ...

+2

Ouais, ce "quelque chose" est * Android *. L'exception indique exactement quel est le problème (et jouer avec l'URL ne va pas aider). Ils ont fait en sorte que les débutants ne peuvent pas se tirer eux-mêmes dans le pied attachant le fil de l'interface utilisateur avec (bloquant) les appels réseau. –

+1

@BrianRoach - merci pour votre commentaire. Améliorer ma réponse maintenant ... – Floris

+0

(Je n'étais pas le downvoter, BTW, ou je l'aurais annulé) –

Questions connexes