Wie öffne ich eine Standard-Google Map-Anwendung aus meiner Anwendung?

140

Sobald der Benutzer in meiner Anwendung auf die Schaltfläche drückt, möchte ich die Standardanwendung von Google Map öffnen und einen bestimmten Standort anzeigen. Wie kann ich es tun? (ohne zu benutzen com.google.android.maps.MapView)

LA_
quelle

Antworten:

241

Sie sollten ein IntentObjekt mit einem Geo-URI erstellen :

String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);

Wenn Sie eine Adresse angeben möchten, sollten Sie eine andere Form von Geo-URI verwenden : geo:0,0?q=address.

Referenz: https://developer.android.com/guide/components/intents-common.html#Maps

Michael
quelle
1
Danke, @Pixie! Was ist das Format von Längen- und Breitengrad? Wenn ich passiere lat: 59.915494, lng: 30.409456, wird die falsche Position zurückgegeben.
LA_
2
Ok, ich habe das Problem gefunden. String.format("geo:%f,%f", latitude, longitude)gab den String mit Kommas zurück : geo:59,915494,30,409456.
LA_
20
Dies bringt mich an den Ort, aber es setzt dort keinen Ballon. Ich würde einen Ballon lieben, damit der Benutzer darauf klicken kann, um Wegbeschreibungen usw. zu erhalten.
Mike
5
Leg dich nicht mit String.format () an, um eine einfache String-Verkettung zu erhalten. Diese Methode ist nur für UI-Text gedacht. Aus diesem Grund kann die Darstellung von Dezimalstellen variieren. Verwenden Sie einfach den Operator "+" oder StringBuilder: String uri = "geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ().
Agustí Sánchez
4
Für Wegbeschreibungen wird jetzt eine Navigationsabsicht mit google.navigation unterstützt: q = Breite, Länge: Uri gmmIntentUri = Uri.parse ("google.navigation: q =" + 12f "+", "+ 2f); Absicht mapIntent = new Intent (Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage ("com.google.android.apps.maps"); startActivity (mapIntent);
David Thompson
105

Sie können auch einfach http://maps.google.com/maps als URI verwenden

String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);

Wenn Sie sicherstellen können, dass nur die Google Maps-App verwendet wird, wird der Intent-Filter (Dialogfeld) mithilfe von nicht angezeigt

intent.setPackage("com.google.android.apps.maps");

wie so:

String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);

Sie können den Positionen auch Beschriftungen hinzufügen, indem Sie nach jedem Koordinatensatz eine Zeichenfolge in Klammern einfügen:

String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "(" + "Home Sweet Home" + ")&daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);

Um den aktuellen Standort des Benutzers als Ausgangspunkt zu verwenden (leider habe ich keine Möglichkeit gefunden, den aktuellen Standort zu kennzeichnen), geben Sie den saddrParameter einfach wie folgt ein:

String uri = "http://maps.google.com/maps?daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);

Der Vollständigkeit halber: Wenn der Benutzer die Karten-App nicht installiert hat, ist es eine gute Idee, die ActivityNotFoundException abzufangen, wie @TonyQ angibt. Dann können wir die Aktivität ohne Einschränkung der Karten-App erneut starten. Wir können ziemlich sicher sein dass wir am Ende nie zum Toast kommen werden, da ein Internetbrowser eine gültige Anwendung ist, um auch dieses URL-Schema zu starten.

        String uri = "http://maps.google.com/maps?daddr=" + 12f + "," + 2f + " (" + "Where the party is at" + ")";
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
        intent.setPackage("com.google.android.apps.maps");
        try
        {
            startActivity(intent);
        }
        catch(ActivityNotFoundException ex)
        {
            try
            {
                Intent unrestrictedIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
                startActivity(unrestrictedIntent);
            }
            catch(ActivityNotFoundException innerEx)
            {
                Toast.makeText(this, "Please install a maps application", Toast.LENGTH_LONG).show();
            }
        }

BEARBEITEN:

Für Wegbeschreibungen wird jetzt eine Navigationsabsicht mit google.navigation unterstützt

Uri navigationIntentUri = Uri.parse("google.navigation:q=" + 12f + "," + 2f);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, navigationIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
David Thompson
quelle
java.util.IllegalFormatConversionException:% f kann keine Ausnahmen für java.lang.String-Argumente
formatieren
Bitte posten Sie, was Sie in der ersten Codezeile durch [die Zeile, die mit String uri = string.format beginnt] ersetzt haben. Scheint, als hätten Sie einen String als einen der Parameter, der ein Float sein sollte
David Thompson
Hey, wenn ich ein Label an Google Maps mit Längen- und Breitengrad übergebe, konvertiert die Kartenanwendung das Label in die Adressen. Können Sie bitte sagen, wie Sie dieses Problem lösen können?
Rohan Sharma
41

Die Verwendung des String-Formats hilft, aber Sie müssen das Gebietsschema genau kennen. In Deutschland wird float mit einem Komma anstelle eines Punktes getrennt.

Wenn Sie das String.format("geo:%f,%f",5.1,2.1);Gebietsschema Englisch verwenden, wird das Ergebnis angezeigt, "geo:5.1,2.1"aber mit dem Gebietsschema Deutsch erhalten Sie"geo:5,1,2,1"

Sie sollten das englische Gebietsschema verwenden, um dieses Verhalten zu verhindern.

String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);

Um eine Beschriftung für den Geopunkt festzulegen, können Sie Ihre Geo-Uri erweitern, indem Sie Folgendes verwenden:

!!! Aber seien Sie vorsichtig damit, das Geo-Uri befindet sich noch in der Entwicklung http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00

String uri = String.format(Locale.ENGLISH, "geo:%f,%f?z=%d&q=%f,%f (%s)", 
                           latitude, longitude, zoom, latitude, longitude, label);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
David Boho
quelle
Sie können auch "& t = h" gegenüber "& t = m" zum Aufrufen der Satelliten- oder Kartenebenenanzeige verwenden.
Tony Gil
1
Ich versuche etwas Ähnliches, außer dass ich eine Abfrage mit den Koordinaten hinzufüge, damit ich eine Sprechblase bekomme. Mein Code sieht genauso aus wie Ihr erstes Beispiel. Ich formatiere den URI mit dem englischen Gebietsschema, aber wenn ich ihn auf meinem Gerät verwende, das auf das deutsche Gebietsschema eingestellt ist, ersetzt Google Maps weiterhin Punkte durch Kommas, sodass meine Abfrage nicht funktioniert. Wenn ich das Gebietsschema des Geräts auf Englisch (US) einstelle, funktioniert es einwandfrei. Was kann ich tun? Es scheint egal zu sein, was Google Maps die Abfragezeichenfolge erneut ändert.
Kaolick
6

Manchmal, wenn keine Anwendung mit geo: protocal verknüpft ist, können Sie try-catch verwenden, um die ActivityNotFoundException zu erhalten, um damit umzugehen.

Es passiert, wenn Sie einen Emulator wie androVM verwenden, auf dem Google Map standardmäßig nicht installiert ist.

TonyQ
quelle
6

Sie können auch das folgende Code-Snippet verwenden. Auf diese Weise wird das Vorhandensein von Google Maps überprüft, bevor die Absicht gestartet wird.

Uri gmmIntentUri = Uri.parse(String.format(Locale.ENGLISH,"geo:%f,%f", latitude, longitude));
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(mapIntent);
}

Referenz: https://developers.google.com/maps/documentation/android-api/intents

Kerim Gökarslan
quelle
1

Verwenden Sie Folgendes, um zu einem Ort mit PIN zu gelangen:

String uri = "http://maps.google.com/maps?q=loc:" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);

für ohne Stift, verwenden Sie dies in uri:

 String uri = "geo:" + destinationLatitude + "," + destinationLongitude;
M. Usman Khan
quelle
0

Ich habe eine Beispiel-App, in der ich die Absicht vorbereite und einfach den CITY_NAME in der Absicht an die Kartenmarkierungsaktivität übergebe, die schließlich den Längen- und Breitengrad von Geocoder mithilfe von CITY_NAME berechnet.

Unten finden Sie den Codeausschnitt zum Starten der Kartenmarkierungsaktivität und der vollständigen MapsMarkerActivity.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    } else if (id == R.id.action_refresh) {
        Log.d(APP_TAG, "onOptionsItemSelected Refresh selected");
        new MainActivityFragment.FetchWeatherTask().execute(CITY, FORECAS_DAYS);
        return true;
    } else if (id == R.id.action_map) {
        Log.d(APP_TAG, "onOptionsItemSelected Map selected");
        Intent intent = new Intent(this, MapsMarkerActivity.class);
        intent.putExtra("CITY_NAME", CITY);
        startActivity(intent);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public class MapsMarkerActivity extends AppCompatActivity
        implements OnMapReadyCallback {

    private String cityName = "";

    private double longitude;

    private double latitude;

    static final int numberOptions = 10;

    String [] optionArray = new String[numberOptions];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_map);
        // Get the SupportMapFragment and request notification
        // when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        // Test whether geocoder is present on platform
        if(Geocoder.isPresent()){
            cityName = getIntent().getStringExtra("CITY_NAME");
            geocodeLocation(cityName);
        } else {
            String noGoGeo = "FAILURE: No Geocoder on this platform.";
            Toast.makeText(this, noGoGeo, Toast.LENGTH_LONG).show();
            return;
        }
    }

    /**
     * Manipulates the map when it's available.
     * The API invokes this callback when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user receives a prompt to install
     * Play services inside the SupportMapFragment. The API invokes this method after the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        // Add a marker in Sydney, Australia,
        // and move the map's camera to the same location.
        LatLng sydney = new LatLng(latitude, longitude);
        // If cityName is not available then use
        // Default Location.
        String markerDisplay = "Default Location";
        if (cityName != null
                && cityName.length() > 0) {
            markerDisplay = "Marker in " + cityName;
        }
        googleMap.addMarker(new MarkerOptions().position(sydney)
                .title(markerDisplay));
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }

    /**
     * Method to geocode location passed as string (e.g., "Pentagon"), which
     * places the corresponding latitude and longitude in the variables lat and lon.
     *
     * @param placeName
     */
    private void geocodeLocation(String placeName){

        // Following adapted from Conder and Darcey, pp.321 ff.
        Geocoder gcoder = new Geocoder(this);

        // Note that the Geocoder uses synchronous network access, so in a serious application
        // it would be best to put it on a background thread to prevent blocking the main UI if network
        // access is slow. Here we are just giving an example of how to use it so, for simplicity, we
        // don't put it on a separate thread.  See the class RouteMapper in this package for an example
        // of making a network access on a background thread. Geocoding is implemented by a backend
        // that is not part of the core Android framework, so we use the static method
        // Geocoder.isPresent() to test for presence of the required backend on the given platform.

        try{
            List<Address> results = null;
            if(Geocoder.isPresent()){
                results = gcoder.getFromLocationName(placeName, numberOptions);
            } else {
                Log.i(MainActivity.APP_TAG, "No Geocoder found");
                return;
            }
            Iterator<Address> locations = results.iterator();
            String raw = "\nRaw String:\n";
            String country;
            int opCount = 0;
            while(locations.hasNext()){
                Address location = locations.next();
                if(opCount == 0 && location != null){
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                }
                country = location.getCountryName();
                if(country == null) {
                    country = "";
                } else {
                    country =  ", " + country;
                }
                raw += location+"\n";
                optionArray[opCount] = location.getAddressLine(0)+", "
                        +location.getAddressLine(1)+country+"\n";
                opCount ++;
            }
            // Log the returned data
            Log.d(MainActivity.APP_TAG, raw);
            Log.d(MainActivity.APP_TAG, "\nOptions:\n");
            for(int i=0; i<opCount; i++){
                Log.i(MainActivity.APP_TAG, "("+(i+1)+") "+optionArray[i]);
            }
            Log.d(MainActivity.APP_TAG, "latitude=" + latitude + ";longitude=" + longitude);
        } catch (Exception e){
            Log.d(MainActivity.APP_TAG, "I/O Failure; do you have a network connection?",e);
        }
    }
}

Links verfallen, daher habe ich oben den vollständigen Code eingefügt, aber nur für den Fall, dass Sie den vollständigen Code sehen möchten, finden Sie ihn unter: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753

JRG
quelle
0

Dies ist in Kotlin geschrieben. Es öffnet die Karten-App, wenn sie gefunden wurde, platziert den Punkt und lässt Sie die Reise beginnen:

  val gmmIntentUri = Uri.parse("http://maps.google.com/maps?daddr=" + adapter.getItemAt(position).latitud + "," + adapter.getItemAt(position).longitud)
        val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
        mapIntent.setPackage("com.google.android.apps.maps")
        if (mapIntent.resolveActivity(requireActivity().packageManager) != null) {
            startActivity(mapIntent)
        }

Ersetzen Sie requireActivity()durch Ihre Context.

Gastón Saillén
quelle