react-native-location
Native GPS location support for React Native. You might decide to use this library over the built-in geolocation because it includes some additional features:
NSLocationAlwaysUsageDescription
property, however, you might have a usecase where you want to start by asking the user for "while in use" permission and later upgrade the permission to "always" when they turn on a feature which requires background location.RNLocation.getCurrentPermission
).Install the library using either Yarn:
yarn add react-native-location
or using npm:
npm install --save react-native-location
You then need to link the native parts of the library for the platforms you are using. Click on the arrow to show the steps for each platform.
In the example folder is a React Native sample app which you can use as a sample implementation to start from.
The app requests permissions, takes reading every 5 distance and starts immediately. To use in the iOS simulator, look on the Debug -> Location
menu for sample trips that will show you updating location such as City Bycicle Ride, City Run, and Freeway Drive.
import RNLocation from 'react-native-location';
RNLocation.configure({
distanceFilter: 5.0
})
RNLocation.requestPermission({
ios: "whenInUse",
android: {
detail: "coarse"
}
}).then(granted => {
if (granted) {
this.locationSubscription = RNLocation.subscribeToLocationUpdates(locations => {
/* Example location returned
{
speed: -1,
longitude: -0.1337,
latitude: 51.50998,
accuracy: 5,
heading: -1,
altitude: 0,
altitudeAccuracy: -1
floor: 0
timestamp: 1446007304457.029,
fromMockProvider: false
}
*/
})
}
})
To access the methods, you need import the react-native-location
module. This is done through import RNLocation from 'react-native-location'
.
RNLocation.configure
This is used to configure the location provider. You can use this to enable background mode, filter location updates to a certain distance change, and ensure you have the power settings set correctly for your use case.
You can call configure
multiple times at it will only change the setting which you pass to it. For example if you only want to change activityType
, you can call configure
with just that property present.
RNLocation.configure({
distanceFilter: 100, // Meters
desiredAccuracy: {
ios: "best",
android: "balancedPowerAccuracy"
},
// Android only
androidProvider: "auto",
interval: 5000, // Milliseconds
fastestInterval: 10000, // Milliseconds
maxWaitTime: 5000, // Milliseconds
// iOS Only
activityType: "other",
allowsBackgroundLocationUpdates: false,
headingFilter: 1, // Degrees
headingOrientation: "portrait",
pausesLocationUpdatesAutomatically: false,
showsBackgroundLocationIndicator: false,
})
There are the valid configuration options and what they do:
Option | Platforms | Description | Values | Documentation |
---|---|---|---|---|
distanceFilter |
Android iOS | The minimum distance in meters that the device location needs to change before the location update callback in your app is called. Defaults to 0 for no filtering. |
number |
Android Docs Apple Docs |
desiredAccuracy |
Android iOS |
The accuracy of the location data. Defaults to Valid options for Valid options for |
{ android: string, ios: string }
|
Android Docs Apple Docs |
androidProvider |
Android | The provider which is used on Android to get the location. Your app must include the Google Play services dependencies to use the playServices location provider. By default it will choose the playServices location provider if it detects that the dependencies are installed, otherwise, it will use the standard Android version which does not require Google Play Services to be installed. Note that auto only checks that the dependencies are installed, not that the user has the Google Play services APK installed and set up correctly. |
"auto" , "playServices" , or "standard" |
|
interval |
Android |
Set the desired interval for active location updates, in milliseconds. The location client will actively try to obtain location updates for your application at this interval, so it has a direct influence on the amount of power used by your application. Choose your interval wisely. This interval is inexact. You may not receive updates at all (if no location sources are available), or you may receive them slower than requested. You may also receive them faster than requested (if other applications are requesting location at a faster interval). |
number |
Android Docs |
fastestInterval |
Android |
Explicitly set the fastest interval for location updates, in milliseconds. This controls the fastest rate at which your application will receive location updates, which might be faster than `interval` in some situations (for example, if other applications are triggering location updates). This allows your application to passively acquire locations at a rate faster than it actively acquires locations, saving power. By default this is 6x the `interval`. |
number |
Android Docs |
maxWaitTime |
Android |
Sets the maximum wait time in milliseconds for location updates. If you pass a value at least 2x larger than the interval specified with setInterval(long), then location delivery may be delayed and multiple locations can be delivered at once. |
number |
Android Docs |
allowsBackgroundLocationUpdates |
iOS | A Boolean value indicating whether the app should receive location updates when suspended. Requires permissions to always access the users location. Defaults to false . |
boolean |
Apple Docs |
activityType |
iOS | The type of user activity associated with the location updates. Defaults to other . |
"other" , "automotiveNavigation" , "fitness" , "otherNavigation" , or "airborne" |
Apple Docs |
headingFilter |
iOS | The minimum angle in degrees that the device heading needs to change before the heading update callback in your app is called. Defaults to 0 for no filtering. |
number |
|
headingOrientation |
iOS | The device orientation to use when computing heading values. Defaults to portrait . |
"portrait" , "portraitUpsideDown" , "landscapeLeft" , or "landscapeRight" |
Apple Docs |
pausesLocationUpdatesAutomatically |
iOS | A Boolean value indicating whether the location manager object may pause location updates. Defaults to true . |
boolean |
Apple Docs |
showsBackgroundLocationIndicator |
iOS | A Boolean indicating whether the status bar changes its appearance when location services are used in the background. Defaults to false . Only works on iOS 11+ and is ignored for earlier versions of iOS. |
boolean |
Apple Docs |
Correctly managing permissions is key to working with the users location in mobile apps.
whenInUse
(foreground) permission rather than background.false
.always
permission then the user gets the chance to accept, but only give you whenInUse
permission. The Promise will still resolve to false
, however, if you call RNLocation.getCurrentPermission
you can check if they actually accepted the lesser permission.RNLocation.requestPermission
This method should be called before subscribing to location updates. You need to pass in the type of permission you want for each platform. You can choose not to ignore a platform and it will be ignored. The method returns a promise which resolves to true
if the permission was granted and false
if not. For Android you can optionally provide a rationale
which will be displayed if you ask the user for permission a 2nd time after they have denied permission once.
RNLocation.requestPermission({
ios: 'whenInUse', // or 'always'
android: {
detail: 'coarse', // or 'fine'
rationale: {
title: "We need to access your location",
message: "We use your location to show where you are on the map",
buttonPositive: "OK",
buttonNegative: "Cancel"
}
}
});
RNLocation.checkPermission
Checks if the currently granted permissions match the given options. You can call this before requestPermission
to check if you already have the permission level you would like. This is especially useful if you want to display a message to the user about not having the correct permissions before actually requesting them.
RNLocation.checkPermission({
ios: 'whenInUse', // or 'always'
android: {
detail: 'coarse' // or 'fine'
}
});
RNLocation.getCurrentPermission
Gets the current permission status. Note that the values will be different on Android and iOS as the permission systems are different. It's usually best to use RNLocation.checkPermission
instead of checking the permission status yourself to avoid re-implementing the logic.
RNLocation.getCurrentPermission()
.then(currentPermission => {
...
})
RNLocation.subscribeToPermissionUpdates
Monitor the permission status for changes.
// Subscribe
const unsubscribe = RNLocation.subscribeToPermissionUpdates(currentPermission => {
...
})
// Unsubscribe
unsubscribe();
RNLocation.subscribeToLocationUpdates
Subscribe to location changes with the given listener. Ensure you have the correct permission before calling this method. The location provider will respect the settings you have given it. Each event may return an array with more than one location. This is because the OS might batch location updates together and deliver them all at once. Take a look at the timestamp
to find the latest.
// Subscribe
const unsubscribe = RNLocation.subscribeToLocationUpdates(locations => {
...
})
// Unsubscribe
unsubscribe();
RNLocation.getLatestLocation
Get the latest location. Ensure you have the correct permission before calling this method.
This will subscribe to location events for you at the unsubscribe when it gets its first valid location. Usually, this method will return very fast with a possibly out of date location, however, in some circumstances it will not return a location. Therefore, this method has a timeout after which the promise will be resovled with null
value.
The location provider will respect the settings you have given it, so if you need a location with a certain accuracy, ensure you call RNLocation.configure
first. If you want any location then ensure you call RNLocation.configure
with no distance filter.
RNLocation.configure({ distanceFilter: null });
RNLocation.getLatestLocation({ timeout: 60000 })
.then(latestLocation => {
// Use the location here
})
RNLocation.subscribeToSignificantLocationUpdates
(iOS only)Subscribe to significant updates to the users location with the given listener. This method does not take into account the distanceFilter
which you configured RNLocation with. In most cases, you should call RNLocation.configure
with the correct settings and then use RNLocation.subscribeToLocationUpdates
to subscribe to the location updates. This will allow you to support both Android and iOS with the same code. For more details, take a look at Apple's documentation.
// Subscribe
const unsubscribe = RNLocation.subscribeToSignificantLocationUpdates(locations => {
...
})
// Unsubscribe
unsubscribe();
RNLocation.subscribeToHeadingUpdates
(iOS only)Subscribe to heading changes with the given listener. Ensure you have the correct permission before calling this method. The location provider will respect the settings you have given it.
// Subscribe
const unsubscribe = RNLocation.subscribeToHeadingUpdates(heading => {
...
})
// Unsubscribe
unsubscribe();
The library is released under the MIT licence. For more information see LICENSE
.