web-dev-qa-db-fra.com

Comment ouvrir une application Google Map standard à partir de mon application?

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)

118
LA_

Vous devriez créer un objet Intent 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

207
Michael

Vous pouvez aussi simplement utiliser http://maps.google.com/maps comme votre 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 seule l'application Google Maps est 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é le moyen de nommer l'emplacement actuel), il vous suffit de déposer le paramètre saddr 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);

Pour être complet, si l'utilisateur n'a pas installé l'application de cartes, il sera judicieux d'attraper l'exception ActivityNotFoundException, comme l'indique @TonyQ, nous pouvons alors relancer l'activité sans la restriction de l'application de cartes. Nous pouvons en être assez sûr. que nous n'allons jamais au Toast à la fin, car un navigateur Internet est également une application valide pour lancer 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();
            }
        }

MODIFIER:

Pour les itinéraires, une intention de navigation est maintenant 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);
86
David Thompson

L'utilisation du format de chaîne aidera, mais vous devez être attentif aux paramètres régionaux. En Allemagne, float sera séparé avec en virgule un point. 

Si vous utilisez String.format("geo:%f,%f",5.1,2.1); sur les paramètres régionaux anglais, le résultat sera "geo:5.1,2.1", mais avec les paramètres régionaux allemand, 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 information géographique en utilisant:

!!! mais attention, le geo-uri est encore en développementhttp://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);
39
David Boho

Vérifiez cette page de google:

http://developer.Android.com/guide/appendix/g-app-intents.html

Vous pouvez utiliser un URI de la forme 

geo:latitude,longitude

pour ouvrir l'afficheur de carte Google et le diriger vers un emplacement.

8
Snicolas

Parfois, si aucune application n'est associée à geo: protocal, .__, vous pouvez utiliser try-catch pour que ActivityNotFoundException le gère.

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

6
TonyQ

Vous pouvez également utiliser l'extrait de code ci-dessous. Ainsi, l'existence de Google Maps est vérifiée avant le démarrage 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

6
Kerim Gökarslan

J'ai un exemple d'application où je prépare l'intention et passe simplement le nom de la ville dans l'activité du marqueur de cartes, qui calcule finalement la longitude et la latitude par géocodeur à l'aide de CITY_NAME.

Vous trouverez ci-dessous l'extrait de code indiquant le démarrage de l'activité du marqueur de cartes et de 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 donc j'ai collé le code complet ci-dessus, mais juste au cas où vous voudriez voir le code complet, il est disponible à l'adresse suivante: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753

0
JRG