i am running a web service with some json data which i use to make markers on my map(this gets updated every hour).i want to add button on my android map so that i will refresh the markers data.any idea without changing much of the structure?should i do something on the threads?or restart the activity?
heres is the code
public class MainActivity extends FragmentActivity {
private static final String LOG_TAG = "jsonmap";
private static final String SERVICE_URL = "http://7a27183e.ngrok.com";
public GoogleMap map;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_maps);
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (map == null) {
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
map = mapFragment.getMap();
if (map != null) {
setUpMap();
// new MarkerTask().execute();
}
}
}
private void setUpMap() {
UiSettings settings = map.getUiSettings();
settings.setZoomControlsEnabled(true);
settings.setScrollGesturesEnabled(true);
// 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 < jsonArray.length(); i++) {
// Create a marker for each city in the JSON data.
//.title(jsonObj.getString("pollutant")+" "+jsonObj.getString("network"))
// .snippet(Integer.toString(jsonObj.getInt("numeric_val")))
//DATE!!
JSONObject jsonObj = jsonArray.getJSONObject(i);
map.addMarker(new MarkerOptions()
.title(jsonObj.getString("network") + "\n" + jsonObj.getString("date"))
.snippet(jsonObj.getString("pollutant") + "=" + jsonObj.getString("numeric_val"))
.position(new LatLng(
jsonObj.getDouble("x"),
jsonObj.getDouble("y")))
.icon(BitmapDescriptorFactory.defaultMarker(new Random().nextInt(360)))
);
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoContents(Marker arg0) {
return null;
}
#Override
public View getInfoWindow(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.customlayout, null);
TextView tTitle = (TextView) v.findViewById(R.id.title);
TextView tSnippet = (TextView) v.findViewById(R.id.snippet);
tTitle.setText(arg0.getTitle());
tSnippet.setText(arg0.getSnippet());
return v;
}
});
}
}
}
this is the json structure:
https://gist.githubusercontent.com/anonymous/42af315ab003ab01764d/raw/79b6cf5451038bd2e35c376766e9ab44bd385a02/gistfile2.txt
and a screenshot:
http://imgur.com/WZNC9Oz
I have done some modification in your method named createMarkersFromJson() at line map.addMarker(). Now you can use changeMarkerPosition() to change the position of marker.
HashMap<String, Marker> markerHashMap = new HashMap<>();
void changeMarkerPosition(String key, LatLng latLng) {
markerHashMap.get(key).setPosition(latLng);
}
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 < jsonArray.length(); i++) {
// Create a marker for each city in the JSON data.
//.title(jsonObj.getString("pollutant")+" "+jsonObj.getString("network"))
// .snippet(Integer.toString(jsonObj.getInt("numeric_val")))
//DATE!!
JSONObject jsonObj = jsonArray.getJSONObject(i);
markerHashMap.put("key"+i,(map.addMarker(new MarkerOptions()
.title(jsonObj.getString("network") + "\n" + jsonObj.getString("date"))
.snippet(jsonObj.getString("pollutant") + "=" + jsonObj.getString("numeric_val"))
.position(new LatLng(
jsonObj.getDouble("x"),
jsonObj.getDouble("y")))
.icon(BitmapDescriptorFactory.defaultMarker(new Random().nextInt(360)))
);)
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoContents(Marker arg0) {
return null;
}
#Override
public View getInfoWindow(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.customlayout, null);
TextView tTitle = (TextView) v.findViewById(R.id.title);
TextView tSnippet = (TextView) v.findViewById(R.id.snippet);
tTitle.setText(arg0.getTitle());
tSnippet.setText(arg0.getSnippet());
return v;
}
});
}
Related
I'm using the tutorial for mapbox and I can get geojson files to show just fine. But when trying to use a MultiLine geojson, I keep getting this exception and it doesn't show in my map.
Exception Loading GeoJSON: org.json.JSONException: Value [-84.38482011299999,44.24712923700008,0] at 1 of type org.json.JSONArray cannot be converted to double
I tried changing this line:
if (!TextUtils.isEmpty(type) && type.equalsIgnoreCase("LineString")) {
I changed "LineString" to "MultiLineString" and I still get the same exception. Everything else in my code is the same as tutorial as of right now.
I currently use osmdroid and I have no problems loading my geojson there, so I don't believe it's an issue with my file.
Trying to make the switch to mapbox.
public class MainActivity extends Activity implements OnMapReadyCallback
{
private static final String TAG = "DrawGeojsonLineActivity";
private MapView mapView;
private MapboxMap mapboxMap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mapbox access token is configured here. This needs to be called either in your application
// object or in the same activity which contains the mapview.
Mapbox.getInstance(this, "pk.eyJ1IjoiamViMTkyMDA0IiwiYSI6ImNpbWNyODZyaDAwMmZ1MWx2dHdzcHQ5M2EifQ.IZsMnB3wOYFIaX1A5sy7Mw");
// This contains the MapView in XML and needs to be called after the access token is configured.
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}
#Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
// Load and Draw the GeoJSON
new DrawGeoJson().execute();
}
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
private class DrawGeoJson extends AsyncTask<Void, Void, List<LatLng>> {
#Override
protected List<LatLng> doInBackground(Void... voids) {
List<LatLng> points = new ArrayList<>();
try {
// Load GeoJSON file
InputStream inputStream = getAssets().open("st_helen_trail.geojson");
BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
inputStream.close();
// Parse JSON
JSONObject json = new JSONObject(sb.toString());
JSONArray features = json.getJSONArray("features");
JSONObject feature = features.getJSONObject(0);
JSONObject geometry = feature.getJSONObject("geometry");
if (geometry != null) {
String type = geometry.getString("type");
// Our GeoJSON only has one feature: a line string
if (!TextUtils.isEmpty(type) && type.equalsIgnoreCase("MultiLineString")) {
// Get the Coordinates
JSONArray coords = geometry.getJSONArray("coordinates");
for (int lc = 0; lc < coords.length(); lc++) {
JSONArray coord = coords.getJSONArray(lc);
LatLng latLng = new LatLng(coord.getDouble(1), coord.getDouble(0));
points.add(latLng);
}
}
}
} catch (Exception exception) {
Log.e(TAG, "Exception Loading GeoJSON: " + exception.toString());
}
return points;
}
#Override
protected void onPostExecute(List<LatLng> points) {
super.onPostExecute(points);
if (points.size() > 0) {
// Draw polyline on map
mapboxMap.addPolyline(new PolylineOptions()
.addAll(points)
.color(Color.parseColor("#3bb2d0"))
.width(2));
}
}
}
}
In your onPostExecute() method add this Code..
#Override
protected void onPostExecute(List<LatLng> points) {
super.onPostExecute(points);
if (points.size() > 0) {
LatLng[] dataOfArray = points.toArray(new LatLng[points.size()]);
// Draw polyline on map
mapboxMap.addPolyline(new PolylineOptions()
.addAll(dataOfArray)
.color(Color.parseColor("#3bb2d0"))
.width(2));
}
}
I figured this out about a week ago. This is what I got to work
I removed this:
new DrawGeoJson().execute();
And this:
private class DrawGeoJson extends AsyncTask<Void, Void, List<LatLng>> { #Override protected List<LatLng> doInBackground(Void... voids) { List<LatLng> points = new ArrayList<>(); try { // Load GeoJSON file InputStream inputStream = getAssets().open("st_helen_trail.geojson"); BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); StringBuilder sb = new StringBuilder(); int cp; while ((cp = rd.read()) != -1) { sb.append((char) cp); } inputStream.close(); // Parse JSON JSONObject json = new JSONObject(sb.toString()); JSONArray features = json.getJSONArray("features"); JSONObject feature = features.getJSONObject(0); JSONObject geometry = feature.getJSONObject("geometry"); if (geometry != null) { String type = geometry.getString("type"); // Our GeoJSON only has one feature: a line string if (!TextUtils.isEmpty(type) && type.equalsIgnoreCase("MultiLineString")) { // Get the Coordinates JSONArray coords = geometry.getJSONArray("coordinates"); for (int lc = 0; lc < coords.length(); lc++) { JSONArray coord = coords.getJSONArray(lc); LatLng latLng = new LatLng(coord.getDouble(1), coord.getDouble(0)); points.add(latLng); } } } } catch (Exception exception) { Log.e(TAG, "Exception Loading GeoJSON: " + exception.toString()); } return points; } #Override protected void onPostExecute(List<LatLng> points) { super.onPostExecute(points); if (points.size() > 0) { // Draw polyline on map mapboxMap.addPolyline(new PolylineOptions() .addAll(points) .color(Color.parseColor("#3bb2d0")) .width(2)); } }
Then added the code below inside the "onMapReady"
final AssetManager assetManager = getAssets();
try {
String[] imgPath = assetManager.list("mi_atv");
for (int i = 0; i< imgPath.length; i++) {
InputStream is1 = assetManager.open("mi_atv/" + imgPath[i]);
Log.d(TAG, imgPath[i]);
int size = is1.available();
byte[] buffer = new byte[size];
is1.read(buffer);
is1.close();
String json1 = new String(buffer, "UTF-8");
GeoJsonSource source = new GeoJsonSource(imgPath[i], json1);
map.addSource(source);
atv = new LineLayer(imgPath[i], imgPath[i]);
atv.setProperties(
lineColor(Color.parseColor("#7fff00")),
lineWidth(1.0f)
);
map.addLayer(main.atv);
}
}
catch (Exception exception) {
Log.e(TAG, "Exception Loading GeoJSON: " + exception.toString());
}
The problem is that in case of multilinestring you have an extra array to get.
MULTILINESTRING example:
coordinates": [ [ [ 7.38588715, 44.17675579 ], [ 7.385923192, 44.176754868 ],...
LINESTRING example:
coordinates": [ [ 7.38588715, 44.17675579 ], [ 7.385923192, 44.176754868 ],...
so:
//replace linestring with multilinestring:
if (!TextUtils.isEmpty(type) && type.equalsIgnoreCase("MultiLineString")) {
// get extra array adding .getJSONArray(0)
JSONArray coords = geometry.getJSONArray("coordinates").getJSONArray(0);
for (int lc = 0; lc < coords.length(); lc++) {
Currently I am working with a project to get current latitude and longitude, I got that. Now I want the latitude and longitude send to MySQL database using Android. HTTP part of this program is not working.
LocationManager locationManager;
String mprovider;
String lat="", lon="";
private String Tag="MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1=(Button)findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postData(lat, lon);
}
});
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
mprovider = locationManager.getBestProvider(criteria, false);
if (mprovider != null && !mprovider.equals("")) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(mprovider);
locationManager.requestLocationUpdates(mprovider, 0, 0, this);
if (location != null) {
onLocationChanged(location);
} else
Toast.makeText(getBaseContext(), "No Location Provider Found Check Your Code", Toast.LENGTH_SHORT).show();
}
}
private void postData(String la, String lo) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost htget = new HttpPost("http://192.168.1.2/yy.php/"+la+"/"+lo);
try {
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(htget);
String resp = response.getStatusLine().toString();
Toast.makeText(this, resp, Toast.LENGTH_SHORT).show();
} catch (ClientProtocolException e) {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onLocationChanged(Location location) {
lat = Double.toString(location.getLatitude());
lon = Double.toString(location.getLongitude());
TextView tv = (TextView) findViewById(R.id.textView2);
tv.setText("Your Location is:" + lat + "--" + lon);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
you can send data form android to server over http. here is more details
Use mysql's spatial extensions.
For making tables and using it with Google Maps api refer this:
Using MySQL and PHP with Google Maps
Before you start, I have few questions:
Which version of gmaps API are you working with?
How are you parsing the map marker (lat. long.) data?
How are you triggering the save (lat long/ map marker data event).
Workable method: create a JSON parser for parsing the Marker data (which is the JSON Object here).
public class MarkerJSONParser {
/** gets a JSONObject and returns a list */
public List<HashMap<String,String>> parse(JSONObject jObject){
JSONArray jMarkers = null;
try {
/** gets all the elements in the 'markers' array */
jMarkers = jObject.getJSONArray("markers");
} catch (JSONException e) {
e.printStackTrace();
}
/** enjoining getMarkers with the array of json object
* here each JSON object is a marker
*/
return getMarkers(jMarkers);
}
private List<HashMap<String, String>> getMarkers(JSONArray jMarkers){
int markersCount = jMarkers.length();
List<HashMap<String, String>> markersList = new ArrayList<HashMap<String,String>>();
HashMap<String, String> marker = null;
/** Parsing and adding each marker to the list object */
for(int i=0; i<markersCount;i++){
try {
/** Call getMarker with marker JSON object to parse the marker */
marker = getMarker((JSONObject)jMarkers.get(i));
markersList.add(marker);
}catch (JSONException e){
e.printStackTrace();
}
}
return markersList;
}
/** Parsing the Marker JSON object */
private HashMap<String, String> getMarker(JSONObject jMarker){
HashMap<String, String> marker = new HashMap<String, String>();
String lat = "-NA-";
String lng ="-NA-";
try {
// Latitude extraction
if(!jMarker.isNull("lat")){
lat = jMarker.getString("lat");
}
// Longitude extraction
if(!jMarker.isNull("lng")){
lng = jMarker.getString("lng");
}
marker.put("lat", lat);
marker.put("lng", lng);
} catch (JSONException e) {
e.printStackTrace();
}
return marker;
}
}
Paste this in your MySQL's MainActivity.java:
// enjoining OnClick Event listener for the GoogleMap
mGoogleMap.setOnMapClickListener(new OnMapClickListener() {
#Override
public void onMapClick(LatLng latlng) {
addMarker(latlng);
sendToServer(latlng);
}
});
// enjoining location retrieval
new RetrieveTask().execute();
}
// Marking lat. long. on the GoogleMaps
private void addMarker(LatLng latlng) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latlng);
markerOptions.title(latlng.latitude + "," + latlng.longitude);
mGoogleMap.addMarker(markerOptions);
}
// Enjoining bg thread to save marker inMySQL server
private void sendToServer(LatLng latlng) {
new SaveTask().execute(latlng);
}
// bg thread to save the marker in MySQL server
private class SaveTask extends AsyncTask<LatLng, Void, Void> {
#Override
protected Void doInBackground(LatLng... params) {
String lat = Double.toString(params[0].latitude);
String lng = Double.toString(params[0].longitude);
String strUrl = "http://www.yourserverurllocation.com";
URL url = null;
try {
url = new URL(strUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
connection.getOutputStream());
outputStreamWriter.write("lat=" + lat + "&lng="+lng);
outputStreamWriter.flush();
outputStreamWriter.close();
InputStream iStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new
InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( (line = reader.readLine()) != null){
sb.append(line);
}
reader.close();
iStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
I'm populating a Google map with markers, I don't get errors and my variables are getting their values but it isnt populating any markers. It just show one marker and it is my current location.
here is the code that i call when populating:
private void showData() {
int count = users.length();
for(;i<=count;i++) {
try {
JSONObject jsonObject = users.getJSONObject(i);
maplat = Double.parseDouble(jsonObject.getString(lat));
maplng = Double.parseDouble(jsonObject.getString(lng));
MarkerOptions marker = new MarkerOptions().position(new LatLng(maplat, maplng)).title("Hello Maps");
marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin));
googleMap.addMarker(marker);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
My whole code:
public class MapActivity extends AppCompatActivity{
private GoogleMap googleMap;
double curLat;
double curLng;
double maplat;
double maplng;
private static final String JSON_ARRAY = "result";
private static final String lat= "lat";
private static final String lng = "lng";
private JSONArray users = null;
private String q;
private static final String GET_URL = "http://testevent.site88.net/getlocation.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
GPSTracker gps = new GPSTracker(this);
curLat = gps.getLatitude();
curLng = gps.getLongitude();
try {
// Loading map
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
}
private void extractJSON(){
try {
JSONObject jsonObject = new JSONObject(q);
users = jsonObject.getJSONArray(JSON_ARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
private void showData() {
int count = users.length();
for(int i = 0;i<=count;i++) {
try {
JSONObject jsonObject = users.getJSONObject(i);
maplat = Double.parseDouble(jsonObject.getString(lat));
maplng = Double.parseDouble(jsonObject.getString(lng));
MarkerOptions marker = new MarkerOptions().position(new LatLng(maplat, maplng)).title("Hello Maps");
marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin));
googleMap.addMarker(marker);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private void getJSON(String url) {
class GetJSON extends AsyncTask<String, Void, String>{
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(MapActivity.this, "Please Wait...",null,true,true);
}
#Override
protected String doInBackground(String... params) {
String uri = params[0];
BufferedReader bufferedReader = null;
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while((json = bufferedReader.readLine())!= null){
sb.append(json+"\n");
}
return sb.toString().trim();
}catch(Exception e){
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
q=s;
extractJSON();
showData();
MarkerOptions marker = new MarkerOptions().position(new LatLng(curLat, curLng)).title("Hello Maps");
// Changing marker icon
marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin));
// adding marker
googleMap.addMarker(marker);
}
}
GetJSON gj = new GetJSON();
gj.execute(url);
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
getJSON(GET_URL);
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
}
}
In my application I want to track the vehicles,am getting multiple latitude and longitude from JSON I plotted the latlong in the google map,when the latlong changes in JSON the marker has to move.but here it moves by creating an new marker the previous marker is still exist.how can I remove the marker in the previous location
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.mapView)).getMap();
mMap.setMyLocationEnabled(true);
Location myLocation = mMap.getMyLocation();
if (mMap != null) {
//mMap.clear();
// setUpMap();
mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location arg0) {
// TODO Auto-generated method stub
final LatLngBounds.Builder builder = new LatLngBounds.Builder();
mMap.clear();
if (marker != null) {
marker.remove();
}
for (int i = 0; i < arraylist1.size(); i++) {
final LatLng position = new LatLng(Double
.parseDouble(arraylist1.get(i).get("Latitude")),
Double.parseDouble(arraylist1.get(i).get(
"Longitude")));
String ime1 = arraylist1.get(i).get("IME");
final MarkerOptions options = new MarkerOptions()
.position(position);
//mMap.addMarker(options);
//mMap.addMarker(options.icon(BitmapDescriptorFactory .fromResource(R.drawable.buspng)).title(ime1));
marker=mMap.addMarker(new MarkerOptions().position(position).icon(BitmapDescriptorFactory .fromResource(R.drawable.buspng)).title(ime1));
//options.title(ime1);
builder.include(position);
}
LatLng latLng = new LatLng(arg0.getLatitude(), arg0
.getLongitude());
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.setMyLocationEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// mMap.setOnMapClickListener(null);
mMap.setOnMarkerClickListener(null);
mMap.animateCamera(CameraUpdateFactory.zoomTo(9));
}
});
}
}
}
/* protected void retrieveAndAddCities() throws IOException {
HttpURLConnection conn = null;
final StringBuilder json = new StringBuilder();
try {
URL url = new URL(SERVICE_URL);
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
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();
}
}
new DownloadJSON().execute();
} */
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
String result="";
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
try {
arraylist1 = new ArrayList<HashMap<String, String>>();
JSONParser jParser = new JSONParser();
String result = "";
json = jParser.getJSONFromUrl(SERVICE_URL);
try {
//arraylist1.clear();
jsonarray = json.getJSONArray("SingleIMEs");
Log.d("Haaaaaaaaaaaa", "" + json);
for (int i = 0; i < jsonarray.length(); i++) {
Log.d("H11111111111111111111111111",
"" + jsonarray.length());
map = new HashMap<String, String>();
json = jsonarray.getJSONObject(i);
// pubname = json.getString("PubName");
latitude = json.getDouble("Latitude");
longitude = json.getDouble("Longitude");
ime = json.getString("IME");
// map.put("PubName", json.getString("PubName"));
//map.put("PubID", json.getString("PubID"));
map.put("Latitude", json.getString("Latitude"));
Log.e("CHECKLAT",""+json.getString("Latitude") );
map.put("Longitude", json.getString("Longitude"));
Log.e("CHECKLONG",""+json.getString("Longitude") );
map.put("IME", json.getString("IME"));
arraylist1.add(map);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
result="Error";
e.printStackTrace();
}
}catch(Exception e){
result="Error";
}
return null;
}
protected void onPostExecute(Void args) {
// mProgressDialog.dismiss();
}
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
/* Toast.makeText(getActivity(), "onLocationUpdated!!!", Toast.LENGTH_SHORT).show();
Log.d("onLocationUpdated!!!","");
new DownloadJSON().execute();
setUpMapIfNeeded(rootView);*/
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
if (marker != null) {
marker.remove();
}
Do you actually have a function to remove the marker here? If not, you have to remove the marker from the map and set it to null in order to remove it.
marker.setMap(null);
Source: marker API documentation
I am attempting to use JSON in order to create markers on my Google map for my app, but, for some reason, they are not showing up. The logcat has no errors or warnings, but the markers aren't showing up.
My JSON is hosted here: https://api.myjson.com/bins/4jb09
Here's my Java:
package com.example.toshiba.jsonmap;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
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;
/**
* #author saxman
*/
public class MainActivity extends FragmentActivity {
private static final String LOG_TAG = "ExampleApp";
private static final String SERVICE_URL = "https://api.myjson.com/bins/4jb09";
protected GoogleMap map;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (map == null) {
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.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 < 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)
))
);
}
}
}
I went ahead and got your code working using an AsyncTask.
Here is how you invoke it in onCreate():
private void setUpMapIfNeeded() {
if (map == null) {
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
map = mapFragment.getMap();
if (map != null) {
//setUpMap();
new MarkerTask().execute();
}
}
}
Here is the AsyncTask, note that I went ahead and made the markers blue just as an example:
private class MarkerTask extends AsyncTask<Void, Void, String> {
private static final String LOG_TAG = "ExampleApp";
private static final String SERVICE_URL = "https://api.myjson.com/bins/4jb09";
// Invoked by execute() method of this object
#Override
protected String doInBackground(Void... args) {
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); //uncaught
} finally {
if (conn != null) {
conn.disconnect();
}
}
return json.toString();
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(String json) {
try {
// De-serialize the JSON string into an array of city objects
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObj = jsonArray.getJSONObject(i);
LatLng latLng = new LatLng(jsonObj.getJSONArray("latlng").getDouble(0),
jsonObj.getJSONArray("latlng").getDouble(1));
//move CameraPosition on first result
if (i == 0) {
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLng).zoom(13).build();
map.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
// Create a marker for each city in the JSON data.
map.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title(jsonObj.getString("name"))
.snippet(Integer.toString(jsonObj.getInt("population")))
.position(latLng));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Error processing JSON", e);
}
}
}
Result:
Also, if you want customized info windows, you can look at the documentation here.
I went ahead and got a simple example working for this as well.
Code to set up the InfoWindowAdapter:
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.customlayout, null);
TextView tLocation = (TextView) v.findViewById(R.id.location);
TextView tSnippet = (TextView) v.findViewById(R.id.population);
tLocation.setText(arg0.getTitle());
tSnippet.setText(arg0.getSnippet());
return v;
}
});
customlayout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:orientation="vertical"
android:background="#000000">
<TextView
android:id="#+id/location"
android:textColor="#D3649F"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/population"
android:textColor="#D3649F"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Result: