A library that provides access to reading geolocation information, polling current location or subscribing location update events from the device.
GitHub
npm
expo-location
allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.
-
npx expo install expo-location
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
You can configure expo-location
using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]
). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.
{
"expo": {
"plugins": [
[
"expo-location",
{
"locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location."
}
]
]
}
}
Name | Default | Description |
---|---|---|
locationAlwaysAndWhenInUsePermission | "Allow $(PRODUCT_NAME) to use your location" | Only for: iOS A string to set the |
locationAlwaysPermission | "Allow $(PRODUCT_NAME) to use your location" | Only for: iOS A string to set the |
locationWhenInUsePermission | "Allow $(PRODUCT_NAME) to use your location" | Only for: iOS A string to set the |
isIosBackgroundLocationEnabled | false | Only for: iOS A boolean to enable |
isAndroidBackgroundLocationEnabled | false | Only for: Android A boolean to enable the |
isAndroidForegroundServiceEnabled | - | Only for: Android A boolean to enable the |
Learn how to configure the native projects in the installation instructions in the expo-location
repository.
To be able to run background location on iOS, you need to add the location
value to the UIBackgroundModes
array in your app's Info.plist file.
If you're using CNG, the required UIBackgroundModes
configuration will be applied automatically by prebuild.
If you're not using Continuous Native Generation (CNG) or you're using a native iOS project, then you'll need to add the following to your Expo.plist file:
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
</key>
Warning: Background location tracking support is provided as-is and is not guaranteed to work in all scenarios. We currently are not prioritizing resources to improve it, but we hope to in the future. You may want to usereact-native-background-geolocation
instead — it requires purchasing a license and is a well-maintained and supported library that includes a config plugin.
To use Background Location methods, the following requirements apply:
Always
option.TaskManager.defineTask
."location"
background mode must be
specified in Info.plist file. See Background location
configuration.To use Geofencing methods, the following requirements apply:
Always
option.regions
that can be simultaneously monitored.If you're using the Android Emulator or iOS Simulator, ensure that Location is enabled.
import { useState, useEffect } from 'react';
import { Platform, Text, View, StyleSheet } from 'react-native';
%%placeholder-start%%%%placeholder-end%%import * as Device from 'expo-device';
import * as Location from 'expo-location';
export default function App() {
const [location, setLocation] = useState<Location.LocationObject | null>(null);
const [errorMsg, setErrorMsg] = useState<string | null>(null);
useEffect(() => {
async function getCurrentLocation() {
%%placeholder-start%%%%placeholder-end%%if (Platform.OS === 'android' && !Device.isDevice) {
setErrorMsg(
'Oops, this will not work on Snack in an Android Emulator. Try it on your device!'
);
return;
}
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
}
getCurrentLocation();
}, []);
let text = 'Waiting...';
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = JSON.stringify(location);
}
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{text}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
paragraph: {
fontSize: 18,
textAlign: 'center',
},
});
Open Android Studio, and launch the Android Emulator. Inside it, go to Settings > Location and enable Use location.
If you don't receive the locations in the emulator, you may have to turn off the Improve Location Accuracy setting. This will turn off Wi-Fi location and only use GPS. Then you can manipulate the location with GPS data through the emulator.
For Android 12 and higher, go to Settings > Location > Location Services > Google Location Accuracy, and turn off Improve Location Accuracy. For Android 11 and lower, go to Settings > Location > Advanced > Google Location Accuracy, and turn off Google Location Accuracy.
With Simulator open, go to Features > Location and choose any option besides None.
import * as Location from 'expo-location';
useBackgroundPermissions(options)
Parameter | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
useForegroundPermissions(options)
Parameter | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
[null | LocationPermissionResponse, RequestPermissionMethod<LocationPermissionResponse>, GetPermissionMethod<LocationPermissionResponse>]
Location.enableNetworkProviderAsync()
Asks the user to turn on high accuracy location mode which enables network provider that uses Google Play services to improve location accuracy and location-based services.
Promise<void>
A promise resolving as soon as the user accepts the dialog. Rejects if denied.
Location.geocodeAsync(address)
Parameter | Type | Description |
---|---|---|
address | string | A string representing address, eg. |
Geocode an address string to latitude-longitude location.
On Android, you must request location permissions with requestForegroundPermissionsAsync
before geocoding can be used.
Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately.
A promise which fulfills with an array (in most cases its size is 1) of LocationGeocodedLocation
objects.
Location.getBackgroundPermissionsAsync()
Checks user's permissions for accessing location while the app is in the background.
A promise that fulfills with an object of type PermissionResponse
.
Location.getCurrentPositionAsync(options)
Parameter | Type |
---|---|
options (optional) | LocationOptions |
Requests for one-time delivery of the user's current location.
Depending on given accuracy
option it may take some time to resolve,
especially when you're inside a building.
Note: Calling it causes the location manager to obtain a location fix which may take several seconds. Consider using
getLastKnownPositionAsync
if you expect to get a quick response and high accuracy is not required.
A promise which fulfills with an object of type LocationObject
.
Location.getForegroundPermissionsAsync()
Checks user's permissions for accessing location while the app is in the foreground.
A promise that fulfills with an object of type LocationPermissionResponse
.
Location.getHeadingAsync()
Gets the current heading information from the device. To simplify, it calls watchHeadingAsync
and waits for a couple of updates, and then returns the one that is accurate enough.
A promise which fulfills with an object of type LocationHeadingObject
.
Location.getLastKnownPositionAsync(options)
Parameter | Type |
---|---|
options (optional) | LocationLastKnownOptions |
Gets the last known position of the device or null
if it's not available or doesn't match given
requirements such as maximum age or required accuracy.
It's considered to be faster than getCurrentPositionAsync
as it doesn't request for the current
location, but keep in mind the returned location may not be up-to-date.
Promise<LocationObject | null>
A promise which fulfills with an object of type LocationObject
or
null
if it's not available or doesn't match given requirements such as maximum age or required
accuracy.
Location.getProviderStatusAsync()
Check status of location providers.
A promise which fulfills with an object of type LocationProviderStatus
.
Location.hasServicesEnabledAsync()
Checks whether location services are enabled by the user.
Promise<boolean>
A promise which fulfills to true
if location services are enabled on the device,
or false
if not.
Location.hasStartedGeofencingAsync(taskName)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the geofencing task to check. |
Promise<boolean>
A promise which fulfills with boolean value indicating whether the geofencing task is started or not.
Location.hasStartedLocationUpdatesAsync(taskName)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the location task to check. |
Promise<boolean>
A promise which fulfills with boolean value indicating whether the location task is started or not.
Location.installWebGeolocationPolyfill()
Polyfills navigator.geolocation
for interop with the core React Native and Web API approach to geolocation.
void
Location.requestBackgroundPermissionsAsync()
Asks the user to grant permissions for location while the app is in the background.
On Android 11 or higher: this method will open the system settings page - before that happens
you should explain to the user why your application needs background location permission.
For example, you can use Modal
component from react-native
to do that.
Note: Foreground permissions should be granted before asking for the background permissions (your app can't obtain background permission without foreground permission).
A promise that fulfills with an object of type PermissionResponse
.
Location.requestForegroundPermissionsAsync()
Asks the user to grant permissions for location while the app is in the foreground.
A promise that fulfills with an object of type LocationPermissionResponse
.
Location.reverseGeocodeAsync(location)
Parameter | Type | Description |
---|---|---|
location | Pick<LocationGeocodedLocation, 'latitude' | 'longitude'> | An object representing a location. |
Reverse geocode a location to postal address.
On Android, you must request location permissions with requestForegroundPermissionsAsync
before geocoding can be used.
Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately.
A promise which fulfills with an array (in most cases its size is 1) of LocationGeocodedAddress
objects.
Location.startGeofencingAsync(taskName, regions)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the task that will be called when the device enters or exits from specified regions. |
regions (optional) | LocationRegion[] | Array of region objects to be geofenced. Default: [] |
Starts geofencing for given regions. When the new event comes, the task with specified name will
be called with the region that the device enter to or exit from.
If you want to add or remove regions from already running geofencing task, you can just call
startGeofencingAsync
again with the new array of regions.
Geofencing task will be receiving following data:
eventType
- Indicates the reason for calling the task, which can be triggered by entering or exiting the region.
See GeofencingEventType
.region
- Object containing details about updated region. See LocationRegion
for more details.Promise<void>
A promise resolving as soon as the task is registered.
Example
import { GeofencingEventType } from 'expo-location';
import * as TaskManager from 'expo-task-manager';
TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { eventType, region }, error }) => {
if (error) {
// check `error.message` for more details.
return;
}
if (eventType === GeofencingEventType.Enter) {
console.log("You've entered region:", region);
} else if (eventType === GeofencingEventType.Exit) {
console.log("You've left region:", region);
}
});
Location.startLocationUpdatesAsync(taskName, options)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the task receiving location updates. |
options (optional) | LocationTaskOptions | An object of options passed to the location manager. |
Registers for receiving location updates that can also come when the app is in the background.
Background location task will be receiving following data:
locations
- An array of the new locations.Promise<void>
A promise resolving once the task with location updates is registered.
Example
import * as TaskManager from 'expo-task-manager';
TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { locations }, error }) => {
if (error) {
// check `error.message` for more details.
return;
}
console.log('Received new locations', locations);
});
Location.stopGeofencingAsync(taskName)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the task to unregister. |
Stops geofencing for specified task. It unregisters the background task so the app will not be receiving any updates, especially in the background.
Promise<void>
A promise resolving as soon as the task is unregistered.
Location.stopLocationUpdatesAsync(taskName)
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the background location task to stop. |
Stops location updates for specified task.
Promise<void>
A promise resolving as soon as the task is unregistered.
Location.watchHeadingAsync(callback)
Parameter | Type | Description |
---|---|---|
callback | LocationHeadingCallback | This function is called on each compass update. It receives an object of type LocationHeadingObject as the first argument. |
Subscribe to compass updates from the device.
A promise which fulfills with a LocationSubscription
object.
Location.watchPositionAsync(options, callback)
Parameter | Type | Description |
---|---|---|
options | LocationOptions | - |
callback | LocationCallback | This function is called on each location update. It receives an object of type
|
Subscribe to location updates from the device. Please note that updates will only occur while the
application is in the foreground. To get location updates while in background you'll need to use
startLocationUpdatesAsync
.
A promise which fulfills with a LocationSubscription
object.
PermissionResponse
An object obtained by permissions get and request functions.
PermissionResponse Properties
Name | Type | Description |
---|---|---|
canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
expires | PermissionExpiration | Determines time when the permission expires. |
granted | boolean | A convenience boolean that indicates if the permission is granted. |
status | PermissionStatus | Determines the status of the permission. |
LocationCallback()
Represents watchPositionAsync
callback.
Parameter | Type |
---|---|
location | LocationObject |
any
LocationGeocodedAddress
Type representing a result of reverseGeocodeAsync
.
Name | Type | Description |
---|---|---|
city | string | null | City name of the address. |
country | string | null | Localized country name of the address. |
district | string | null | Additional city-level information like district name. |
formattedAddress | string | null | Only for: Android Composed string of the address components, for example, "111 8th Avenue, New York, NY". |
isoCountryCode | string | null | Localized (ISO) country code of the address, if available. |
name | string | null | The name of the placemark, for example, "Tower Bridge". |
postalCode | string | null | Postal code of the address. |
region | string | null | The state or province associated with the address. |
street | string | null | Street name of the address. |
streetNumber | string | null | Street number of the address. |
subregion | string | null | Additional information about administrative area. |
timezone | string | null | Only for: iOS The timezone identifier associated with the address. |
LocationGeocodedLocation
Type representing a result of geocodeAsync
.
Name | Type | Description |
---|---|---|
accuracy (optional) | number | The radius of uncertainty for the location, measured in meters. |
altitude (optional) | number | The altitude in meters above the WGS 84 reference ellipsoid. |
latitude | number | The latitude in degrees. |
longitude | number | The longitude in degrees. |
LocationHeadingCallback()
Represents watchHeadingAsync
callback.
Parameter | Type |
---|---|
location | LocationHeadingObject |
any
LocationHeadingObject
Type of the object containing heading details and provided by watchHeadingAsync
callback.
Name | Type | Description |
---|---|---|
accuracy | number | Level of calibration of compass:
Reference for iOS:
|
magHeading | number | Measure of magnetic north in degrees. |
trueHeading | number | Measure of true north in degrees (needs location permissions, will return |
LocationLastKnownOptions
Type representing options object that can be passed to getLastKnownPositionAsync
.
Name | Type | Description |
---|---|---|
maxAge (optional) | number | A number of milliseconds after which the last known location starts to be invalid and thus
|
requiredAccuracy (optional) | number | The maximum radius of uncertainty for the location, measured in meters. If the last known
location's accuracy radius is bigger (less accurate) then |
LocationObject
Type representing the location object.
Name | Type | Description |
---|---|---|
coords | LocationObjectCoords | The coordinates of the position. |
mocked (optional) | boolean | Only for: Android Whether the location coordinates is mocked or not. |
timestamp | number | The time at which this position information was obtained, in milliseconds since epoch. |
LocationObjectCoords
Type representing the location GPS related data.
Name | Type | Description |
---|---|---|
accuracy | number | null | The radius of uncertainty for the location, measured in meters. Can be |
altitude | number | null | The altitude in meters above the WGS 84 reference ellipsoid. Can be |
altitudeAccuracy | number | null | The accuracy of the altitude value, in meters. Can be |
heading | number | null | Horizontal direction of travel of this device, measured in degrees starting at due north and
continuing clockwise around the compass. Thus, north is 0 degrees, east is 90 degrees, south is
180 degrees, and so on. Can be |
latitude | number | The latitude in degrees. |
longitude | number | The longitude in degrees. |
speed | number | null | The instantaneous speed of the device in meters per second. Can be |
LocationOptions
Type representing options argument in getCurrentPositionAsync
.
Name | Type | Description |
---|---|---|
accuracy (optional) | Accuracy | Location manager accuracy. Pass one of Default: LocationAccuracy.Balanced |
distanceInterval (optional) | number | Receive updates only when the location has changed by at least this distance in meters.
Default value may depend on |
mayShowUserSettingsDialog (optional) | boolean | Only for: Android Specifies whether to ask the user to turn on improved accuracy location mode which uses Wi-Fi, cell networks and GPS sensor. Default: true |
timeInterval (optional) | number | Only for: Android Minimum time to wait between each update in milliseconds.
Default value may depend on |
LocationPermissionResponse
LocationPermissionResponse
extends PermissionResponse
type exported by expo-modules-core
and contains additional platform-specific fields.
Type: PermissionResponse
extended by:
Name | Type | Description |
---|---|---|
android (optional) | PermissionDetailsLocationAndroid | - |
ios (optional) | PermissionDetailsLocationIOS | - |
LocationProviderStatus
Represents the object containing details about location provider.
Name | Type | Description |
---|---|---|
backgroundModeEnabled | boolean | - |
gpsAvailable (optional) | boolean | Only for: Android Whether the GPS provider is available. If |
locationServicesEnabled | boolean | Whether location services are enabled. See Location.hasServicesEnabledAsync for a more convenient solution to get this value. |
networkAvailable (optional) | boolean | Only for: Android Whether the network provider is available. If |
passiveAvailable (optional) | boolean | Only for: Android Whether the passive provider is available. If |
LocationRegion
Type representing geofencing region object.
Name | Type | Description |
---|---|---|
identifier (optional) | string | The identifier of the region object. Defaults to auto-generated UUID hash. |
latitude | number | The latitude in degrees of region's center point. |
longitude | number | The longitude in degrees of region's center point. |
notifyOnEnter (optional) | boolean | Boolean value whether to call the task if the device enters the region. Default: true |
notifyOnExit (optional) | boolean | Boolean value whether to call the task if the device exits the region. Default: true |
radius | number | The radius measured in meters that defines the region's outer boundary. |
state (optional) | GeofencingRegionState | One of GeofencingRegionState region state. Determines whether the device is inside or outside a region. |
LocationSubscription
Represents subscription object returned by methods watching for new locations or headings.
Name | Type | Description |
---|---|---|
remove | () => void | Call this function with no arguments to remove this subscription. The callback will no longer be called for location updates. |
LocationTaskOptions
Type representing background location task options.
Type: LocationOptions
extended by:
Name | Type | Description |
---|---|---|
activityType (optional) | ActivityType | Only for: iOS The type of user activity associated with the location updates. Default: ActivityType.Other
|
deferredUpdatesDistance (optional) | number | The distance in meters that must occur between last reported location and the current location before deferred locations are reported. Default: 0 |
deferredUpdatesInterval (optional) | number | Minimum time interval in milliseconds that must pass since last reported location before all later locations are reported in a batched update Default: 0 |
deferredUpdatesTimeout (optional) | number | - |
foregroundService (optional) | LocationTaskServiceOptions | - |
pausesUpdatesAutomatically (optional) | boolean | Only for: iOS A boolean value indicating whether the location manager can pause location
updates to improve battery life without sacrificing location data. When this option is set to
Default: false |
showsBackgroundLocationIndicator (optional) | boolean | Only for: iOS A boolean indicating whether the status bar changes its appearance when location services are used in the background. Default: false |
LocationTaskServiceOptions
Name | Type | Description |
---|---|---|
killServiceOnDestroy (optional) | boolean | Boolean value whether to destroy the foreground service if the app is killed. |
notificationBody | string | Subtitle of the foreground service notification. |
notificationColor (optional) | string | Color of the foreground service notification. Accepts |
notificationTitle | string | Title of the foreground service notification. |
PermissionDetailsLocationAndroid
Name | Type | Description |
---|---|---|
accuracy | 'fine' | 'coarse' | 'none' | Indicates the type of location provider. |
PermissionDetailsLocationIOS
Name | Type | Description |
---|---|---|
scope | 'whenInUse' | 'always' | 'none' | The scope of granted permission. Indicates when it's possible to use location. |
PermissionExpiration
Literal Type: multiple types
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never'
| number
PermissionHookOptions
Literal Type: multiple types
Acceptable values are: PermissionHookBehavior
| Options
BestForNavigation
Accuracy.BestForNavigation = 6
The highest possible accuracy that uses additional sensor data to facilitate navigation apps.
ActivityType
Enum with available activity types of background location tracking.
ActivityType Values
Other
ActivityType.Other = 1
Default activity type. Use it if there is no other type that matches the activity you track.
AutomotiveNavigation
ActivityType.AutomotiveNavigation = 2
Location updates are being used specifically during vehicular navigation to track location changes to the automobile.
Fitness
ActivityType.Fitness = 3
Use this activity type if you track fitness activities such as walking, running, cycling, and so on.
OtherNavigation
ActivityType.OtherNavigation = 4
Activity type for movements for other types of vehicular navigation that are not automobile related.
Airborne
ActivityType.Airborne = 5
Intended for airborne activities. Fall backs to ActivityType.Other
if
unsupported.
GeofencingEventType
A type of the event that geofencing task can receive.
GeofencingEventType Values
GeofencingRegionState
State of the geofencing region that you receive through the geofencing task.
GeofencingRegionState Values
Unknown
GeofencingRegionState.Unknown = 0
Indicates that the device position related to the region is unknown.
UNDETERMINED
PermissionStatus.UNDETERMINED = "undetermined"
User hasn't granted or denied the permission yet.
: Foreground and background services are not available in Expo Go for Android. Instead, we recommend using a development build to avoid limitations.
When you install the expo-location
module, it automatically adds the following permissions:
ACCESS_COARSE_LOCATION
: for approximate device locationACCESS_FINE_LOCATION
: for precise device locationThe following permissions are optional:
FOREGROUND_SERVICE
and FOREGROUND_SERVICE_LOCATION
: to be able to access location while the app is open but backgrounded. FOREGROUND_SERVICE_LOCATION
is only required as of Android 14. When you enable this in a new build, you will need to submit your app for review and request access to use the foreground service permission.ACCESS_BACKGROUND_LOCATION
: to be able to access location while the app is backgrounded or closed. When you enable this in a new build, you will need to submit your app for review and request access to use the background location permission.Android Permission | Description |
---|---|
Allows an app to access approximate location.
| |
Allows an app to access precise location.
| |
Allows a regular application to use Service.startForeground.
| |
Allows a regular application to use Service.startForeground with the type "location".
| |
Allows an app to access location in the background.
|
Note: Excluding a required permission from a module in your app can break the functionality corresponding to that permission. Always make sure to include all permissions a module is dependent on.
When your Expo project doesn't benefit from having particular permission included, you can omit it. For example, if your application doesn't need access to the precise location, you can exclude the ACCESS_FINE_LOCATION
permission.
Another example can be stated using available location accuracies. Android defines the approximate location accuracy estimation within about 3 square kilometers, and the precise location accuracy estimation within about 50 meters. For example, if the location accuracy value is Low, you can exclude ACCESS_FINE_LOCATION
permission. To learn more about levels of location accuracies, see Android documentation.
To learn more on how to exclude permission, see Excluding Android permissions.
The following usage description keys are used by this library:
Info.plist Key | Description |
---|---|
A message that tells the user why the app is requesting access to the user’s location information at all times. | |
A message that tells the user why the app is requesting access to the user's location at all times.DeprecatedFor apps deployed to targets in iOS 11 and later, use NSLocationAlwaysAndWhenInUseUsageDescription instead. | |
A message that tells the user why the app is requesting access to the user’s location information while the app is running in the foreground. |