Come aprire un'applicazione standard di Google Map dalla mia applicazione?


140

Una volta che l'utente preme il pulsante nella mia applicazione, vorrei aprire l'applicazione Google Map standard e mostrare una posizione particolare. Come posso farlo? (senza usare com.google.android.maps.MapView)

Risposte:


242

È necessario creare un Intentoggetto con un geo-URI:

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

Se si desidera specificare un indirizzo, è necessario utilizzare un'altra forma di geo-URI: geo:0,0?q=address.

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


1
Grazie @Pixie! Qual è il formato di latitudine e longitudine? Se passo lat: 59.915494, lng: 30.409456, restituisce una posizione errata.
LA_

2
Ok, ho trovato il problema. String.format("geo:%f,%f", latitude, longitude)restituita la stringa con le virgole: geo:59,915494,30,409456.
LA_

20
Questo mi porta nella posizione ma non mette un pallone lì. Mi piacerebbe un baloon in modo che l'utente possa fare clic su di esso per ottenere indicazioni stradali ecc.
Mike

5
Non scherzare con String.format () per una semplice concatenazione di stringhe. Questo metodo è destinato solo al testo dell'interfaccia utente, ecco perché la rappresentazione dei punti decimali può variare. Basta usare l'operatore "+" o StringBuilder: String uri = "geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ().
Agustí Sánchez,

4
Per le indicazioni stradali, ora è supportato un intento di navigazione con google.navigation: q = latitudine, longitudine: Uri gmmIntentUri = Uri.parse ("google.navigation: q =" + 12f "+", "+ 2f); Intent mapIntent = new Intent (Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage ("com.google.android.apps.maps"); startActivity (mapIntent);
David Thompson

106

Puoi anche semplicemente utilizzare http://maps.google.com/maps come URI

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);

oppure puoi assicurarti che venga utilizzata solo l'app Google Maps, questo interrompe la visualizzazione del filtro intenti (finestra di dialogo), utilizzando

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

così:

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);

oppure puoi aggiungere etichette alle posizioni aggiungendo una stringa tra parentesi dopo ogni serie di coordinate in questo modo:

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);

Per utilizzare la posizione corrente dell'utente come punto di partenza (sfortunatamente non ho trovato il modo di etichettare la posizione corrente), quindi rilasciare il saddrparametro come segue:

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);

Per completezza, se l'utente non ha installato l'app per le mappe, sarà una buona idea catturare ActivityNotFoundException, come afferma @TonyQ, quindi possiamo ricominciare l'attività senza la limitazione dell'app per le mappe, possiamo essere abbastanza sicuri che non arriveremo mai a Toast alla fine poiché un browser Internet è un'applicazione valida per avviare anche questo schema di URL.

        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();
            }
        }

MODIFICARE:

Per le indicazioni stradali, ora è supportato un intento di navigazione con google.navigation

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);

java.util.IllegalFormatConversionException:% f non può formattare java.lang.String eccezioni argomenti
Amitsharma

Pubblica ciò che hai sostituito la prima riga di codice con [la riga che inizia con String uri = string.format] Sembra che tu abbia una stringa come uno dei parametri che dovrebbe essere un float
David Thompson

Ehi, quando passo l'etichetta su google maps con latitudine e longitudine, l'applicazione della mappa converte l'etichetta negli indirizzi. Puoi per favore dirlo come risolvere questo problema?
Rohan Sharma,

41

L'uso del formato String ti aiuterà, ma devi essere attento alle impostazioni internazionali. In Germania il galleggiante sarà separato con in virgola anziché un punto.

Usando String.format("geo:%f,%f",5.1,2.1);l'inglese locale il risultato sarà "geo:5.1,2.1"ma con il tedesco locale otterrai"geo:5,1,2,1"

È necessario utilizzare le impostazioni internazionali inglesi per impedire questo comportamento.

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

Per impostare un'etichetta sul punto geografico, puoi estendere il tuo uri geografico usando:

!!! ma attenzione, il geo-uri è ancora in via di sviluppo 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);

puoi anche usare "& t = h" contro "& t = m" per chiamare nella visualizzazione del livello satellitare o della mappa.
tony gil,

1
Sto provando qualcosa di simile tranne che aggiungo una query con le coordinate in modo da ottenere un fumetto. Il mio codice è esattamente come il tuo primo esempio. Formatto l'URI con le impostazioni internazionali inglesi, ma quando lo uso sul mio dispositivo impostato sulle impostazioni locali tedesche, Google Maps sostituisce ancora i punti con virgole in modo che la mia query non funzioni. Quando imposto le impostazioni locali del dispositivo su inglese americano, funziona perfettamente. Cosa posso fare? Sembra che Google Maps modifichi nuovamente la stringa di query.
Kaolick,


6

A volte se non è presente alcuna applicazione associata a geo: protocal, è possibile utilizzare try-catch per ottenere ActivityNotFoundException per gestirlo.

Succede quando si utilizza un emulatore come androVM che non è installato google map per impostazione predefinita.


6

Puoi anche utilizzare lo snippet di codice in basso, in questo modo viene verificata l'esistenza di google maps prima dell'avvio dell'intento.

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);
}

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


1

Per andare alla posizione con il PIN, usa:

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);

per senza pin, usa questo in uri:

 String uri = "geo:" + destinationLatitude + "," + destinationLongitude;

0

Ho un'app di esempio in cui preparo l'intento e ho appena passato CITY_NAME nell'intento all'attività dell'indicatore delle mappe che alla fine calcola la longitudine e la latitudine di Geocoder usando CITY_NAME.

Di seguito è riportato lo snippet di codice per l'avvio dell'attività dell'indicatore delle mappe e la completa 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);
        }
    }
}

I collegamenti scadono, quindi ho incollato il codice completo sopra, ma nel caso in cui se desideri vedere il codice completo, è disponibile all'indirizzo: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753


0

Questo è scritto in Kotlin, aprirà l'app mappe se viene trovato e posiziona il punto e ti consente di iniziare il viaggio:

  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)
        }

Sostituisci requireActivity()con il tuo Context.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.