You just need to access the XML in a network operation on a background Thread, parse the XML, and then display the Markers accordingly on the UI Thread.
I just got this working using this answer as a guide for the XML parsing.
Imports:
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
Here is the full Activity class, which includes an AsyncTask as an inner class that downloads and parses the XML from the URL in doInBackground(), then draws the Markers in onPostExecute():
public class MapFromXML extends AppCompatActivity implements OnMapReadyCallback {
GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_map_from_xml);
}
@Override
public void onResume() {
super.onResume();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null) {
if (mMap == null) {
mapFragment.getMapAsync(this);
} else {
new GetXmlAsync().execute();
}
}
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
new GetXmlAsync().execute();
}
public class GetXmlAsync extends AsyncTask<URL, Void, List<MarkerInfo>> {
@Override
protected List<MarkerInfo> doInBackground(URL... params) {
List<MarkerInfo> markerInfoList = new ArrayList<>();
Document doc = null;
URL url = null;
try {
url = new URL("http://www.example.com/GoogleMapXML.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc = db.parse(new InputSource(url.openStream()));
} catch (ParserConfigurationException e1) {
e1.printStackTrace();
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (SAXException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
try {
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("name");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
String name = ((Node) nameList.item(0)).getNodeValue();
NodeList latList = fstElmnt.getElementsByTagName("lat");
Element latElement = (Element) latList.item(0);
latList = latElement.getChildNodes();
String lat = ((Node) latList.item(0)).getNodeValue();
NodeList lonList = fstElmnt.getElementsByTagName("lng");
Element lonElement = (Element) lonList.item(0);
lonList = lonElement.getChildNodes();
String lng = ((Node) lonList.item(0)).getNodeValue();
MarkerInfo info = new MarkerInfo(name, Double.parseDouble(lat), Double.parseDouble(lng));
markerInfoList.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
return markerInfoList;
}
@Override
protected void onPostExecute(List<MarkerInfo> markerList) {
for (MarkerInfo info : markerList) {
mMap.addMarker(new MarkerOptions().position(new LatLng(info.lat, info.lon))
.title(info.name)
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
}
if (markerList.size() > 0) {
mMap.moveCamera(CameraUpdateFactory
.newLatLng(new LatLng(markerList.get(0).lat, markerList.get(0).lon)));
mMap.animateCamera(CameraUpdateFactory.zoomTo(5));
}
}
}
public class MarkerInfo {
double lat;
double lon;
String name;
public MarkerInfo(String n, double la, double lo) {
name = n;
lat = la;
lon = lo;
}
}
}
Here is the res/layout/content_map_from_xml.xml layout file for the Activity:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MapFromXML"
tools:showIn="@layout/activity_map_from_xml">
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>
Result:
