UNPKG

react-native-cross-geolocation

Version:

React Native Geolocation complatible module that uses the new Google Location API on Android devices.

151 lines (137 loc) 3.98 kB
import { NativeEventEmitter, NativeModules, PermissionsAndroid, Platform, } from 'react-native' import invariant from 'invariant' //const logError = require('logError'); //const warning = require('fbjs/lib/warning'); const RNGeolocation = NativeModules.LocationObserver const LocationEventEmitter = new NativeEventEmitter(RNGeolocation) const logError = () => {} var nextWatchID = 1 var subscriptions = {} var updatesEnabled = false /** * The Geolocation API extends the web spec: * https://developer.mozilla.org/en-US/docs/Web/API/Geolocation * * See https://facebook.github.io/react-native/docs/geolocation.html */ module.exports = { LowAccuracyMode: { BALANCED: RNGeolocation.BALANCED, LOW_POWER: RNGeolocation.LOW_POWER, NO_POWER: RNGeolocation.NO_POWER, }, /* * Sets configuration options that will be used in all location requests. * * See https://facebook.github.io/react-native/docs/geolocation.html#setrnconfiguration * */ setRNConfiguration: RNGeolocation.setConfiguration, /* * Request suitable Location permission based on the key configured on pList. * * See https://facebook.github.io/react-native/docs/geolocation.html#requestauthorization */ requestAuthorization () {}, /* * Invokes the success callback once with the latest location info. * * See https://facebook.github.io/react-native/docs/geolocation.html#getcurrentposition */ getCurrentPosition(geo_success, geo_error, geo_options) { invariant( typeof geo_success === 'function', 'Must provide a valid geo_success callback.' ) let promise // Supports Android's new permission model. For Android older devices, // it's always on. if (Platform.Version >= 23) { promise = PermissionsAndroid.check( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION ).then((hasPermission) => { if (hasPermission) { return true } return PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION ) }) } else { promise = Promise.resolve() } promise.then(() => { // native module will call geo_error if has no parmissions RNGeolocation.getCurrentPosition( geo_options || {}, geo_success, geo_error || logError ) }) }, /* * Invokes the success callback whenever the location changes. * * See https://facebook.github.io/react-native/docs/geolocation.html#watchposition */ watchPosition (success, error, options) { if (!updatesEnabled) { RNGeolocation.startObserving(options || {}) updatesEnabled = true } const watchID = String(nextWatchID++) subscriptions[watchID] = [ LocationEventEmitter.addListener( 'geolocationDidChange', success ), error ? LocationEventEmitter.addListener( 'geolocationError', error ) : null, ] return watchID }, clearWatch (watchID) { var sub = subscriptions[watchID] if (!sub) { // Silently exit when the watchID is invalid or already cleared // This is consistent with timers return } sub[0].remove() // array element refinements not yet enabled in Flow if (sub[1]) { sub[1].remove() } delete subscriptions[watchID] for (var p in subscriptions) { if (subscriptions.hasOwnProperty(p)) { return // still valid subscriptions } } RNGeolocation.stopObserving() }, stopObserving () { if (updatesEnabled) { RNGeolocation.stopObserving() updatesEnabled = false Object.keys(subscriptions).forEach((id) => { const sub = subscriptions[id] if (sub) { //warning(false, 'Called stopObserving with existing subscriptions.'); sub[0].remove() if (sub[1]) { sub[1].remove() } } }) subscriptions = {} } } }