Запуск Google Maps Directions через намерение на Android


399

Мое приложение должно показывать направления Google Maps от A до B, но я не хочу помещать Google Maps в свое приложение - вместо этого я хочу запустить его с помощью Intent. Это возможно? Если да, то как?


Ответы:


630

Вы можете использовать что-то вроде этого:

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, 
    Uri.parse("http://maps.google.com/maps?saddr=20.344,34.34&daddr=20.5666,45.345"));
startActivity(intent);

Чтобы начать навигацию с текущего местоположения, удалите saddr параметр и значение.

Вы можете использовать фактический адрес улицы вместо широты и долготы. Однако это даст пользователю возможность выбора между открытием через браузер или Google Maps.

Это запустит Google Maps в режиме навигации напрямую:

Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
    Uri.parse("google.navigation:q=an+address+city"));

ОБНОВИТЬ

В мае 2017 года Google запустил новый API для универсальных кроссплатформенных URL-адресов Карт Google:

https://developers.google.com/maps/documentation/urls/guide

Вы также можете использовать Intents с новым API.


2
Не то, чтобы я в курсе. Однако не будет никакого диалога, если пользователь уже выбрал приложение по умолчанию, чтобы открыть этот тип намерений быть приложением карты.
Jan S.

111
Если вы хотите избавиться от диалогового окна, вы можете дать подсказку, какой пакет вы хотите использовать. Перед startActivity () добавьте это: intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
Джереми Логан

а как заставить его показывать на навигаторе а не в приложении гуглмапс?
NullPointerException

68
Принуждение пользователя к определенной деятельности, когда у него могут быть другие приложения, которые он предпочитает, кажется мне противоречащим духу Android. Я был бы соблазн позволить фильтрам намерений позаботиться о вещах здесь.
суперсветовой

15
Похоже, что теперь
навигационные цели

124

Это немного не по теме, потому что вы спрашивали «указания», но вы также можете использовать схему Geo URI, описанную в документации Android:

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

Проблема с использованием «гео: широта, долгота» заключается в том, что Карты Google центрируются только в вашей точке без каких-либо булавок или меток.

Это довольно запутанно, особенно если вам нужно указать точное место или / и попросить указания.

Если вы используете параметр запроса "geo: lat, lon? Q = name" для того, чтобы пометить свое геопункт, он использует запрос для поиска и отклоняет параметры lat / lon.

Я нашел способ центрировать карту с широтой / долготой и отобразить булавку с пользовательской меткой, что очень удобно для отображения и полезно при запросе указаний или любых других действий:

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, 
Uri.parse("geo:0,0?q=37.423156,-122.084917 (" + name + ")"));
startActivity(intent);

ПРИМЕЧАНИЕ (от @TheNail): не работает в Maps v.7 (последняя версия на момент написания). Будет игнорировать координаты и искать объект с заданным именем в скобках. См. Также Назначение для Google Maps 7.0.0 с указанием местоположения.


3
Хорошо, по умолчанию geo: 0,0 просто перемещает карту туда. Это решение ["geo: 0,0? Q = 37.423156, -122.084917 (" + name + ")"] позволяет ввести собственное имя маркера. Спасибо.
gnac

4
Прекрасно работает - fyi не работает вместе с параметром запроса "z" (уровень масштабирования)
scolestock

1
Можно ли установить режим транзита по умолчанию в намерении. По умолчанию выбран вариант автомобиля. Могу ли я установить Walking как режим по умолчанию?
Медведь

6
Почему ты не используешь geo:37.423156,-122.084917?q=37.423156,-122.084917 ...?
rekire

1
Убедитесь, что вы urlEncode параметра метки. У меня были проблемы со специальными символами, такими как пробел.
Итан

100

Хотя текущие ответы великолепны, ни один из них не сделал то, что я искал, я хотел открыть только приложение карт, добавить имя для каждого исходного местоположения и пункта назначения, используя схему гео-URI для меня и вообще, на веб-ссылке на картах не было ярлыков, поэтому я пришел к этому решению, которое, по сути, представляет собой объединение других решений и комментариев, сделанных здесь, надеюсь, это будет полезно для других, просматривающих этот вопрос.

String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?saddr=%f,%f(%s)&daddr=%f,%f (%s)", sourceLatitude, sourceLongitude, "Home Sweet Home", 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);

Чтобы использовать ваше текущее местоположение в качестве отправной точки (к сожалению, я не нашел способа обозначить текущее местоположение), используйте следующее

String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?daddr=%f,%f (%s)", 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);

Для полноты, если у пользователя нет установленного приложения карт, то будет хорошей идеей перехватить ActivityNotFoundException, тогда мы сможем начать действие снова без ограничения приложения карт, мы можем быть уверены, что никогда не получим Toast в конце, так как интернет-браузер является допустимым приложением для запуска этой схемы URL.

        String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?daddr=%f,%f (%s)", 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();
            }
        }

PS Любые широты или долготы, использованные в моем примере, не являются репрезентативными для моего местоположения, любое сходство с истинным местоположением является чистым совпадением, иначе я не из Африки: P

РЕДАКТИРОВАТЬ:

Для указаний теперь поддерживается навигация с помощью google.navigation.

Uri navigationIntentUri = Uri.parse("google.navigation:q=" + 12f +"," + 2f);//creating intent with latlng
Intent mapIntent = new Intent(Intent.ACTION_VIEW, navigationIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);

2
Это отличный ответ, Дэвид! Кроме того, вы знаете, как действительно запустить навигацию, находясь в приложении навигации? В своем нынешнем состоянии пользователь должен нажать «Начать навигацию» в последний раз. Я искал в Google какой-либо параметр для передачи, но не смог найти ни одного.
Нирмал

При нажатии кнопки «Назад» в приложении «Карты» появляется черный экран и воссоздается основное действие. Есть идеи, как это исправить?
Jas

@Jas удалить метод intent.setclassname
Ameen Maheen

Привет, приведенный выше код занимает много времени, чтобы запустить приложение карты по умолчанию в Android версии 4.4.2, 4.4.4 и 5.0.2. Хорошо запускается в версии 5.1 и Marshmallow. Не могли бы вы помочь в решении этой проблемы.
OnePunchMan

Теперь я бы предложил использовать intent.SetPackage вместо intent.setClassName ("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"); Я обновлю ответ, чтобы отразить это.
Дэвид Томпсон

22

Использование последних кроссплатформенных URL Карт Google : даже если приложение Google Maps отсутствует, оно откроется в браузере

Пример https://www.google.com/maps/dir/?api=1&origin=81.23444,67.0000&destination=80.252059,13.060604

Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
    .authority("www.google.com")
    .appendPath("maps")
    .appendPath("dir")
    .appendPath("")
    .appendQueryParameter("api", "1")
    .appendQueryParameter("destination", 80.00023 + "," + 13.0783);
String url = builder.build().toString();
Log.d("Directions", url);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);

10

Откройте Google Карты, используя Intent с разными режимами:

Мы можем открыть приложение Google Maps, используя намерение:

val gmmIntentUri = Uri.parse("google.navigation:q="+destintationLatitude+","+destintationLongitude + "&mode=b")
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
startActivity(mapIntent)

Здесь «mode = b» для велосипеда.

Мы можем установить режимы вождения, ходьбы и езды на велосипеде, используя:

  • г для вождения
  • ш для прогулок
  • б для езды на велосипеде

Вы можете узнать больше о намерениях с Google Maps здесь .

Примечание: если нет маршрута для велосипеда / автомобиля / пешехода, он покажет вам «Не могу найти дорогу туда»

Вы можете проверить мой оригинальный ответ здесь .


8

Ну, вы можете попробовать открыть встроенное приложение Android Maps с помощью Intent.setClassNameметода.

Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse("geo:37.827500,-122.481670"));
i.setClassName("com.google.android.apps.maps",
    "com.google.android.maps.MapsActivity");
startActivity(i);

6

Для нескольких точек маршрута также могут быть использованы следующие.

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, 
    Uri.parse("https://www.google.com/maps/dir/48.8276261,2.3350114/48.8476794,2.340595/48.8550395,2.300022/48.8417122,2.3028844"));
startActivity(intent);

Первый набор координат - ваше начальное местоположение. Все следующие являются путевыми точками, проложенный маршрут проходит.

Просто продолжайте добавлять путевые точки, указав в конце «/ широта, долгота». Существует, по-видимому, ограничение в 23 путевых точки в соответствии с Google Docs . Не уверен, что это относится и к Android.


Что не работает? Что вы видите при выполнении этого точного кода?
Адел Тарик

На самом деле не используйте точные координаты, которые я здесь поставил. Они где-то посреди, где нет дорог, так что это не сработает.
Адель Тарик,

4

Если вы заинтересованы в отображении широты и долготы от текущего направления, вы можете использовать это:

Направления всегда даны от текущего местоположения пользователей.

Следующий запрос поможет вам выполнить это. Вы можете передать широту и долготу пункта назначения здесь:

google.navigation:q=latitude,longitude

Используйте выше как:

Uri gmmIntentUri = Uri.parse("google.navigation:q=latitude,longitude");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);

Или, если вы хотите показать через местоположение, используйте:

google.navigation:q=a+street+address

Больше информации здесь: Google Maps Intents для Android


для направления работы, мне нужно было добавитьmapIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Кто-то где-то

4

Google DirectionsViewс местоположением источника в качестве текущего местоположения и местоположения пункта назначения, заданного в виде строки

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?f=d&daddr="+destinationCityName));
intent.setComponent(new ComponentName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"));
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

В приведенном выше destinationCityNameтексте строка может быть изменена при необходимости.


3

попробуй это

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr="+src_lat+","+src_ltg+"&daddr="+des_lat+","+des_ltg));
intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
startActivity(intent);

3

Вот что сработало для меня:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://maps.google.co.in/maps?q=" + yourAddress));
if (intent.resolveActivity(getPackageManager()) != null) {
   startActivity(intent);
}

1

если вы знаете точку A, точку B (и любые другие объекты или дорожки между ними), вы можете использовать файл KML вместе со своими намерениями.

String kmlWebAddress = "http://www.afischer-online.de/sos/AFTrack/tracks/e1/01.24.Soltau2Wietzendorf.kml";
String uri = String.format(Locale.ENGLISH, "geo:0,0?q=%s",kmlWebAddress);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);

для получения дополнительной информации см. этот SO ответ

ПРИМЕЧАНИЕ. В этом примере используется образец файла, который (по состоянию на 13 марта) все еще находится в сети. если он отключился, найдите файл kml в Интернете и измените свой URL


1
При нажатии кнопки «Назад» в приложении «Карты» появляется черный экран и воссоздается основное действие. Есть идеи, как это исправить?
Jas

@Jas, Google изменил много своих API, и это поведение, возможно, также изменилось. Я уже давно пользуюсь открытыми картами улиц, поэтому я смогу вам помочь. :)
Тони Гил

0

Прежде всего вам нужно теперь, чтобы вы могли использовать неявное намерение, документация Android предоставляет нам очень подробные общие намерения для реализации намерения карты, вам нужно создать новое намерение с двумя параметрами

  • действие
  • Uri

Для действий, которые мы можем использовать, Intent.ACTION_VIEW а для Uri мы должны построить его, ниже я приложил пример кода для создания, построения и запуска действия.

 String addressString = "1600 Amphitheatre Parkway, CA";

    /*
    Build the uri 
     */
    Uri.Builder builder = new Uri.Builder();
    builder.scheme("geo")
            .path("0,0")
            .query(addressString);
    Uri addressUri = builder.build();
    /*
    Intent to open the map
     */
    Intent intent = new Intent(Intent.ACTION_VIEW, addressUri);

    /*
    verify if the devise can launch the map intent
     */
    if (intent.resolveActivity(getPackageManager()) != null) {
       /*
       launch the intent
        */
        startActivity(intent);
    }

1
Использование Uri.Builder работает только для абсолютных URI в форме:, а <scheme>://<authority><absolute path>?<query>#<fragment>не непрозрачных URI <scheme>:<opaque part>#<fragment>. Приведенный выше код приводит к следующему URI: geo:/0%2C0?Eiffel%20Towerчто приводит к сбою приложения Google Maps. По этой же причине даже официальная документация использует необработанные / непрозрачные URI. Правильный код будет:Uri.parse("geo:0,0?q=" + Uri.encode("Eiffel Tower"))
Bitek

Также см. Этот ответ для объяснения того, почему ваш ответ не работает: stackoverflow.com/a/12035226/313113
bitek

0

Хорошее решение kotlin, использующее последний кроссплатформенный ответ, упомянутый lakshman sai ...

Нет ненужных Uri.toString и Uri.parse, хотя этот ответ чистый и минимальный:

 val intentUri = Uri.Builder().apply {
      scheme("https")
      authority("www.google.com")
      appendPath("maps")
      appendPath("dir")
      appendPath("")
      appendQueryParameter("api", "1")
      appendQueryParameter("destination", "${yourLocation.latitude},${yourLocation.longitude}")
 }.build()
 startActivity(Intent(Intent.ACTION_VIEW).apply {
      data = intentUri
 })

0

Таким способом вы можете запустить Google Maps Directions через Android

btn_search_route.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String source = et_source.getText().toString();
            String destination = et_destination.getText().toString();

            if (TextUtils.isEmpty(source)) {
                et_source.setError("Enter Soruce point");
            } else if (TextUtils.isEmpty(destination)) {
                et_destination.setError("Enter Destination Point");
            } else {
                String sendstring="http://maps.google.com/maps?saddr=" +
                        source +
                        "&daddr=" +
                        destination;
                Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
                        Uri.parse(sendstring));
                startActivity(intent);
            }
        }

    });
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.