Android-Tutorials auf Google Map: Routen zwischen zwei Punkten zeichnen
Veröffentlicht: 2018-05-30In diesem Beitrag werden wir darüber diskutieren, wie man eine Route auf Google Maps zwischen zwei Punkten zeichnet.

Zunächst benötigen wir eine Google Map-Integration in unserer App. Besuchen Sie dazu
- https://developers.google.com/maps/documentation/android-api/signup
- Klicken Sie auf die Schaltfläche Get A Key
Sie sehen ein Dialogfeld ähnlich dem folgenden.

Erstellen Sie ein neues Projekt und klicken Sie auf Weiter. Sie erhalten einen API-Schlüssel wie den folgenden.

Angenommen, wenn Sie diese Schlüsselverwendung einschränken möchten, klicken Sie auf API Console. Klicken Sie andernfalls auf FERTIG.
In der API-Konsole können Sie die Schlüsselverwendung nur für Websites, Android-Apps, IOS-Apps usw. einschränken.
Wenn Sie auf die API-Konsole klicken, werden Sie zu einer anderen Seite mit dem Erstellungsdatum, Erstellt von usw. weitergeleitet. Wählen Sie den API-Schlüssel aus, auf den er beschränkt werden soll, und klicken Sie dann auf den Android Apps Radio Button.
Angenommen, Sie möchten die Nutzung auf Ihre Android-Apps beschränken, Paketnamen und Fingerabdruck hinzufügen.
Sie können den Paketnamen aus der Datei Androidmanifest.xml abrufen .

Um einen Fingerabdruck hinzuzufügen, müssen Sie das SHA-1-Zertifikat erwerben. Besuchen Sie dazu Android Studio und öffnen Sie die Gradle-Datei in der rechten Ecke.
Klicken Sie außerdem auf App Gradle >> Aufgaben >> android >> signingreport

Kopieren Sie das SHA-1-Zertifikat und fügen Sie es in das SHA-1-Fingerabdruckfeld ein, wie in der obigen Abbildung gezeigt. Klicken Sie zuletzt auf die Schaltfläche SPEICHERN.
Erstellen Sie nun ein neues Android-Projekt mit dem Namen, der Firmendomäne und anderen Details. Wählen Sie Ihre Android-Version als Lollipop und wählen Sie die Route in Google Map Activity wie unten gezeigt. Klicken Sie nun auf die Schaltfläche Weiter und Fertig stellen.

Nach dem Erstellen des Projekts können Sie einige Dateien sehen, wie z
- MapsActivity.java
- Activity_maps.xml
- google_maps-api.xml
Ändern Sie zuerst die google_map_api.xml. Fügen Sie in dieser Datei den zuvor erstellten Google API-Schlüssel hinzu.
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">API Key</string>Als nächstes ändern Sie die Datei Androidmanifest.xml
- Internetverbindung - Um mit der API zu kommunizieren und den Standort zu erhalten
- READ_GSERVICES – Immer wenn eine App das Google Service Framework verwenden möchte
- ACCESS_COARSE_LOCATION - Es bestimmt den Standort des Benutzers über WLAN und mobile Daten. Es gibt einen ungefähren Standort
- ACCESS_FINE_LOCATION - Ermittelt den Standort des Benutzers mithilfe von GPS. Es gibt Ihnen den genauen Standort.
- Fügen Sie außerdem das Metadaten-Tag im Anwendungs-Tag hinzu, das den API-Schlüsselwert enthält
Androidmanifest.xml-Datei sieht wie folgt aus
<manifest xmlns:andro package="com.example.drawroutes"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" /> <activity android:name=".MapsActivity" android:label="@string/title_activity_maps"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>Ändern Sie nun die Datei in build.gradle. Stellen Sie beim Ändern sicher, dass Sie die beiden Abhängigkeiten hinzufügen, nämlich:
- Implementierung 'com.google.android.gms:play-services-maps:11.8.0'
- Implementierung 'com.google.android.gms:play-services-location:11.8.0'
Während die erste Abhängigkeit verwendet wird, um die Google-Karte anzuzeigen, wird die zweite Abhängigkeit verwendet, um den Google-Standort und die Aktivitätserkennung zu erhalten.
Die Datei build.gradle sieht also wie folgt aus
apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.example.drawroutes" minSdkVersion 19 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.google.android.gms:play-services-maps:11.8.0' implementation 'com.google.android.gms:play-services-location:11.8.0' }Beginnen wir mit MapsActivity. In dieser Aktivität legen wir die Layoutdatei namens Activity_maps . fest
Definieren Sie in dieser XML-Datei ein Fragment und deklarieren Sie die ID und den Namen für das Fragment. Schließlich sieht die XML wie unten gezeigt aus .
<fragment xmlns:andro xmlns:tools="schemas.android.com/tools" android: android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.drawroutes.MapsActivity" />Hier deklarieren Sie Android: name="com.google.android.gms.maps.SupportMapFragment", weil wir die Aktivität von FragmentActivity erweitern. Wenn Sie MapFragment verwenden möchten, können Sie Activity erweitern.
Erweitern Sie als Nächstes MapsActivity, wobei die ID auf diese Weise definiert ist:
Final SupportMapFragment mapFragment =(SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map);Lassen Sie uns den Code hier aufteilen und einen nach dem anderen besprechen. Zuerst müssen Sie die GoogleMap-Klasse instanziieren.
Deklarieren Sie nun die Karte aufClick Listner
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng point) { // Already two locations if (MarkerPoints.size() > 1) { MarkerPoints.clear(); mMap.clear(); } // Adding new item to the ArrayList MarkerPoints.add(point); // Creating MarkerOptions MarkerOptions options = new MarkerOptions(); // Setting the position of the marker options.position(point); /** * For the start location, the color of marker is GREEN and * for the end location, the color of marker is RED. */ if (MarkerPoints.size() == 1) { options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); } else if (MarkerPoints.size() == 2) { options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); } // Add new marker to the Google Map Android API V2 mMap.addMarker(options); // Checks, whether start and end locations are captured if (MarkerPoints.size() >= 2) { LatLng origin = MarkerPoints.get(0); LatLng dest = MarkerPoints.get(1); // Getting URL to the Google Directions API String url = getUrl(origin, dest); Log.d("onMapClick", url.toString()); FetchUrl FetchUrl = new FetchUrl(); // Start downloading json data from Google Directions API FetchUrl.execute(url); //move map camera mMap.moveCamera(CameraUpdateFactory.newLatLng(origin)); mMap.animateCamera(CameraUpdateFactory.zoomTo(11)); } } });Der oben gezeigte Code wird ausgeführt, wenn der Benutzer auf einen Android-Bildschirm tippt. Dies wird verwendet, um die Markierung an den Punkten zu platzieren, zwischen denen der Pfad gezeichnet wird.
MarkerPoints.get() wird verwendet, um auf die Koordinaten der beiden Punkte zuzugreifen und sie zu speichern. Es wird in LatLng-Ursprung und -Ziel gespeichert.

Und getUrl wird verwendet, um die URL abzurufen und mit Async Task implementiert.
Async Task: Async Task ist eine von Android bereitgestellte abstrakte Klasse, die bei der Verwendung des UI-Threads hilft. Die Klasse Async Task ermöglicht es uns, lang andauernde Operationen oder Hintergrundoperationen durchzuführen und die Ergebnisse im UI-Thread anzuzeigen, ohne den Hauptthread zu beeinträchtigen. Async Task wird verwendet, um Aufgaben/Vorgänge, die asynchron im Hintergrund ausgeführt werden müssen, auszuführen. In der Klasse Async Task gibt es zwei Methoden.
- doInbackground : Task wird in dieser Methode implementiert.
- onPostExecute: Ergebnis wird in dieser Methode angezeigt.
private class FetchUrl extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... url) { // For storing data from web service String data = ""; try { // Fetching the data from web service data = downloadUrl(url[0]); Log.d("Background Task data", data.toString()); } catch (Exception e) { Log.d("Background Task", e.toString()); } return data; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); ParserTask parserTask = new ParserTask(); // Invokes the thread for parsing the JSON data parserTask.execute(result); } }downloadUrl: Dies wird verwendet, um die URL vom Webdienst abzurufen und das Ergebnis wird mit ParserTask geparst. Dies ist auch eine asynchrone Aufgabe.
private String downloadUrl(String strUrl) throws IOException { String data = ""; InputStream iStream = null; HttpURLConnection urlConnection = null; try { URL url = new URL(strUrl); // Creating an http connection to communicate with url urlConnection = (HttpURLConnection) url.openConnection(); // Connecting to url urlConnection.connect(); // Reading data from url iStream = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); StringBuffer sb = new StringBuffer(); String line = ""; while ((line = br.readLine()) != null) { sb.append(line); } data = sb.toString(); Log.d("downloadUrl", data.toString()); br.close(); } catch (Exception e) { Log.d("Exception", e.toString()); } finally { iStream.close(); urlConnection.disconnect(); } return data; }Hier werden Daten in Form von Json zurückgegeben. welche Benutzer mit HttpURLConnection abrufen können.
Parser Task: Definieren Sie eine neue Klasse mit dem Namen ParserTask, die AsyncTask erweitert. Analysieren Sie die von der downloadUrl-Methode zurückgegebenen Json-Daten.
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> { // Parsing the data in non-ui thread @Override protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { JSONObject jObject; List<List<HashMap<String, String>>> routes = null; try { jObject = new JSONObject(jsonData[0]); Log.d("ParserTask",jsonData[0].toString()); DataParser parser = new DataParser(); Log.d("ParserTask", parser.toString()); // Starts parsing data routes = parser.parse(jObject); Log.d("ParserTask","Executing routes"); Log.d("ParserTask",routes.toString()); } catch (Exception e) { Log.d("ParserTask",e.toString()); e.printStackTrace(); } return routes; } // Executes in UI thread, after the parsing process @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList<LatLng> points; PolylineOptions lineOptions = null; // Traversing through all the routes for (int i = 0; i < result.size(); i++) { points = new ArrayList<>(); lineOptions = new PolylineOptions(); // Fetching i-th route List<HashMap<String, String>> path = result.get(i); // Fetching all the points in i-th route for (int j = 0; j < path.size(); j++) { HashMap<String, String> point = path.get(j); double lat = Double.parseDouble(point.get("lat")); double lng = Double.parseDouble(point.get("lng")); LatLng position = new LatLng(lat, lng); points.add(position); } // Adding all the points in the route to LineOptions lineOptions.addAll(points); lineOptions.width(10); lineOptions.color(Color.RED); Log.d("onPostExecute","onPostExecute lineoptions decoded"); } // Drawing polyline in the Google Map for the i-th route if(lineOptions != null) { mMap.addPolyline(lineOptions); } else { Log.d("onPostExecute","without Polylines drawn"); } } }Hier analysiert „doInBackround“ die Daten. In der Methode „onPostExecute“ fügen wir die Polylinie hinzu, um die Route auf Google Map zu zeichnen.
Indem wir diese Methoden befolgen, parsen wir die Daten in eine andere Klasse, dh DataParser
class DataParser { List<List<HashMap<String,String>>> parse(JSONObject jObject){ List<List<HashMap<String, String>>> routes = new ArrayList<>() ; JSONArray jRoutes; JSONArray jLegs; JSONArray jSteps; try { jRoutes = jObject.getJSONArray("routes"); /** Traversing all routes */ for(int i=0;i<jRoutes.length();i++){ jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs"); List path = new ArrayList<>(); /** Traversing all legs */ for(int j=0;j<jLegs.length();j++){ jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps"); /** Traversing all steps */ for(int k=0;k<jSteps.length();k++){ String polyline = ""; polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points"); List<LatLng> list = decodePoly(polyline); /** Traversing all points */ for(int l=0;l<list.size();l++){ HashMap<String, String> hm = new HashMap<>(); hm.put("lat", Double.toString((list.get(l)).latitude) ); hm.put("lng", Double.toString((list.get(l)).longitude) ); path.add(hm); } } routes.add(path); } } } catch (JSONException e) { e.printStackTrace(); }catch (Exception e){ } return routes; } /** * Method to decode polyline points * */ private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng((((double) lat / 1E5)), (((double) lng / 1E5))); poly.add(p); } return poly; } }Mit der Parse-Methode erhalten Sie Json-Daten, die JSONArray mithilfe von getJSONArray aufteilen können. Durchqueren Sie alle Routen, Punkte usw. und fügen Sie alle Durchquerungspunkte der Liste hinzu.
routen.add(Pfad);
Zeichnen Sie die Route auf der Google-Karte mit Polylinie. Dies geschieht in der onPostExecute-Methode, in der ParseTask AsyncTask-Klasse.
@Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList<LatLng> points; PolylineOptions lineOptions = null; // Traversing through all the routes for (int i = 0; i < result.size(); i++) { points = new ArrayList<>(); lineOptions = new PolylineOptions(); // Fetching i-th route List<HashMap<String, String>> path = result.get(i); // Fetching all the points in i-th route for (int j = 0; j < path.size(); j++) { HashMap<String, String> point = path.get(j); double lat = Double.parseDouble(point.get("lat")); double lng = Double.parseDouble(point.get("lng")); LatLng position = new LatLng(lat, lng); points.add(position); } // Adding all the points in the route to LineOptions lineOptions.addAll(points); lineOptions.width(10); lineOptions.color(Color.RED); Log.d("onPostExecute","onPostExecute lineoptions decoded"); } // Drawing polyline in the Google Map for the i-th route if(lineOptions != null) { mMap.addPolyline(lineOptions); } else { Log.d("onPostExecute","without Polylines drawn"); } }Die oben genannten Punkte werden aus dem Ergebnis geholt und zeichnen eine Route auf Google Maps. Hier werden ArrayList-Punkte verwendet, um die Breiten- und Längengradpositionen auf Google Map zu speichern.
Zuletzt wird die Route mit polyLine auf Google Map gezeichnet: lineOptions.addAll(points);
Fügen Sie die Polylinie wie folgt zur Karte hinzu: mMap.addPolyline(lineOptions);
Führen Sie abschließend die Anwendung aus. Es wird erfolgreich ausgeführt. Die Ausgabe des Bildschirms ist wie unten gezeigt.

