81

I am trying to open google maps or maps in my react-native application.

When I run the app on my iPhone/simulator, I receive this error

"Don't know how to open URI:...".

What I am doing wrong?

My code:

    openGps() {
      var url = 'geo:37.484847,-122.148386'
      this.openExternalApp(url)
    }
    
    openExternalApp(url) {
      Linking.canOpenURL(url).then(supported => {
        if (supported) {
          Linking.openURL(url);
        } else {
          console.log('Don\'t know how to open URI: ' + url);
        }
      });
    }
David Leuliette
  • 1,595
  • 18
  • 26
lolix
  • 1,447
  • 2
  • 19
  • 23

18 Answers18

243

To open url with custom label ios/android:

const scheme = Platform.select({ ios: 'maps://0,0?q=', android: 'geo:0,0?q=' });
const latLng = `${lat},${lng}`;
const label = 'Custom Label';
const url = Platform.select({
  ios: `${scheme}${label}@${latLng}`,
  android: `${scheme}${latLng}(${label})`
});

    
Linking.openURL(url);
Collin Price
  • 5,620
  • 3
  • 33
  • 35
Narek Ghazaryan
  • 2,758
  • 1
  • 7
  • 11
23

This is because iOS does not yet have support for geo: yet as mentioned in this SO answer. What you can do is detect the OS and:

  • use geo: on Android
  • handle iOS differently. Possibly use maps: as it will open up Apple Maps, though I'm unsure how to properly send the coordinates to it. Or maybe append it to a google maps HTTP URL and open it in the browser.

For example, your openGps function could look like this:

openGps = (lat, lng) => {
  var scheme = Platform.OS === 'ios' ? 'maps:' : 'geo:';
  var url = scheme + `${lat},${lng}`;
  Linking.openURL(url);
}
TheMisir
  • 4,083
  • 1
  • 27
  • 37
Michael Cheng
  • 9,644
  • 6
  • 46
  • 48
23

you can do like this:

Android:

 <TouchableOpacity onPress={() => Linking.openURL('google.navigation:q=100+101')}>

where q is the destination lat + long

IOS:

  <TouchableOpacity onPress={() => Linking.openURL('maps://app?saddr=100+101&daddr=100+102')}>

where saddr is start address and daddr is destination address lat+long

oma
  • 1,804
  • 12
  • 13
23
const url = Platform.select({
  ios: `maps:0,0?q=${fullAddress}`,
  android: `geo:0,0?q=${fullAddress}`,
})

Linking.openURL(url)
Pragnesh
  • 404
  • 3
  • 15
12
const latitude = "40.7127753";
const longitude = "-74.0059728";
const label = "New York, NY, USA";

const url = Platform.select({
  ios: "maps:" + latitude + "," + longitude + "?q=" + label,
  android: "geo:" + latitude + "," + longitude + "?q=" + label
});
Linking.openURL(url);

or with checking if there's a google map app on device and if not open the location in browser

const latitude = "40.7127753";
const longitude = "-74.0059728";
const label = "New York, NY, USA";

const url = Platform.select({
  ios: "maps:" + latitude + "," + longitude + "?q=" + label,
  android: "geo:" + latitude + "," + longitude + "?q=" + label
});

Linking.canOpenURL(url).then(supported => {
  if (supported) {
    return Linking.openURL(url);
  } else {
    const browser_url =
      "https://www.google.de/maps/@" +
      latitude +
      "," +
      longitude +
      "?q=" +
      label;
    return Linking.openURL(browser_url);
  }
});
omerts
  • 8,485
  • 2
  • 32
  • 39
Ali Mohammad
  • 794
  • 9
  • 16
  • 1
    With this answer the map opens along with custom label which is a good thing. But a major issue in this approach is that if I have multiple addresses with same block names in different cities then no matter which lat long I provide, it always takes me to the first city with the given block name. If there is a fix for that then this would be a good solution. – Pooja Mule Nov 29 '21 at 12:54
  • This just search apple maps and google maps for the label and ignores the coordinates. – Simon Bengtsson Feb 21 '23 at 09:24
10

Working on Android with an address using the following:

Linking.openURL('https://www.google.com/maps/search/?api=1&query=address');

Replace address with your favourite address.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Yossi
  • 5,577
  • 7
  • 41
  • 76
4

To complement other answers, here's a snippet of adding a marker on Android:

    const location = `${latitude},${longitude}`
    const url = Platform.select({
      ios: `maps:${location}`,
      android: `geo:${location}?center=${location}&q=${location}&z=16`,
    });
    Linking.openURL(url);

If you want more details about Android and google maps, here's the link for the documentation: https://developers.google.com/maps/documentation/urls/android-intents

betoharres
  • 1,736
  • 2
  • 19
  • 25
3

I've tried this solution and it's working

const scheme = Platform.select({ ios: 'maps:0,0?q=', android: 'geo:0,0?q=' });
const latLng = `${lat},${lng}`;
const label = 'Custom Label';
const url = Platform.select({
  ios: `${scheme}${label}@${latLng}`,
  android: `${scheme}${latLng}(${label})`
});

Linking.openURL(url);

David Buck
  • 3,752
  • 35
  • 31
  • 35
Akhele
  • 131
  • 3
  • 9
3

For apple maps direction with coordinate like this

Linking.openURL(`maps://app?daddr=${latitude},${longitude}&dirflg=d&t=m`)

dirflg = The transport type.

  1. d (by car)
  2. w (by foot)
  3. r (by public transit)

t = map type m standart view

daddr = destination address

enter image description here

Yakup DURMUS
  • 139
  • 5
2

From the documentation in Apple Map Links, a little changes from @Narek Ghazaryan's answer. This is due to apple maps will query on provided "label" first. If the label or store name do not exist, it will show nothing.

So we need to add a parameter as "ll" to specify current location with the provided label / store name.

const scheme = Platform.select({ ios: 'maps:0,0?q=', android: 'geo:0,0?q=' });
const latLng = `${lat},${lng}`;
const label = 'Custom Label';
const url = Platform.select({
  ios: `${scheme}${label}&ll=${latLng}`,
  android: `${scheme}${latLng}(${label})`
});
Kyo Kurosagi
  • 2,177
  • 1
  • 18
  • 18
2

One solution is to use react-native-map-link lib. It opens a bottom sheet with desired options

import { showLocation } from 'react-native-map-link'

showLocation({
    latitude: 38.8976763,
    longitude: -77.0387185,
    sourceLatitude: -8.0870631,  // optionally specify starting location for directions
    sourceLongitude: -34.8941619,  // not optional if sourceLatitude is specified
    title: 'The White House',  // optional
    googleForceLatLon: false,  // optionally force GoogleMaps to use the latlon for the query instead of the title
    googlePlaceId: 'ChIJGVtI4by3t4kRr51d_Qm_x58',  // optionally specify the google-place-id
    alwaysIncludeGoogle: true, // optional, true will always add Google Maps to iOS and open in Safari, even if app is not installed (default: false)
    dialogTitle: 'This is the dialog Title', // optional (default: 'Open in Maps')
    dialogMessage: 'This is the amazing dialog Message', // optional (default: 'What app would you like to use?')
    cancelText: 'This is the cancel button text', // optional (default: 'Cancel')
    appsWhiteList: ['google-maps'] // optionally you can set which apps to show (default: will show all supported apps installed on device)
    // appTitles: { 'google-maps': 'My custom Google Maps title' } // optionally you can override default app titles
    // app: 'uber'  // optionally specify specific app to use
})
Mihail
  • 1,246
  • 1
  • 9
  • 8
2

With the help of oma's answer, I came up with this. For the ios version, I directly wrote googleMaps instead of maps because it did not work. This is given that Google Maps is installed on the device and I tested this with a physical device. If its not installed it will go into the store. It works perfectly while starting the navigation too.

<Button
  hasText
  transparent
  onPress={() =>
    Linking.openURL(
      Platform.OS === 'ios'
        ? 'googleMaps://app?saddr=6.931970+79.857750&daddr=6.909877+79.848521'
        : 'google.navigation:q=6.909877+79.848521',
    )
 }>
    <Text>Open Maps</Text>
 </Button>

FYI - Im using the Button component from the Native Base library.

Dilshan Liyanage
  • 4,440
  • 2
  • 31
  • 33
2

For google map/Map direction, you can use this code

const latitude = "30.3753";
const longitude = "69.3451";
const openMapDirection = () => {
    const url: any = Platform.select({
      ios: `comgooglemaps://?center=${latitude},${longitude}&q=${latitude},${longitude}&zoom=14&views=traffic"`,
      android: `geo://?q=${latitude},${longitude}`,
    });
    Linking.canOpenURL(url)
      .then((supported) => {
        if (supported) {
          return Linking.openURL(url);
        } else {
          const browser_url = `https://www.google.de/maps/@${latitude},${longitude}`;
          return Linking.openURL(browser_url);
        }
      })
      .catch(() => {
        if (Platform.OS === 'ios') {
          Linking.openURL(
            `maps://?q=${latitude},${longitude}`,
          );
        }
      });
  };

Note: For open google map on IOS you have to add this in info.plist

<key>LSApplicationQueriesSchemes</key>
  <array>
   <string>comgooglemaps</string>
  </array>
Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80
2

I have created a separate component for store location and full code is as under.

Component code:

import React from "react";
import { View, Pressable, Platform, Linking } from "react-native";
import styles from "./styles";
import Text from "../Text";

const StoreLocation = ({}) => {

  /**
   * method to open google map
   */
  const openMap = () => {
    const latitude = 33.189368147027565; // latitude of your desire location
    const longitude = 73.35574341458842; // longitude of your desire location
    const scheme = Platform.select({
      ios: "maps:0,0?q=",  // if device is ios 
      android: "geo:0,0?q=", // if device is android 
    });
    const latLng = `${latitude},${longitude}`;
    const label = "your own label";
    const url = Platform.select({
      ios: `${scheme}${label}@${latLng}`,
      android: `${scheme}${latLng}(${label})`,
    });

    Linking.openURL(url);
  };

  return (
    <Pressable onPress={() => openMap()} style={styles.mapView}>
      <View>
        <Text>Open Map</Text>
      </View>
    </Pressable>
  );
};

export default StoreLocation;

if you only want to use method just copy openMap() method and change your desired longitude, latitude & label to use this method according to your app.

tested on Android

راجہ مخلص
  • 1,177
  • 6
  • 15
1

I think react-native-launch-navigator module is a much cleaner way of doing this. Then it is simple as LaunchNavigator.navigate([50.279306, -5.163158], {start: "50.342847, -4.749904"}) .then(() => console.log("Launched navigator")) .catch((err) =>console.error("Error launching navigator: "+err));.

Erangad
  • 671
  • 7
  • 16
1

I found this to be the easiest way to navigate from your app to Google Maps

const url = `https://www.google.com/maps/dir/?api=1&destination=lat,long&dir_action=navigate`
Linking.openURL(url);
Ahmed Imam
  • 1,315
  • 2
  • 19
  • 42
0

you can also use this solution

Linking.openURL(`https://www.google.com/maps/dir/?api=1&origin=${startPlace.latitude},${startPlace.longitude}&destination=${endPlace.latitude},${endPlace.longitude}`)

reference: https://developers.google.com/maps/documentation/urls/get-started#map-action

sobol
  • 1
  • 2
-1

This Will work....

const lat = "12.914490",
const lng = "77.666512",
const lable = "Any Title",

const scheme = Platform.OS === "android" ? "geo:0,0?q=" : "maps:0,0?q=";
var latLng = `${lat},${lng}`;
var label = lable;

const url = Platform.select({
   ios: `${scheme}${label}@${latLng}`,
   android: `${scheme}${latLng}(${label})`,
});

console.log(url)