2014-01-25 4 views
-2

Раньше у меня были мои карты google, работающие над моим приложением. Теперь я добавил код для получения с моего php-сервера, и теперь он сбой, и я не знаю, почему. Я убедился, что JSON верен. Предполагается, что вы должны связаться с моим сервером, получить список мест и ввести их на карте с помощью маркеров. Я также попытался сделать это в Async, но после поиска нашел, что я не могу изменить интерфейс пользователя из фона.Android google map crashes

МОЙ MAP.JAVA

public class Map extends FragmentActivity implements OnInfoWindowClickListener 
{  
    private GoogleMap map; 
    private int zoomLevel = 10; 
    static JSONObject object =null; 

// flag for Internet connection status 
    Boolean isInternetPresent = false; 

    // Connection detector class 
    Connection cd; 

public boolean onCreateOptionsMenu(Menu menu) 
{ 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.mapnav, menu); 
     return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) 
{  
    switch (item.getItemId()) 
    { 
    case R.id.action_add: 
     // Single menu item is selected do something 
     // Ex: launching new activity/screen or show alert message 
     Toast.makeText(this, "Add place is Selected", Toast.LENGTH_SHORT).show(); 
     Intent A = new Intent(this, Add.class); 
     startActivity(A); 
     return true; 

    case R.id.action_events: 
     // Single menu item is selected do something 
     // Ex: launching new activity/screen or show alert message 
     Toast.makeText(this, "Events is Selected", Toast.LENGTH_SHORT).show(); 
     Intent E = new Intent(this, Events.class); 
     startActivity(E); 
     return true; 

    case R.id.action_map: 
     Toast.makeText(this, "Map is Selected", Toast.LENGTH_SHORT).show(); 
     Intent M = new Intent(this, Map.class); 
     startActivity(M); 
     return true; 

    case R.id.action_chat: 
     Toast.makeText(this, "Chat is Selected", Toast.LENGTH_SHORT).show(); 
     Intent c = new Intent(this, Chat.class); 
     startActivity(c); 
     return true; 

    case R.id.action_settings: 
     Toast.makeText(this, "Settings is Selected", Toast.LENGTH_SHORT).show(); 
     return true; 

    default: 
     return super.onOptionsItemSelected(item); 
    } 
}  

    protected void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map_layout); 

    JsonParser jsonParser = new JsonParser(); 
    String json = jsonParser.getJSONFromUrl("http://www.mywebsite.com/test.json"); 

    if (json != null) 
    { 
     try 
     { 
      JSONObject parent = new JSONObject(json); 
      JSONArray eventDetails = parent.getJSONArray("maps"); 

      for(int i=0; i < eventDetails.length(); i++) 
      { 
       object = eventDetails.getJSONObject(i); 

       String getName = object.getString("name"); 
       String getAddy =object.getString("addy"); 
       String getHours = object.getString("hours"); 
       String getDesc = object.getString("desc"); 
       String getLat = object.getString("lat"); 
       String getLong = object.getString("long"); 

       Log.e("JSON", "> " + getName + getAddy + getHours + getDesc + getLat + getLong); 

       // creating connection detector class instance 
       cd = new Connection(getApplicationContext()); 

       try 
       { 
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 

        Criteria criteria = new Criteria(); 

        // Get name of best provider 
        String provider = locationManager.getBestProvider(criteria, true); 

        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) 
           .getMap(); 

        if (map!=null) 
        { 
         map.getUiSettings().setCompassEnabled(true); 
         map.setTrafficEnabled(true); 
         map.setMyLocationEnabled(true); 

         // My current location 
         Location myloc = locationManager.getLastKnownLocation(provider); 

         // Get latitude of current location 
         double latitude = myloc.getLatitude(); 
         // Get longitude of current location 
         double longitude = myloc.getLongitude(); 

         double lat = Double.valueOf(getLat); 
         double lng = Double.valueOf(getLong); 

         // create latlng 
         LatLng mylocation = new LatLng(latitude, longitude); 

         // Move the camera instantly to defaultLatLng. 
         map.moveCamera(CameraUpdateFactory.newLatLngZoom(mylocation, zoomLevel)); 

         LatLng location = new LatLng(lat, lng); 

         map.addMarker(new MarkerOptions().position(location) 
           .title(getName) 
           .snippet(getHours) 
           .icon(BitmapDescriptorFactory 
             .fromResource(R.drawable.icon))); 

         // map.setOnInfoWindowClickListener(this); 
        } 
       } 
       catch (NullPointerException e) 
       { 
        e.printStackTrace(); 
       } 
       } 
      } 
     catch (JSONException e) 
     { 
      // TODO Auto-generated catch block 
      Log.e("Json Error", "Error: " + e.toString()); 
       e.printStackTrace(); 
     } 
    } 
    } 

    @SuppressWarnings("deprecation") 
    public void showAlertDialog(Context context, String title, String message, Boolean status) { 
     AlertDialog alertDialog = new AlertDialog.Builder(context).create(); 

     // Setting Dialog Title 
     alertDialog.setTitle(title); 

     // Setting Dialog Message 
     alertDialog.setMessage(message); 

     // Setting alert dialog icon 
     alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail); 

     // Setting OK Button 
     alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) 
      { 
       Intent intent = new Intent(getApplicationContext(), Navigation.class); 

       startActivity(intent); 
      } 
     }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 

    @Override 
    public void onPause() 
    { 
       if (map != null) 
       { 
           map.setMyLocationEnabled(false); 
           map.setTrafficEnabled(false); 
       } 
       super.onPause(); 
    } 

    @Override 
    public void onInfoWindowClick(Marker marker) 
    { 
       Intent intent = new Intent(this, Map_layout.class); 
       intent.putExtra("snippet", marker.getSnippet()); 
       intent.putExtra("title", marker.getTitle()); 
       intent.putExtra("position", marker.getPosition()); 
       startActivity(intent); 
    } 

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

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

     @Override 
     protected Void doInBackground(Void... arg0) 
     { 
      return null; 
     } 
     } 
} 

МОЙ LogCat

01-25 18:46:36.142: E/AndroidRuntime(7482): FATAL EXCEPTION: main 
01-25 18:46:36.142: E/AndroidRuntime(7482): Process: com.databasedemo, PID: 7482 
01-25 18:46:36.142: E/AndroidRuntime(7482): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.databasedemo/com.databasedemo.Map}: android.os.NetworkOnMainThreadException 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread.access$800(ActivityThread.java:135) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.os.Handler.dispatchMessage(Handler.java:102) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.os.Looper.loop(Looper.java:136) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread.main(ActivityThread.java:5017) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at java.lang.reflect.Method.invoke(Method.java:515) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at dalvik.system.NativeStart.main(Native Method) 
01-25 18:46:36.142: E/AndroidRuntime(7482): Caused by: android.os.NetworkOnMainThreadException 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at java.net.InetAddress.getAllByName(InetAddress.java:214) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnec tionOperator.java:137) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at com.databasedemo.JsonParser.getJSONFromUrl(JsonParser.java:35) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at com.databasedemo.Map.onCreate(Map.java:97) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.Activity.performCreate(Activity.java:5231) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 
01-25 18:46:36.142: E/AndroidRuntime(7482):  ... 11 more 

// редактирования.К работает в фоновом режиме ...

public class Map extends FragmentActivity implements OnInfoWindowClickListener 
{  
    private GoogleMap map; 
    private int zoomLevel = 10; 
    static JSONObject object =null; 

// flag for Internet connection status 
    Boolean isInternetPresent = false; 

    // Connection detector class 
    Connection cd; 

public boolean onCreateOptionsMenu(Menu menu) 
{ 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.mapnav, menu); 
     return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) 
{  
    switch (item.getItemId()) 
    { 
    case R.id.action_add: 
     // Single menu item is selected do something 
     // Ex: launching new activity/screen or show alert message 
     Toast.makeText(this, "Add place is Selected", Toast.LENGTH_SHORT).show(); 
     Intent A = new Intent(this, Add.class); 
     startActivity(A); 
     return true; 

    case R.id.action_events: 
     // Single menu item is selected do something 
     // Ex: launching new activity/screen or show alert message 
     Toast.makeText(this, "Events is Selected", Toast.LENGTH_SHORT).show(); 
     Intent E = new Intent(this, Events.class); 
     startActivity(E); 
     return true; 

    case R.id.action_map: 
     Toast.makeText(this, "Map is Selected", Toast.LENGTH_SHORT).show(); 
     Intent M = new Intent(this, Map.class); 
     startActivity(M); 
     return true; 

    case R.id.action_chat: 
     Toast.makeText(this, "Chat is Selected", Toast.LENGTH_SHORT).show(); 
     Intent c = new Intent(this, Chat.class); 
     startActivity(c); 
     return true; 

    case R.id.action_settings: 
     Toast.makeText(this, "Settings is Selected", Toast.LENGTH_SHORT).show(); 
     return true; 

    default: 
     return super.onOptionsItemSelected(item); 
    } 
}  

    protected void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map_layout); 
    new PrefetchData().execute(); 
    } 

    @SuppressWarnings("deprecation") 
    public void showAlertDialog(Context context, String title, String message, Boolean status) { 
     AlertDialog alertDialog = new AlertDialog.Builder(context).create(); 

     // Setting Dialog Title 
     alertDialog.setTitle(title); 

     // Setting Dialog Message 
     alertDialog.setMessage(message); 

     // Setting alert dialog icon 
     alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail); 

     // Setting OK Button 
     alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) 
      { 
       Intent intent = new Intent(getApplicationContext(), Navigation.class); 

       startActivity(intent); 
      } 
     }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 

    @Override 
    public void onPause() 
    { 
       if (map != null) 
       { 
           map.setMyLocationEnabled(false); 
           map.setTrafficEnabled(false); 
       } 
       super.onPause(); 
    } 

    @Override 
    public void onInfoWindowClick(Marker marker) 
    { 
       Intent intent = new Intent(this, Map_layout.class); 
       intent.putExtra("snippet", marker.getSnippet()); 
       intent.putExtra("title", marker.getTitle()); 
       intent.putExtra("position", marker.getPosition()); 
       startActivity(intent); 
    } 

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

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

     @Override 
     protected Void doInBackground(Void... arg0) 
     { 
      JsonParser jsonParser = new JsonParser(); 
      String json = jsonParser.getJSONFromUrl("http://www.mywebsite.com/test.json"); 

      if (json != null) 
      { 
       try 
       { 
        JSONObject parent = new JSONObject(json); 
        JSONArray eventDetails = parent.getJSONArray("maps"); 

        for(int i=0; i < eventDetails.length(); i++) 
        { 
         object = eventDetails.getJSONObject(i); 

         String getName = object.getString("name"); 
         String getAddy =object.getString("addy"); 
         String getHours = object.getString("hours"); 
         String getDesc = object.getString("desc"); 
         String getLat = object.getString("lat"); 
         String getLong = object.getString("long"); 

         Log.e("JSON", "> " + getName + getAddy + getHours + getDesc + getLat + getLong); 

         // creating connection detector class instance 
         cd = new Connection(getApplicationContext()); 

         try 
         { 
          LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 

          Criteria criteria = new Criteria(); 

          // Get name of best provider 
          String provider = locationManager.getBestProvider(criteria, true); 

          map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) 
             .getMap(); 

          if (map!=null) 
          { 
           map.getUiSettings().setCompassEnabled(true); 
           map.setTrafficEnabled(true); 
           map.setMyLocationEnabled(true); 

           // My current location 
           Location myloc = locationManager.getLastKnownLocation(provider); 

           // Get latitude of current location 
           double latitude = myloc.getLatitude(); 
           // Get longitude of current location 
           double longitude = myloc.getLongitude(); 

           double lat = Double.valueOf(getLat); 
           double lng = Double.valueOf(getLong); 

           // create latlng 
           LatLng mylocation = new LatLng(latitude, longitude); 

           // Move the camera instantly to defaultLatLng. 
           map.moveCamera(CameraUpdateFactory.newLatLngZoom(mylocation, zoomLevel)); 

           LatLng location = new LatLng(lat, lng); 

           map.addMarker(new MarkerOptions().position(location) 
             .title(getName) 
             .snippet(getHours) 
             .icon(BitmapDescriptorFactory 
               .fromResource(R.drawable.icon))); 

           // map.setOnInfoWindowClickListener(this); 
          } 
         } 
         catch (NullPointerException e) 
         { 
          e.printStackTrace(); 
         } 
         } 
        } 
       catch (JSONException e) 
       { 
        // TODO Auto-generated catch block 
        Log.e("Json Error", "Error: " + e.toString()); 
         e.printStackTrace(); 
       } 
      } 
      return null; 
     } 
     } 
} 

// LOG CAT для обкатки ФОНЕ

01-25 18:58:20.042: E/AndroidRuntime(7593): FATAL EXCEPTION: AsyncTask #1 
01-25 18:58:20.042: E/AndroidRuntime(7593): Process: com.databasedemo, PID: 7593 
01-25 18:58:20.042: E/AndroidRuntime(7593): java.lang.RuntimeException: An error occured while executing doInBackground() 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at android.os.AsyncTask$3.done(AsyncTask.java:300) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.lang.Thread.run(Thread.java:841) 
01-25 18:58:20.042: E/AndroidRuntime(7593): Caused by: java.lang.IllegalStateException: Not on the main thread 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at maps.aq.o.b(Unknown Source) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at maps.ak.g.b(Unknown Source) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at maps.af.al.k(Unknown Source) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at clz.onTransact(SourceFile:304) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at android.os.Binder.transact(Binder.java:361) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.getUiSettings(Unknown Source) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at com.google.android.gms.maps.GoogleMap.getUiSettings(Unknown Source) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at com.databasedemo.Map$PrefetchData.doInBackground(Map.java:198) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at com.databasedemo.Map$PrefetchData.doInBackground(Map.java:1) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at android.os.AsyncTask$2.call(AsyncTask.java:288) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
01-25 18:58:20.042: E/AndroidRuntime(7593):  ... 4 more 

ответ

0

Правильный способ сделать это с помощью AsyncTask, как уже упоминалось. В AsyncTask есть 3 ключевых компонента, вам понадобятся два из них. Третий - это прогресс, который вам не кажется нужным, поскольку вы делаете только один сетевой вызов. Два вы будете использовать, являются:

  • doInBackground - Это где материал, который занимает много времени, как сетевые операции, должно произойти. Обычно вы найдете что-то отсюда, чтобы перейти к основному потоку, например, к растровому или струнному объекту или, возможно, даже к чему-то еще.
  • onPostExecute - Здесь находится материал UI. Android позволяет только одному потоку получать доступ к пользовательскому интерфейсу, все остальные потоки должны передавать материал в поток пользовательского интерфейса для выполнения работы или работать с пользовательским интерфейсом. Оказывается, onPostExecute всегда запускается в потоке пользовательского интерфейса.

Все, что вам нужно сделать, это выяснить, какая часть этого является сетевым подключением, а какая часть - операции пользовательского интерфейса, а также что нужно перетекать между ними, чтобы заставить ее работать. На рисунке Android API docs показан пример того, как это сделать.

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
     int count = urls.length; 
     long totalSize = 0; 
     for (int i = 0; i < count; i++) { 
      totalSize += Downloader.downloadFile(urls[i]); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
     showDialog("Downloaded " + result + " bytes"); 
    } 
} 
0
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.databasedemo/com.databasedemo.Map}: android.os.NetworkOnMainThreadException 

Выполняется сетевая операция на UI Thread. Начиная с API 11 у вас больше не будет длительных задач на UI Thread. У вас есть AsyncTask, но вы его не используете.

В обновленном вопросе вы используете AsyncTask, но вы пытаетесь манипулировать элементами пользовательского интерфейса с фона Thread. Вы должны использовать AsyncTaskonPostExecute() для обновления пользовательского интерфейса.

+0

Но когда я положил его на задний план в AsyncTask, я также получаю ошибки. Позвольте мне запустить его в фоновом режиме и опубликуйте этот лог-кот. – Jayce

+1

Это потому, что вам нужно научиться правильно реализовывать 'AsyncTask'. – Emmanuel

+0

Посмотрите мой обновленный ответ. – Emmanuel