Skip to content

Commit

Permalink
Release 3.10 (#271)
Browse files Browse the repository at this point in the history
* use latest play services version 21.0.1 (#249)

Thanks, I'll test this out and include in the next version

* work in Headless JS (#254)

Co-authored-by: lavrik acer <valery.lavrik@gmail.com>

* Default `maximumAge` to 0 on iOS. (#268)

* Example updates (#270)

* chore: headless js + example updates

* chore: revert ts changes

* chore: fix background location timer types

* chore: move types package

---------

Co-authored-by: Brian Rojas <marchinram@gmail.com>
Co-authored-by: valery-lavrik <valery-lavrik@users.noreply.github.com>
Co-authored-by: lavrik acer <valery.lavrik@gmail.com>
Co-authored-by: Justin Kaufman <57186+jkaufman@users.noreply.github.com>
  • Loading branch information
5 people committed Aug 29, 2023
1 parent 7de1d36 commit f3da392
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 53 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ Geolocation.setRNConfiguration(
config: {
skipPermissionRequests: boolean;
authorizationLevel?: 'always' | 'whenInUse' | 'auto';
enableBackgroundLocationUpdates?: boolean;
locationProvider?: 'playServices' | 'android' | 'auto';
}
) => void
Expand All @@ -173,6 +174,7 @@ Supported options:

* `skipPermissionRequests` (boolean) - Defaults to `false`. If `true`, you must request permissions before using Geolocation APIs.
* `authorizationLevel` (string, iOS-only) - Either `"whenInUse"`, `"always"`, or `"auto"`. Changes whether the user will be asked to give "always" or "when in use" location services permission. Any other value or `auto` will use the default behaviour, where the permission level is based on the contents of your `Info.plist`.
* `enableBackgroundLocationUpdates` (boolean, iOS-only) - When using `skipPermissionRequests`, toggle wether to automatically enableBackgroundLocationUpdates. Defaults to true.
* `locationProvider` (string, Android-only) - Either `"playServices"`, `"android"`, or `"auto"`. Determines wether to use `Google’s Location Services API` or `Android’s Location API`. The `"auto"` mode defaults to `android`, and falls back to Android's Location API if play services aren't available.

---
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ repositories {
dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+'
implementation 'com.google.android.gms:play-services-location:20.0.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public void getCurrentLocationData(ReadableMap options, Callback success, Callba
Activity currentActivity = mReactContext.getCurrentActivity();

if (currentActivity == null) {
error.invoke(PositionError.buildError(PositionError.ACTIVITY_NULL, "mReactContext.getCurrentActivity() returned null but should be non-null in getCurrentLocationData"));
return;
mSingleLocationCallback = createSingleLocationCallback(success, error);
checkLocationSettings(options, mSingleLocationCallback);
return;
}

try {
Expand All @@ -59,29 +60,7 @@ public void getCurrentLocationData(ReadableMap options, Callback success, Callba
if (location != null && (SystemClock.currentTimeMillis() - location.getTime()) < locationOptions.maximumAge) {
success.invoke(locationToMap(location));
} else {
mSingleLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
emitError(PositionError.POSITION_UNAVAILABLE, "No location provided (FusedLocationProvider/lastLocation).");
return;
}

AndroidLocationManager.LocationOptions locationOptions = AndroidLocationManager.LocationOptions.fromReactMap(options);
Location location = locationResult.getLastLocation();
success.invoke(locationToMap(location));

mFusedLocationClient.removeLocationUpdates(mSingleLocationCallback);
mSingleLocationCallback = null;
}

@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
if (!locationAvailability.isLocationAvailable()) {
emitError(PositionError.POSITION_UNAVAILABLE, "Location not available (FusedLocationProvider/lastLocation).");
}
}
};
mSingleLocationCallback = createSingleLocationCallback(success, error);
checkLocationSettings(options, mSingleLocationCallback);
}
});
Expand Down Expand Up @@ -151,4 +130,29 @@ private void requestLocationUpdates(LocationRequest locationRequest, LocationCal
throw e;
}
}

private LocationCallback createSingleLocationCallback(Callback success, Callback error){
return new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
error.invoke(PositionError.buildError(PositionError.POSITION_UNAVAILABLE, "No location provided (FusedLocationProvider/lastLocation)."));
return;
}

Location location = locationResult.getLastLocation();
success.invoke(locationToMap(location));

mFusedLocationClient.removeLocationUpdates(mSingleLocationCallback);
mSingleLocationCallback = null;
}

@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
if (!locationAvailability.isLocationAvailable()) {
error.invoke(PositionError.buildError(PositionError.POSITION_UNAVAILABLE, "Location not available (FusedLocationProvider/lastLocation)."));
}
}
};
}
}
6 changes: 4 additions & 2 deletions example/ios/GeolocationExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
</dict>
</dict>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
Expand All @@ -51,5 +49,9 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Testing purposes</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Testing purposes</string>
</dict>
</plist>
6 changes: 6 additions & 0 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ PODS:
- React-jsinspector (0.70.10)
- React-logger (0.70.10):
- glog
- react-native-background-timer (2.4.1):
- React-Core
- react-native-geolocation (3.0.6):
- RCT-Folly (= 2021.07.22.00)
- RCTRequired
Expand Down Expand Up @@ -711,6 +713,7 @@ DEPENDENCIES:
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- react-native-geolocation (from `../..`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
Expand Down Expand Up @@ -782,6 +785,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
React-logger:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-background-timer:
:path: "../node_modules/react-native-background-timer"
react-native-geolocation:
:path: "../.."
react-native-safe-area-context:
Expand Down Expand Up @@ -845,6 +850,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 1457c7bb2f08f257e6b5ece8b62348da43c4ccf2
React-jsinspector: 2a1985769123b199c195a96f46478b35db139712
React-logger: 7fbdc3576b2ed3834360c8ea3c1c2ec54ac3043a
react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe
react-native-geolocation: a4df6c9ef98f624737b40c9e3d709eec1bff6ea7
react-native-safe-area-context: 0dfc8e3a7d5ff115d100bafe4269d64a2c0a1456
React-perflogger: f86e85eb59151d09e9b44b8931f5c088e4f08bbc
Expand Down
1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@react-navigation/native-stack": "^6.7.0",
"react": "18.1.0",
"react-native": "0.70.10",
"react-native-background-timer": "^2.4.1",
"react-native-safe-area-context": "4.5.1",
"react-native-screens": "3.17.0"
},
Expand Down
68 changes: 68 additions & 0 deletions example/src/configs/BackgroundLocationUpdates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Copyright (c) React Native Community
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

'use strict';

import React, { useEffect, useRef, useState } from 'react';
import { View, Button, AppState } from 'react-native';
import BackgroundTimer from 'react-native-background-timer';
import Geolocation from '@react-native-community/geolocation';

export default function BackgroundLocationUpdates() {
const appState = useRef(AppState.currentState);
const [backgroundListener, setBackgroundListener] = useState(false);

useEffect(() => {
if (!backgroundListener) {
return;
}

const subscription = AppState.addEventListener('change', (nextAppState) => {
if (nextAppState.match(/inactive|background/)) {
BackgroundTimer.runBackgroundTimer(() => {
Geolocation.getCurrentPosition(
(position) => {
console.log(
'getCurrentPosition background',
JSON.stringify(position)
);
},
(error) =>
console.log(
'getCurrentPosition background error',
JSON.stringify(error)
),
{ enableHighAccuracy: true }
);
}, 1000);

console.log('App has come to the foreground!');
} else {
BackgroundTimer.stopBackgroundTimer();
}

appState.current = nextAppState;
});

return () => {
subscription.remove();
};
}, [backgroundListener]);

return (
<View>
<Button
title={`${
backgroundListener ? 'Disable' : 'Enable'
} background location updates`}
onPress={() => setBackgroundListener(!backgroundListener)}
/>
</View>
);
}
62 changes: 39 additions & 23 deletions example/src/configs/SetConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export default function SetConfigurationExample() {
const [locationProvider, setLocationProvider] = useState<
'playServices' | 'android' | 'auto'
>('auto');
const [enableBackgroundLocationUpdates, setEnableBackgroundLocationUpdates] =
useState(false);

useEffect(() => {
Geolocation.setRNConfiguration({
skipPermissionRequests,
Expand All @@ -60,34 +63,47 @@ export default function SetConfigurationExample() {
/>
</View>
{Platform.OS === 'ios' && (
<View style={styles.row}>
<Text>authorizationLevel</Text>
<View style={styles.segmentControlContainer}>
{authorizationLevelOptions.map((item, index) => (
<TouchableOpacity
key={`segmented-control-${index}`}
onPress={() =>
setAuthorizationLevel(authorizationLevelOptions[index])
}
style={[
styles.segmentedControlButton,
authorizationLevelOptions.indexOf(authorizationLevel) ===
index && styles.segmentedControlButtonActive,
]}
>
<Text
<>
<View style={styles.row}>
<Text>authorizationLevel</Text>
<View style={styles.segmentControlContainer}>
{authorizationLevelOptions.map((item, index) => (
<TouchableOpacity
key={`segmented-control-${index}`}
onPress={() =>
setAuthorizationLevel(authorizationLevelOptions[index])
}
style={[
styles.segmentControlText,
styles.segmentedControlButton,
authorizationLevelOptions.indexOf(authorizationLevel) ===
index && styles.segmentControlTextActive,
index && styles.segmentedControlButtonActive,
]}
>
{item}
</Text>
</TouchableOpacity>
))}
<Text
style={[
styles.segmentControlText,
authorizationLevelOptions.indexOf(authorizationLevel) ===
index && styles.segmentControlTextActive,
]}
>
{item}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</View>
<View style={styles.row}>
<Text>enableBackgroundLocationUpdates</Text>
<Switch
onValueChange={() =>
setEnableBackgroundLocationUpdates(
!enableBackgroundLocationUpdates
)
}
value={enableBackgroundLocationUpdates}
/>
</View>
</>
)}
{Platform.OS === 'android' && (
<View style={styles.row}>
Expand Down
9 changes: 9 additions & 0 deletions example/src/configs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import RequestAuthorization from './RequestAuthorization';
import SetConfiguration from './SetConfiguration';
import BackgroundLocationUpdates from './BackgroundLocationUpdates';

const configs = [
{
Expand All @@ -20,6 +21,14 @@ const configs = [
return <RequestAuthorization />;
},
},
{
id: 'backgroundLocationUpdates',
title: 'getCurrentLoaction() in background',
description: 'Test background location updates',
render() {
return <BackgroundLocationUpdates />;
},
},
];

export default configs;
1 change: 1 addition & 0 deletions example/src/examples/WatchPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function WatchPositionExample() {
try {
const watchID = Geolocation.watchPosition(
(position) => {
console.log('watchPosition', JSON.stringify(position));
setPosition(JSON.stringify(position));
},
(error) => Alert.alert('WatchPosition Error', JSON.stringify(error))
Expand Down
5 changes: 5 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4238,6 +4238,11 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==

react-native-background-timer@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/react-native-background-timer/-/react-native-background-timer-2.4.1.tgz#a3bc1cafa8c1e3aeefd0611de120298b67978a0f"
integrity sha512-TE4Kiy7jUyv+hugxDxitzu38sW1NqjCk4uE5IgU2WevLv7sZacaBc6PZKOShNRPGirLl1NWkaG3LDEkdb9Um5g==

react-native-codegen@^0.70.6:
version "0.70.6"
resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.70.6.tgz#2ce17d1faad02ad4562345f8ee7cbe6397eda5cb"
Expand Down
5 changes: 3 additions & 2 deletions ios/RNCGeolocation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef NS_ENUM(NSInteger, RNCGeolocationAuthorizationLevel) {
typedef struct {
BOOL skipPermissionRequests;
RNCGeolocationAuthorizationLevel authorizationLevel;
BOOL enableBackgroundLocationUpdates;
} RNCGeolocationConfiguration;

typedef struct {
Expand Down Expand Up @@ -76,7 +77,7 @@ + (RNCGeolocationOptions)RNCGeolocationOptions:(id)json

return (RNCGeolocationOptions){
.timeout = [RCTConvert NSTimeInterval:options[@"timeout"]] ?: 1000 * 60 * 10,
.maximumAge = [RCTConvert NSTimeInterval:options[@"maximumAge"]] ?: INFINITY,
.maximumAge = [RCTConvert NSTimeInterval:options[@"maximumAge"]],
.accuracy = [RCTConvert BOOL:options[@"enableHighAccuracy"]] ? kCLLocationAccuracyBest : RNC_DEFAULT_LOCATION_ACCURACY,
.distanceFilter = distanceFilter,
.useSignificantChanges = static_cast<BOOL>([RCTConvert BOOL:options[@"useSignificantChanges"]] ?: NO),
Expand Down Expand Up @@ -174,7 +175,7 @@ - (void)beginLocationUpdatesWithDesiredAccuracy:(CLLocationAccuracy)desiredAccur
{
if (!_locationConfiguration.skipPermissionRequests) {
[self requestAuthorization:nil error:nil];
} else {
} else if (_locationConfiguration.enableBackgroundLocationUpdates) {
[self enableBackgroundLocationUpdates];
}

Expand Down
2 changes: 2 additions & 0 deletions js/NativeRNCGeolocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type GeolocationConfiguration = {
skipPermissionRequests: boolean;
authorizationLevel?: 'always' | 'whenInUse' | 'auto';
locationProvider?: 'playServices' | 'android' | 'auto';
enableBackgroundLocationUpdates?: boolean;
};

export type GeolocationOptions = {
Expand Down Expand Up @@ -42,6 +43,7 @@ export interface Spec extends TurboModule {
setConfiguration(config: {
skipPermissionRequests: boolean;
authorizationLevel?: string;
enableBackgroundLocationUpdates?: string;
}): void;
requestAuthorization(
success: () => void,
Expand Down

0 comments on commit f3da392

Please sign in to comment.