tschoffelen / react-native-map-link

🗺 Open the map app of the user's choice.
MIT License
663 stars 141 forks source link
android directions ios maps react-native

React Native Map Link

GitHub release npm GitHub license


An easy way to open a location in a map app of the user's choice, based on the apps they have installed on their device. The app supports Apple Maps, Google Maps, Citymapper, Uber, and a dozen other apps.

Full list of supported apps - Apple Maps – `apple-maps` - Google Maps – `google-maps` - Citymapper – `citymapper` - Uber – `uber` - Lyft – `lyft` - The Transit App – `transit` - TruckMap – `truckmap` - Waze – `waze` - Yandex.Navi – `yandex` - Moovit – `moovit` - Yandex Taxi – `yandex-taxi` - Yandex Maps – `yandex-maps` - Kakao Map – `kakaomap` - TMAP - `tmap` - Mapy.cz – `mapycz` - Maps.me – `maps-me` - OsmAnd - `osmand` - Gett - `gett` - Naver Map - `navermap` - 2GIS - `dgis` - Liftago - `liftago` - Petal Maps - `petalmaps` (Android only) - Sygic - `sygic`


Example screenshot

Installation

1. Install the package

npm i -S react-native-map-link      # or yarn add react-native-map-link

2. Post-install steps

Based on the platforms your app supports, you also need to:

iOS – Update Info.plist To allow your app to detect if any of the directions apps are installed, an extra step is required on iOS. Your app needs to provide the `LSApplicationQueriesSchemes` key inside `ios/{my-project}/Info.plist` to specify the URL schemes with which the app can interact. Just add this in your `Info.plist` depending on which apps you'd like to support. Omitting these might mean that the library can't detect some of the maps apps installed by the user. ```xml LSApplicationQueriesSchemes comgooglemaps citymapper uber lyft transit truckmap waze yandexnavi moovit yandextaxi yandexmaps kakaomap tmap szn-mapy mapsme osmandmaps gett nmap dgis lftgpas sygic ``` Using Expo? [Read the instructions](docs/expo.md) to make it work on iOS.
Android – Update AndroidManifest.xml When switching to Android 11/Android SDK 30 (i.e. using Expo SDK 41), this library doesn't work out of the box anymore. The reason is the new [Package Visibilty](https://developer.android.com/training/package-visibility) security feature. We'll have to update our `AndroidManifest.xml` to explicitly allow querying for other apps. You can do so by coping the `` statement below, and pasting it in the top level of your AndroidManifest (i.e. within the ` ... `). ```xml ``` If you're running into a 'unexpected element `` found in ``' error, make sure you have an updated version of Gradle in your `android/build.gradle` file: ```java classpath("com.android.tools.build:gradle:3.5.4") ``` More info [here](https://stackoverflow.com/a/67383641/1129689).
Expo – Update app.json [Read the instructions here](docs/expo.md)

Simple example

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

showLocation({
  latitude: 38.8976763,
  longitude: -77.0387185,
  title: 'Your destination',
});

Full usage

Using the showLocation function will shown an action sheet on iOS and an alert on Android, without any custom styling:

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, // required 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)
  naverCallerName: 'com.example.myapp', // to link into Naver Map You should provide your appname which is the bundle ID in iOS and applicationId in android.
  appTitles: {'google-maps': 'My custom Google Maps title'}, // optionally you can override default app titles
  app: 'uber', // optionally specify specific app to use
  directionsMode: 'walk', // optional, accepted values are 'car', 'walk', 'public-transport' or 'bike'
});

Alternatively you can specify the address field and leave the latitude and longitude properties as empty strings

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

showLocation({
  address: '1600 Pennsylvania Avenue NW, Washington, DC 20500', // Required if replacing latitude and longitude
  app: 'comgooglemaps',  // optionally specify specific app to use
});

Notes:

Or

Using the getApps function will return an array (GetAppResult[]) with the apps available on the smartphone:

type GetAppResult = {
  id: string;
  name: string;
  icon: NodeRequire;
  open: () => Promise<void>;
};
import {getApps, GetAppResult} from 'react-native-map-link';

const Demo = () => {
  const [availableApps, setAvailableApps] = useState<GetAppResult[]>([]);

  useEffect(() => {
    (async () => {
      const result = await getApps({
        latitude: 38.8976763,
        longitude: -77.0387185,
        address: '1600 Pennsylvania Avenue NW, Washington, DC 20500', // optional 
        title: 'The White House', // optional
        googleForceLatLon: false, // optionally force GoogleMaps to use the latlon for the query instead of the title
        alwaysIncludeGoogle: true, // optional, true will always add Google Maps to iOS and open in Safari, even if app is not installed (default: false)
        appsWhiteList: ['google-maps'], // optionally you can set which apps to show (default: will show all supported apps installed on device)
      });
      setAvailableApps(result);
    })();
  }, []);

  return (
    <React.Fragment>
      {availableApps.map(({icon, name, id, open}) => (
        <Pressable key={id} onPress={open}>
          <Image source={icon} />
          <Text>{name}</Text>
        </Pressable>
      ))}
    </React.Fragment>
  );
};

More information




Get professional support for this package →
Custom consulting sessions available for implementation support or feature development.