Comment ouvrir l'application Google Map standard depuis mon application?

140

Une fois que l'utilisateur appuie sur le bouton de mon application, je souhaite ouvrir l'application Google Map standard et afficher un emplacement particulier. Comment puis-je le faire? (sans utiliser com.google.android.maps.MapView)

LA_
la source

Réponses:

242

Vous devez créer un Intentobjet avec un géo-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 vous souhaitez spécifier une adresse, vous devez utiliser une autre forme de géo-URI: geo:0,0?q=address.

référence: https://developer.android.com/guide/components/intents-common.html#Maps

Michael
la source
1
Merci, @Pixie! Quel est le format de la latitude et de la longitude? Si je passe, lat: 59.915494, lng: 30.409456il retourne une mauvaise position.
LA_
2
Ok, j'ai trouvé le problème. String.format("geo:%f,%f", latitude, longitude)retourné la chaîne par des virgules: geo:59,915494,30,409456.
LA_
20
Cela me déplace vers l'emplacement mais il n'y met pas de ballon. J'adorerais un ballon pour que l'utilisateur puisse cliquer dessus pour obtenir un itinéraire, etc.
Mike
5
Ne jouez pas avec String.format () pour une concaténation de chaînes simple. Cette méthode est destinée uniquement au texte de l'interface utilisateur, c'est pourquoi la représentation de la virgule décimale peut varier. Utilisez simplement l'opérateur "+" ou StringBuilder: String uri = "geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ().
Agustí Sánchez
4
Pour les itinéraires, une intention de navigation est désormais prise en charge avec google.navigation: q = latitude, longitude: 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

Vous pouvez également simplement utiliser http://maps.google.com/maps comme 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);

ou vous pouvez vous assurer que l'application Google Maps est uniquement utilisée, cela empêche le filtre d'intention (boîte de dialogue) d'apparaître, en utilisant

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

ainsi:

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

ou vous pouvez ajouter des étiquettes aux emplacements en ajoutant une chaîne entre parenthèses après chaque ensemble de coordonnées comme ceci:

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

Pour utiliser l'emplacement actuel des utilisateurs comme point de départ (malheureusement, je n'ai pas trouvé de moyen d'étiqueter l'emplacement actuel), déposez simplement le saddrparamètre comme suit:

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

Par souci d'exhaustivité, si l'utilisateur n'a pas installé l'application de cartes, ce sera une bonne idée d'attraper l'exception ActivityNotFoundException, comme l'indique @TonyQ, nous pouvons alors redémarrer l'activité sans la restriction de l'application de cartes, nous pouvons être à peu près sûrs que nous n'atteindrons jamais Toast à la fin car un navigateur Internet est une application valide pour lancer également ce schéma d'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();
            }
        }

ÉDITER:

Pour les itinéraires, une intention de navigation est désormais prise en charge avec 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
la source
java.util.IllegalFormatConversionException:% f ne peut pas formater les exceptions d'arguments java.lang.String
Amitsharma
Veuillez poster ce que vous avez remplacé la première ligne de code par [la ligne qui commence par String uri = string.format] On dirait que vous avez une chaîne comme l'un des paramètres qui devrait être un flottant
David Thompson
Hé, quand je passe l'étiquette à google maps avec latitude et longitude, l'application de carte convertit l'étiquette en adresses. Pouvez-vous s'il vous plaît dire que comment résoudre ce problème?
Rohan Sharma
41

L'utilisation du format String vous aidera, mais vous devez faire attention aux paramètres régionaux. En Allemagne, le flotteur sera séparé par une virgule à la place d'un point.

En utilisant la String.format("geo:%f,%f",5.1,2.1);langue anglaise, le résultat sera "geo:5.1,2.1"mais avec la langue allemande, vous obtiendrez"geo:5,1,2,1"

Vous devez utiliser les paramètres régionaux anglais pour éviter ce problème.

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

Pour définir une étiquette sur le point géographique, vous pouvez étendre votre géo-uri en utilisant:

!!! mais attention, le geo-uri est toujours en cours de développement 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
la source
vous pouvez également utiliser "& t = h" par rapport à "& t = m" pour appeler en affichage par satellite ou par couche cartographique.
tony gil
1
J'essaye quelque chose de similaire sauf que j'ajoute une requête avec les coordonnées pour que j'obtienne un ballon. Mon code ressemble exactement à votre premier exemple. Je formate l'URI avec les paramètres régionaux anglais, mais lorsque je l'utilise sur mon appareil défini sur les paramètres régionaux allemands, Google Maps remplace toujours les points par des virgules afin que ma requête ne fonctionne pas. Lorsque je règle les paramètres régionaux de l'appareil sur English US fe, cela fonctionne parfaitement. Que puis-je faire? Il semble que peu importe ce que Google Maps modifie à nouveau la chaîne de requête.
kaolick
6

Parfois, s'il n'y a aucune application associée à geo: protocal, vous pouvez utiliser try-catch pour obtenir ActivityNotFoundException pour le gérer.

Cela se produit lorsque vous utilisez un émulateur comme androVM qui n'est pas installé par défaut sur google map.

TonyQ
la source
6

Vous pouvez également utiliser l'extrait de code ci-dessous, de cette manière, l'existence de google maps est vérifiée avant le début de l'intention.

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

Référence: https://developers.google.com/maps/documentation/android-api/intents

Kerim Gökarslan
la source
1

Pour accéder à un emplacement AVEC PIN dessus, utilisez:

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

pour sans broche, utilisez ceci dans uri:

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

J'ai un exemple d'application dans lequel je prépare l'intention et passe simplement CITY_NAME dans l'intention à l'activité de marqueur de cartes qui calcule finalement la longitude et la latitude par Geocoder à l'aide de CITY_NAME.

Vous trouverez ci-dessous l'extrait de code du démarrage de l'activité des marqueurs de cartes et l'intégralité de 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);
        }
    }
}

Les liens expirent, j'ai donc collé le code complet ci-dessus, mais juste au cas où vous voudriez voir le code complet, il est disponible à: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753

JRG
la source
0

Ceci est écrit en Kotlin, il ouvrira l'application de cartes s'il est trouvé et placera le point et vous permettra de commencer le voyage:

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

Remplacez requireActivity()par votre Context.

Gastón Saillén
la source