title: Grab Google Maps markers from external JSON
body: <p>I'm working on a map app for android (Google Maps API 2), my goal is two things. There, some of which I managed to do one.</p>
  
  <p>1: Center and follow the user's position. (Successful)
  2: Get markers from external JSON source and display on the map. As well as update their position continuously.</p>
  
  <p>I found a piece of code here: <a href="https://gist.github.com/saxman/5347195" rel="nofollow">https://gist.github.com/saxman/5347195</a></p>
  
  <p>I put together the code with my code that comes from 1.
  Function 1 still works, but logcat says it can not find the file I have specified. That's because it does not exist.
  I do not know how the JSON structure should look like, CORS is enabled on the server side to fetch JSON should not be any danger.</p>
  
  <p>However, I wonder if anyone knows how the JSON structure should look like, because I do not know how to figure it out. In addition, so maybe this code is not working, hence the question can be updated if the JSON structure is complete, but the markers do not appear, for example.</p>
  
  <p><strong>How would the JSON look like? It's impossible for me to figure out.</strong></p>
  
  <p>MainActivity.java</p>
  
  <pre><code>package com.billstrom.yolo;
  
  import android.annotation.TargetApi;
  import android.app.Dialog;
  import android.location.Criteria;
  import android.location.Location;
  import android.location.LocationListener;
  import android.location.LocationManager;
  import android.os.Build;
  import android.os.Bundle;
  import android.support.v4.app.FragmentActivity;
  import android.view.Menu;
  import android.widget.TextView;
  import android.util.Log;
  
  import com.google.android.gms.common.ConnectionResult;
  import com.google.android.gms.common.GooglePlayServicesUtil;
  import com.google.android.gms.maps.CameraUpdateFactory;
  import com.google.android.gms.maps.GoogleMap;
  import com.google.android.gms.maps.SupportMapFragment;
  import com.google.android.gms.maps.model.LatLng;
  import com.google.android.gms.maps.model.MarkerOptions;
  
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
  
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.net.HttpURLConnection;
  import java.net.URL;
  
  /**
   * 
   */
  
  @TargetApi(Build.VERSION_CODES.GINGERBREAD)
  public class MainActivity extends FragmentActivity implements LocationListener {
  
      private static final String LOG_TAG = "Example";
  
      private static final String SERVICE_URL = "http://codele.se/app/blackcab/drivers.json";
  
      protected GoogleMap map;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          setUpMapIfNeeded();
  
          // Getting Google Play availability status
          int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
  
          // Showing status
          if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
  
              int requestCode = 10;
              Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
              dialog.show();
  
          }else { // Google Play Services are available   
  
              // Getting reference to the SupportMapFragment of activity_main.xml
              SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
  
              // Getting GoogleMap object from the fragment
              map = fm.getMap();
  
              // Enabling MyLocation Layer of Google Map
              map.setMyLocationEnabled(true); 
  
  
  
               // Getting LocationManager object from System Service LOCATION_SERVICE
              LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
  
              // Creating a criteria object to retrieve provider
              Criteria criteria = new Criteria();
  
              // Getting the name of the best provider
              String provider = locationManager.getBestProvider(criteria, true);
  
              // Getting Current Location
              Location location = locationManager.getLastKnownLocation(provider);
  
              if(location!=null){
                      onLocationChanged(location);
              }
  
              locationManager.requestLocationUpdates(provider, 20000, 0, this);
          }
  
      }
  
       @Override
          protected void onResume() {
              super.onResume();
              setUpMapIfNeeded();
          }
  
       private void setUpMapIfNeeded() {
              if (map == null) {
                  map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                          .getMap();
                  if (map != null) {
                      setUpMap();
                  }
              }
          }
       private void setUpMap() {
              // Retrieve the city data from the web service
              // In a worker thread since it's a network operation.
              new Thread(new Runnable() {
                  public void run() {
                      try {
                          retrieveAndAddCities();
                      } catch (IOException e) {
                          Log.e(LOG_TAG, "Cannot retrive cities", e);
                          return;
                      }
                  }
              }).start();
          }
  
          protected void retrieveAndAddCities() throws IOException {
              HttpURLConnection conn = null;
              final StringBuilder json = new StringBuilder();
              try {
                  // Connect to the web service
                  URL url = new URL(SERVICE_URL);
                  conn = (HttpURLConnection) url.openConnection();
                  InputStreamReader in = new InputStreamReader(conn.getInputStream());
  
                  // Read the JSON data into the StringBuilder
                  int read;
                  char[] buff = new char[1024];
                  while ((read = in.read(buff)) != -1) {
                      json.append(buff, 0, read);
                  }
              } catch (IOException e) {
                  Log.e(LOG_TAG, "Error connecting to service", e);
                  throw new IOException("Error connecting to service", e);
              } finally {
                  if (conn != null) {
                      conn.disconnect();
                  }
              }
  
              // Create markers for the city data.
              // Must run this on the UI thread since it's a UI operation.
              runOnUiThread(new Runnable() {
                  public void run() {
                      try {
                          createMarkersFromJson(json.toString());
                      } catch (JSONException e) {
                          Log.e(LOG_TAG, "Error processing JSON", e);
                      }
                  }
              });
          }
  
          void createMarkersFromJson(String json) throws JSONException {
              // De-serialize the JSON string into an array of city objects
              JSONArray jsonArray = new JSONArray(json);
              for (int i = 0; i &lt; jsonArray.length(); i++) {
                  // Create a marker for each city in the JSON data.
                  JSONObject jsonObj = jsonArray.getJSONObject(i);
                  map.addMarker(new MarkerOptions()
                      .title(jsonObj.getString("name"))
                      .snippet(Integer.toString(jsonObj.getInt("population")))
                      .position(new LatLng(
                              jsonObj.getJSONArray("latlng").getDouble(0),
                              jsonObj.getJSONArray("latlng").getDouble(1)
                       ))
                  );
              }
          }
  
      @Override
      public void onLocationChanged(Location location) {
  
          TextView tvLocation = (TextView) findViewById(R.id.tv_location);
  
          // Getting latitude of the current location
          double latitude = location.getLatitude();
  
          // Getting longitude of the current location
          double longitude = location.getLongitude();     
  
          // Creating a LatLng object for the current location
          LatLng latLng = new LatLng(latitude, longitude);
  
          // Showing the current location in Google Map
          map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
  
          // Zoom in the Google Map
          map.animateCamera(CameraUpdateFactory.zoomTo(15));      
  
  
          // Setting latitude and longitude in the TextView tv_location
          tvLocation.setText("Latitude:" +  latitude  + ", Longitude:"+ longitude );      
  
      }
  
      @Override
      public void onProviderDisabled(String provider) {
          // TODO Auto-generated method stub      
      }
  
      @Override
      public void onProviderEnabled(String provider) {
          // TODO Auto-generated method stub      
      }
  
      @Override
      public void onStatusChanged(String provider, int status, Bundle extras) {
          // TODO Auto-generated method stub      
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.activity_main, menu);
          return true;
      }
  }
  </code></pre>
  
  <p>logcat output</p>
  
  <pre><code>07-01 16:27:40.787: E/Black Cab(17968): Error connecting to service
  07-01 16:27:40.787: E/Black Cab(17968): java.io.FileNotFoundException: http://codele.se/app/blackcab/drivers.json
  07-01 16:27:40.787: E/Black Cab(17968):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
  07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:133)
  07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity$1.run(MainActivity.java:117)
  07-01 16:27:40.787: E/Black Cab(17968):     at java.lang.Thread.run(Thread.java:856)
  07-01 16:27:40.787: E/Black Cab(17968): Cannot retrive cities
  07-01 16:27:40.787: E/Black Cab(17968): java.io.IOException: Error connecting to service
  07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:143)
  07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity$1.run(MainActivity.java:117)
  07-01 16:27:40.787: E/Black Cab(17968):     at java.lang.Thread.run(Thread.java:856)
  07-01 16:27:40.787: E/Black Cab(17968): Caused by: java.io.FileNotFoundException: http://codele.se/app/blackcab/drivers.json
  07-01 16:27:40.787: E/Black Cab(17968):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
  07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:133)
  07-01 16:27:40.787: E/Black Cab(17968):     ... 2 more
  </code></pre>