2015-02-28 20:46:42 -08:00
|
|
|
/**
|
2015-03-23 13:35:08 -07:00
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
*
|
2018-02-16 18:24:55 -08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2015-02-28 20:46:42 -08:00
|
|
|
*
|
2018-05-10 19:06:46 -07:00
|
|
|
* @format
|
2015-03-25 11:12:57 -07:00
|
|
|
* @flow
|
2015-02-28 20:46:42 -08:00
|
|
|
*/
|
2018-05-10 19:06:46 -07:00
|
|
|
|
2015-02-28 20:46:42 -08:00
|
|
|
'use strict';
|
|
|
|
|
2016-05-25 04:17:35 -07:00
|
|
|
const NativeEventEmitter = require('NativeEventEmitter');
|
|
|
|
const RCTLocationObserver = require('NativeModules').LocationObserver;
|
2015-02-28 20:46:42 -08:00
|
|
|
|
2016-05-25 04:17:35 -07:00
|
|
|
const invariant = require('fbjs/lib/invariant');
|
|
|
|
const logError = require('logError');
|
2017-09-06 03:25:01 -07:00
|
|
|
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
|
|
|
|
* found when Flow v0.54 was deployed. To see the error delete this comment and
|
|
|
|
* run Flow. */
|
2016-05-25 04:17:35 -07:00
|
|
|
const warning = require('fbjs/lib/warning');
|
2015-02-28 20:46:42 -08:00
|
|
|
|
2016-05-25 04:17:35 -07:00
|
|
|
const LocationEventEmitter = new NativeEventEmitter(RCTLocationObserver);
|
2016-05-24 12:33:57 -07:00
|
|
|
|
2017-06-05 18:58:37 -07:00
|
|
|
const Platform = require('Platform');
|
|
|
|
const PermissionsAndroid = require('PermissionsAndroid');
|
|
|
|
|
2018-05-10 15:44:52 -07:00
|
|
|
let subscriptions = [];
|
|
|
|
let updatesEnabled = false;
|
2015-02-28 20:46:42 -08:00
|
|
|
|
2017-08-29 04:00:41 -07:00
|
|
|
type GeoConfiguration = {
|
2018-05-10 19:06:46 -07:00
|
|
|
skipPermissionRequests: boolean,
|
|
|
|
};
|
2017-08-29 04:00:41 -07:00
|
|
|
|
2015-04-24 16:10:46 -07:00
|
|
|
type GeoOptions = {
|
2017-07-24 11:15:27 -07:00
|
|
|
timeout?: number,
|
|
|
|
maximumAge?: number,
|
2018-05-10 19:06:46 -07:00
|
|
|
enableHighAccuracy?: boolean,
|
2016-08-09 06:32:41 -07:00
|
|
|
distanceFilter: number,
|
2018-05-10 19:06:46 -07:00
|
|
|
useSignificantChanges?: boolean,
|
|
|
|
};
|
2015-04-24 16:10:46 -07:00
|
|
|
|
2015-02-28 20:46:42 -08:00
|
|
|
/**
|
2016-09-20 05:46:59 -07:00
|
|
|
* The Geolocation API extends the web spec:
|
2015-11-18 09:03:51 -08:00
|
|
|
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
|
|
|
|
*
|
2018-01-29 16:10:49 -08:00
|
|
|
* See https://facebook.github.io/react-native/docs/geolocation.html
|
2015-02-28 20:46:42 -08:00
|
|
|
*/
|
2018-05-10 15:44:52 -07:00
|
|
|
const Geolocation = {
|
2017-08-29 04:00:41 -07:00
|
|
|
/*
|
|
|
|
* Sets configuration options that will be used in all location requests.
|
|
|
|
*
|
2018-01-29 16:10:49 -08:00
|
|
|
* See https://facebook.github.io/react-native/docs/geolocation.html#setrnconfiguration
|
2017-08-29 04:00:41 -07:00
|
|
|
*
|
|
|
|
*/
|
2018-05-10 19:06:46 -07:00
|
|
|
setRNConfiguration: function(config: GeoConfiguration) {
|
2017-08-29 04:00:41 -07:00
|
|
|
if (RCTLocationObserver.setConfiguration) {
|
|
|
|
RCTLocationObserver.setConfiguration(config);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-05-25 07:01:17 -07:00
|
|
|
/*
|
|
|
|
* Request suitable Location permission based on the key configured on pList.
|
2018-02-22 07:04:35 -08:00
|
|
|
*
|
2018-01-29 16:10:49 -08:00
|
|
|
* See https://facebook.github.io/react-native/docs/geolocation.html#requestauthorization
|
2017-05-25 07:01:17 -07:00
|
|
|
*/
|
|
|
|
requestAuthorization: function() {
|
|
|
|
RCTLocationObserver.requestAuthorization();
|
|
|
|
},
|
|
|
|
|
2015-04-24 16:10:46 -07:00
|
|
|
/*
|
2018-02-22 07:04:35 -08:00
|
|
|
* Invokes the success callback once with the latest location info.
|
|
|
|
*
|
2018-01-29 16:10:49 -08:00
|
|
|
* See https://facebook.github.io/react-native/docs/geolocation.html#getcurrentposition
|
2015-04-24 16:10:46 -07:00
|
|
|
*/
|
2017-06-05 18:58:37 -07:00
|
|
|
getCurrentPosition: async function(
|
2015-03-25 11:12:57 -07:00
|
|
|
geo_success: Function,
|
|
|
|
geo_error?: Function,
|
2018-05-10 19:06:46 -07:00
|
|
|
geo_options?: GeoOptions,
|
2015-03-26 10:06:50 -07:00
|
|
|
) {
|
2015-02-28 20:46:42 -08:00
|
|
|
invariant(
|
|
|
|
typeof geo_success === 'function',
|
2018-05-10 19:06:46 -07:00
|
|
|
'Must provide a valid geo_success callback.',
|
2015-02-28 20:46:42 -08:00
|
|
|
);
|
2017-06-05 18:58:37 -07:00
|
|
|
let hasPermission = true;
|
|
|
|
// Supports Android's new permission model. For Android older devices,
|
|
|
|
// it's always on.
|
|
|
|
if (Platform.OS === 'android' && Platform.Version >= 23) {
|
|
|
|
hasPermission = await PermissionsAndroid.check(
|
|
|
|
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
|
|
);
|
|
|
|
if (!hasPermission) {
|
|
|
|
const status = await PermissionsAndroid.request(
|
|
|
|
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
|
|
);
|
|
|
|
hasPermission = status === PermissionsAndroid.RESULTS.GRANTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hasPermission) {
|
|
|
|
RCTLocationObserver.getCurrentPosition(
|
|
|
|
geo_options || {},
|
|
|
|
geo_success,
|
|
|
|
geo_error || logError,
|
|
|
|
);
|
|
|
|
}
|
2015-03-09 03:04:44 -07:00
|
|
|
},
|
|
|
|
|
2015-04-24 16:10:46 -07:00
|
|
|
/*
|
2018-01-29 16:10:49 -08:00
|
|
|
* Invokes the success callback whenever the location changes.
|
2018-02-22 07:04:35 -08:00
|
|
|
*
|
2018-01-29 16:10:49 -08:00
|
|
|
* See https://facebook.github.io/react-native/docs/geolocation.html#watchposition
|
2015-04-24 16:10:46 -07:00
|
|
|
*/
|
2018-05-10 19:06:46 -07:00
|
|
|
watchPosition: function(
|
|
|
|
success: Function,
|
|
|
|
error?: Function,
|
|
|
|
options?: GeoOptions,
|
|
|
|
): number {
|
2015-03-09 03:04:44 -07:00
|
|
|
if (!updatesEnabled) {
|
|
|
|
RCTLocationObserver.startObserving(options || {});
|
|
|
|
updatesEnabled = true;
|
|
|
|
}
|
2018-05-10 15:44:52 -07:00
|
|
|
const watchID = subscriptions.length;
|
2015-03-09 03:04:44 -07:00
|
|
|
subscriptions.push([
|
2018-05-10 19:06:46 -07:00
|
|
|
LocationEventEmitter.addListener('geolocationDidChange', success),
|
|
|
|
error
|
|
|
|
? LocationEventEmitter.addListener('geolocationError', error)
|
|
|
|
: null,
|
2015-03-09 03:04:44 -07:00
|
|
|
]);
|
2015-02-28 20:46:42 -08:00
|
|
|
return watchID;
|
2015-03-09 03:04:44 -07:00
|
|
|
},
|
|
|
|
|
2015-03-25 11:12:57 -07:00
|
|
|
clearWatch: function(watchID: number) {
|
2018-05-10 15:44:52 -07:00
|
|
|
const sub = subscriptions[watchID];
|
2015-02-28 20:46:42 -08:00
|
|
|
if (!sub) {
|
|
|
|
// Silently exit when the watchID is invalid or already cleared
|
|
|
|
// This is consistent with timers
|
|
|
|
return;
|
|
|
|
}
|
2015-03-25 11:12:57 -07:00
|
|
|
|
2015-03-09 03:04:44 -07:00
|
|
|
sub[0].remove();
|
2015-03-25 11:12:57 -07:00
|
|
|
// array element refinements not yet enabled in Flow
|
2018-05-10 19:06:46 -07:00
|
|
|
const sub1 = sub[1];
|
|
|
|
sub1 && sub1.remove();
|
2015-02-28 20:46:42 -08:00
|
|
|
subscriptions[watchID] = undefined;
|
2018-05-10 15:44:52 -07:00
|
|
|
let noWatchers = true;
|
|
|
|
for (let ii = 0; ii < subscriptions.length; ii++) {
|
2015-02-28 20:46:42 -08:00
|
|
|
if (subscriptions[ii]) {
|
|
|
|
noWatchers = false; // still valid subscriptions
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (noWatchers) {
|
2015-03-09 03:04:44 -07:00
|
|
|
Geolocation.stopObserving();
|
2015-02-28 20:46:42 -08:00
|
|
|
}
|
2015-03-09 03:04:44 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
stopObserving: function() {
|
2015-02-28 20:46:42 -08:00
|
|
|
if (updatesEnabled) {
|
|
|
|
RCTLocationObserver.stopObserving();
|
|
|
|
updatesEnabled = false;
|
2018-05-10 15:44:52 -07:00
|
|
|
for (let ii = 0; ii < subscriptions.length; ii++) {
|
|
|
|
const sub = subscriptions[ii];
|
2015-03-25 11:12:57 -07:00
|
|
|
if (sub) {
|
2017-06-22 08:34:16 -07:00
|
|
|
warning(false, 'Called stopObserving with existing subscriptions.');
|
2015-03-25 11:12:57 -07:00
|
|
|
sub[0].remove();
|
|
|
|
// array element refinements not yet enabled in Flow
|
2018-05-10 19:06:46 -07:00
|
|
|
const sub1 = sub[1];
|
|
|
|
sub1 && sub1.remove();
|
2015-02-28 20:46:42 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
subscriptions = [];
|
|
|
|
}
|
2018-05-10 19:06:46 -07:00
|
|
|
},
|
2015-05-19 13:43:46 -07:00
|
|
|
};
|
2015-02-28 20:46:42 -08:00
|
|
|
|
2015-03-09 03:04:44 -07:00
|
|
|
module.exports = Geolocation;
|