¿Cómo abrir la aplicación estándar de Google Map desde mi aplicación?

140

Una vez que el usuario presiona el botón en mi aplicación, me gustaría abrir la aplicación estándar de Google Map y mostrar una ubicación particular. ¿Cómo puedo hacerlo? (sin usar com.google.android.maps.MapView)

LA_
fuente

Respuestas:

241

Debe crear un Intentobjeto 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);

Si desea especificar una dirección, se debe utilizar otra forma de geo-URI: geo:0,0?q=address.

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

Miguel
fuente
1
Gracias, @ Pixie! ¿Cuál es el formato de latitud y longitud? Si lo paso lat: 59.915494, lng: 30.409456, vuelve a la posición incorrecta.
LA_
2
Ok, he encontrado el problema. String.format("geo:%f,%f", latitude, longitude)devuelve la cadena con comas: geo:59,915494,30,409456.
LA_
20
Esto me mueve a la ubicación pero no pone un globo allí. Me encantaría un globo para que el usuario pueda hacer clic en él para obtener instrucciones, etc.
Mike
55
No te metas con String.format () para una simple concatenación de cadenas. Ese método está diseñado solo para texto de interfaz de usuario, por eso la representación del punto decimal puede variar. Simplemente use el operador "+" o StringBuilder: String uri = "geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ().
Agustí Sánchez
44
Para obtener instrucciones, ahora se admite una intención de navegación con google.navigation: q = latitud, longitud: Uri gmmIntentUri = Uri.parse ("google.navigation: q =" + 12f "+", "+ 2f); Intención mapIntent = nuevo Intención (Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage ("com.google.android.apps.maps"); startActivity (mapIntent);
David Thompson
105

También puede simplemente usar http://maps.google.com/maps como su 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);

o puede asegurarse de que solo se use la aplicación Google Maps, esto evita que aparezca el filtro de intención (diálogo), usando

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

al igual que:

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

o puede agregar etiquetas a las ubicaciones agregando una cadena dentro de paréntesis después de cada conjunto de coordenadas de la siguiente manera:

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

Para usar la ubicación actual de los usuarios como punto de partida (desafortunadamente no he encontrado una manera de etiquetar la ubicación actual), simplemente deje el saddrparámetro de la siguiente manera:

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

Para completar, si el usuario no tiene la aplicación de mapas instalada, entonces será una buena idea atrapar la ActivityNotFoundException, como dice @TonyQ, entonces podemos comenzar la actividad nuevamente sin la restricción de la aplicación de mapas, podemos estar bastante seguros que nunca llegaremos al Toast al final ya que un navegador de Internet es una aplicación válida para lanzar este esquema de URL también.

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

EDITAR:

Para obtener instrucciones, ahora se admite una intención de navegación 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);
David Thompson
fuente
java.util.IllegalFormatConversionException:% f no puede formatear java.lang.String argumentos excepciones
Amitsharma
Publique lo que reemplazó la primera línea de código con [la línea que comienza con String uri = string.format] Parece que tiene una cadena como uno de los parámetros que debería ser flotante
David Thompson
Hola, cuando paso la etiqueta a Google Maps con latitud y longitud, la aplicación de mapas convierte la etiqueta en las direcciones. ¿Puedes decirme cómo resolver este problema?
Rohan Sharma
41

Usar el formato de cadena ayudará, pero debes tener cuidado con la configuración regional. En alemania float se separará con una coma en lugar de un punto.

Usando String.format("geo:%f,%f",5.1,2.1);el idioma local, el resultado será, "geo:5.1,2.1"pero con el idioma alemán obtendrá"geo:5,1,2,1"

Debe usar la configuración regional en inglés para evitar este comportamiento.

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

Para establecer una etiqueta en el punto geográfico, puede ampliar su uri geográfica utilizando:

!!! pero tenga cuidado con esto, el geo-uri todavía está en desarrollo 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
fuente
también puede usar "& t = h" versus "& t = m" para llamar en la visualización de la capa de satélite o mapa.
Tony Gil
1
Estoy intentando algo similar, excepto que agrego una consulta con las coordenadas para obtener un globo. Mi código se ve exactamente como su primer ejemplo. Formateo el URI con configuración regional en inglés, pero cuando lo uso en mi dispositivo configurado en configuración regional en alemán, Google Maps todavía reemplaza los puntos con comas para que mi consulta no funcione. Cuando configuro la configuración regional del dispositivo en inglés EE. UU., Funciona perfectamente bien. ¿Que puedo hacer? Parece que no importa qué Google Maps cambie nuevamente la cadena de consulta.
kaolick
6

A veces, si no hay ninguna aplicación asociada con geo: protocal, puede usar try-catch para obtener ActivityNotFoundException para manejarlo.

Ocurre cuando usa algún emulador como androVM que no está instalado de forma predeterminada en google map.

TonyQ
fuente
6

También puede usar el fragmento de código a continuación, de esta manera se verifica la existencia de google maps antes de que se inicie la intención.

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

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

Kerim Gökarslan
fuente
1

Para ir a la ubicación CON PIN, use:

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

sin pin, use esto en uri:

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

Tengo una aplicación de muestra donde preparo la intención y simplemente paso CITY_NAME en la intención a la actividad del marcador de mapas que eventualmente calcula la longitud y latitud por Geocoder usando CITY_NAME.

A continuación se muestra el fragmento de código de inicio de la actividad del marcador de mapas y la actividad completa de MapsMarker.

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

Los enlaces caducan, así que he pegado el código completo arriba, pero en caso de que desee ver el código completo, está disponible en: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753

JRG
fuente
0

Esto está escrito en Kotlin, abrirá la aplicación de mapas si se encuentra y colocará el punto y le permitirá comenzar el viaje:

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

Reemplace requireActivity()con su Context.

Gastón Saillén
fuente