react-native-nitro-geolocation 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +4 -4
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +642 -50
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocationCompat.kt +81 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +4 -4
- package/ios/LocationManager.swift +4 -4
- package/ios/NitroGeolocation.swift +543 -68
- package/ios/NitroGeolocationCompat.swift +109 -0
- package/nitrogen/generated/android/c++/JAuthorizationLevel.hpp +61 -0
- package/nitrogen/generated/android/c++/JAuthorizationLevelInternal.hpp +3 -4
- package/nitrogen/generated/android/c++/JFunc_void.hpp +2 -1
- package/nitrogen/generated/android/c++/JFunc_void_GeolocationError.hpp +2 -1
- package/nitrogen/generated/android/c++/JFunc_void_GeolocationResponse.hpp +6 -1
- package/nitrogen/generated/android/c++/JFunc_void_LocationError.hpp +78 -0
- package/nitrogen/generated/android/c++/JGeolocationCoordinates.hpp +25 -17
- package/nitrogen/generated/android/c++/JGeolocationError.hpp +5 -1
- package/nitrogen/generated/android/c++/JGeolocationOptions.hpp +5 -1
- package/nitrogen/generated/android/c++/JGeolocationResponse.hpp +9 -1
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.cpp +109 -0
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.hpp +70 -0
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.cpp +98 -42
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.hpp +7 -5
- package/nitrogen/generated/android/c++/JLocationError.hpp +61 -0
- package/nitrogen/generated/android/c++/JLocationProvider.hpp +61 -0
- package/nitrogen/generated/android/c++/JLocationProviderInternal.hpp +3 -4
- package/nitrogen/generated/android/c++/JLocationRequestOptions.hpp +81 -0
- package/nitrogen/generated/android/c++/JModernGeolocationConfiguration.hpp +73 -0
- package/nitrogen/generated/android/c++/JNullableDouble.cpp +26 -0
- package/nitrogen/generated/android/c++/JNullableDouble.hpp +69 -0
- package/nitrogen/generated/android/c++/JPermissionStatus.hpp +64 -0
- package/nitrogen/generated/android/c++/JRNConfigurationInternal.hpp +5 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevel.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevelInternal.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationError.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationResponse.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_LocationError.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationCoordinates.kt +34 -25
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationError.kt +27 -18
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationOptions.kt +33 -24
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationResponse.kt +18 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationCompatSpec.kt +92 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationSpec.kt +17 -17
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProvider.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderInternal.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationRequestOptions.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ModernGeolocationConfiguration.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/NullableDouble.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/PermissionStatus.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/RNConfigurationInternal.kt +24 -15
- package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
- package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +14 -2
- package/nitrogen/generated/ios/NitroGeolocation+autolinking.rb +1 -1
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +55 -13
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +325 -68
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +26 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.hpp +130 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationSpecSwift.hpp +47 -26
- package/nitrogen/generated/ios/swift/AuthorizationLevel.swift +44 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_GeolocationError.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_GeolocationResponse.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_LocationError.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/GeolocationCoordinates.swift +132 -93
- package/nitrogen/generated/ios/swift/GeolocationError.swift +11 -40
- package/nitrogen/generated/ios/swift/GeolocationOptions.swift +29 -98
- package/nitrogen/generated/ios/swift/GeolocationResponse.swift +5 -16
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec.swift +61 -0
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec_cxx.swift +244 -0
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec.swift +13 -5
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec_cxx.swift +66 -64
- package/nitrogen/generated/ios/swift/LocationError.swift +35 -0
- package/nitrogen/generated/ios/swift/LocationProvider.swift +44 -0
- package/nitrogen/generated/ios/swift/LocationRequestOptions.swift +116 -0
- package/nitrogen/generated/ios/swift/ModernGeolocationConfiguration.swift +83 -0
- package/nitrogen/generated/ios/swift/NullableDouble.swift +18 -0
- package/nitrogen/generated/ios/swift/PermissionStatus.swift +48 -0
- package/nitrogen/generated/ios/swift/RNConfigurationInternal.swift +16 -50
- package/nitrogen/generated/shared/c++/AuthorizationLevel.hpp +80 -0
- package/nitrogen/generated/shared/c++/GeolocationCoordinates.hpp +45 -27
- package/nitrogen/generated/shared/c++/GeolocationError.hpp +32 -16
- package/nitrogen/generated/shared/c++/GeolocationOptions.hpp +38 -22
- package/nitrogen/generated/shared/c++/GeolocationResponse.hpp +23 -7
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.hpp +79 -0
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.cpp +4 -3
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.hpp +22 -16
- package/nitrogen/generated/shared/c++/LocationError.hpp +87 -0
- package/nitrogen/generated/shared/c++/LocationProvider.hpp +80 -0
- package/nitrogen/generated/shared/c++/LocationRequestOptions.hpp +107 -0
- package/nitrogen/generated/shared/c++/ModernGeolocationConfiguration.hpp +100 -0
- package/nitrogen/generated/shared/c++/PermissionStatus.hpp +84 -0
- package/nitrogen/generated/shared/c++/RNConfigurationInternal.hpp +29 -13
- package/package.json +16 -7
- package/src/GeolocationClient.ts +116 -0
- package/src/NitroGeolocation.nitro.ts +177 -30
- package/src/NitroGeolocationCompat.nitro.ts +41 -0
- package/src/NitroGeolocationModule.ts +6 -0
- package/src/compat/clearWatch.ts +9 -0
- package/src/{getCurrentPosition.ts → compat/getCurrentPosition.ts} +7 -3
- package/src/compat/index.tsx +34 -0
- package/src/compat/requestAuthorization.ts +9 -0
- package/src/{setRNConfiguration.ts → compat/setRNConfiguration.ts} +6 -4
- package/src/{stopObserving.ts → compat/stopObserving.ts} +4 -2
- package/src/{watchPosition.ts → compat/watchPosition.ts} +7 -6
- package/src/components/GeolocationProvider.tsx +91 -0
- package/src/components/index.ts +13 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useCheckPermission.ts +46 -0
- package/src/hooks/useGetCurrentPosition.ts +44 -0
- package/src/hooks/useRequestPermission.ts +38 -0
- package/src/hooks/useWatchPosition.ts +127 -0
- package/src/index.tsx +72 -27
- package/src/types.ts +32 -4
- package/src/utils/cache.ts +25 -0
- package/src/utils/config.ts +93 -0
- package/src/utils/errors.ts +82 -0
- package/src/utils/index.ts +27 -0
- package/src/utils/provider.ts +61 -0
- package/src/utils/quality.ts +98 -0
- package/src/clearWatch.ts +0 -13
- package/src/requestAuthorization.ts +0 -9
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a location request with its configuration options.
|
|
3
|
+
*/
|
|
4
|
+
export interface LocationRequest {
|
|
5
|
+
/** Whether high accuracy mode is enabled */
|
|
6
|
+
enableHighAccuracy: boolean;
|
|
7
|
+
/** Minimum distance change (in meters) for updates */
|
|
8
|
+
distanceFilter: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Accuracy level for location services.
|
|
13
|
+
* - 'high': GPS-level accuracy (~5-10 meters)
|
|
14
|
+
* - 'medium': Network-assisted accuracy (~100 meters)
|
|
15
|
+
* - 'low': Cell tower accuracy (~1000+ meters)
|
|
16
|
+
*/
|
|
17
|
+
export type AccuracyLevel = "high" | "medium" | "low";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Merged configuration representing the optimal settings
|
|
21
|
+
* for multiple concurrent location requests.
|
|
22
|
+
*/
|
|
23
|
+
export interface MergedConfiguration {
|
|
24
|
+
/** The best (highest) accuracy level among all requests */
|
|
25
|
+
bestAccuracy: AccuracyLevel;
|
|
26
|
+
/** The smallest (most sensitive) distance filter among all requests */
|
|
27
|
+
smallestDistanceFilter: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Merges multiple location request configurations to determine
|
|
32
|
+
* the optimal settings that satisfy all requests.
|
|
33
|
+
*
|
|
34
|
+
* This is important for battery optimization - when multiple watches
|
|
35
|
+
* or getCurrentPosition calls are active simultaneously, we should use
|
|
36
|
+
* the most demanding settings to satisfy all requests with a single
|
|
37
|
+
* location subscription.
|
|
38
|
+
*
|
|
39
|
+
* Strategy:
|
|
40
|
+
* - Use the highest accuracy level requested by any client
|
|
41
|
+
* - Use the smallest distance filter to ensure all clients get updates
|
|
42
|
+
*
|
|
43
|
+
* @param requests - Array of location requests to merge
|
|
44
|
+
* @returns Merged configuration with optimal settings
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const requests = [
|
|
49
|
+
* { enableHighAccuracy: false, distanceFilter: 100 },
|
|
50
|
+
* { enableHighAccuracy: true, distanceFilter: 10 },
|
|
51
|
+
* { enableHighAccuracy: false, distanceFilter: 50 }
|
|
52
|
+
* ];
|
|
53
|
+
*
|
|
54
|
+
* const merged = mergeConfigurations(requests);
|
|
55
|
+
* // Result: { bestAccuracy: 'high', smallestDistanceFilter: 10 }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function mergeConfigurations(
|
|
59
|
+
requests: LocationRequest[]
|
|
60
|
+
): MergedConfiguration {
|
|
61
|
+
// If no requests, return default low-power settings
|
|
62
|
+
if (requests.length === 0) {
|
|
63
|
+
return {
|
|
64
|
+
bestAccuracy: "low",
|
|
65
|
+
smallestDistanceFilter: 0
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let bestAccuracy: AccuracyLevel = "low";
|
|
70
|
+
let smallestDistanceFilter = Number.POSITIVE_INFINITY;
|
|
71
|
+
|
|
72
|
+
// Iterate through all requests to find the most demanding settings
|
|
73
|
+
for (const request of requests) {
|
|
74
|
+
// If any request needs high accuracy, use high accuracy
|
|
75
|
+
if (request.enableHighAccuracy) {
|
|
76
|
+
bestAccuracy = "high";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Use the smallest distance filter
|
|
80
|
+
smallestDistanceFilter = Math.min(
|
|
81
|
+
smallestDistanceFilter,
|
|
82
|
+
request.distanceFilter
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
bestAccuracy,
|
|
88
|
+
smallestDistanceFilter:
|
|
89
|
+
smallestDistanceFilter === Number.POSITIVE_INFINITY
|
|
90
|
+
? 0
|
|
91
|
+
: smallestDistanceFilter
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes for geolocation errors.
|
|
3
|
+
* These codes match the W3C Geolocation API specification.
|
|
4
|
+
*/
|
|
5
|
+
export enum LocationErrorCode {
|
|
6
|
+
/** User denied the request for Geolocation */
|
|
7
|
+
PERMISSION_DENIED = 1,
|
|
8
|
+
/** Location provider is unavailable */
|
|
9
|
+
POSITION_UNAVAILABLE = 2,
|
|
10
|
+
/** The request to get location timed out */
|
|
11
|
+
TIMEOUT = 3
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Geolocation error object.
|
|
16
|
+
*/
|
|
17
|
+
export interface LocationError extends Error {
|
|
18
|
+
code: LocationErrorCode;
|
|
19
|
+
message: string;
|
|
20
|
+
PERMISSION_DENIED: LocationErrorCode.PERMISSION_DENIED;
|
|
21
|
+
POSITION_UNAVAILABLE: LocationErrorCode.POSITION_UNAVAILABLE;
|
|
22
|
+
TIMEOUT: LocationErrorCode.TIMEOUT;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a standardized LocationError object.
|
|
27
|
+
*
|
|
28
|
+
* @param code - The error code from LocationErrorCode enum
|
|
29
|
+
* @param message - A human-readable error message
|
|
30
|
+
* @returns A LocationError object
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const error = createLocationError(
|
|
35
|
+
* LocationErrorCode.PERMISSION_DENIED,
|
|
36
|
+
* 'User denied location permission'
|
|
37
|
+
* );
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function createLocationError(
|
|
41
|
+
code: LocationErrorCode,
|
|
42
|
+
message: string
|
|
43
|
+
): LocationError {
|
|
44
|
+
const error = new Error(message) as LocationError;
|
|
45
|
+
error.code = code;
|
|
46
|
+
error.PERMISSION_DENIED = LocationErrorCode.PERMISSION_DENIED;
|
|
47
|
+
error.POSITION_UNAVAILABLE = LocationErrorCode.POSITION_UNAVAILABLE;
|
|
48
|
+
error.TIMEOUT = LocationErrorCode.TIMEOUT;
|
|
49
|
+
return error;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Maps iOS CLError codes to LocationErrorCode.
|
|
54
|
+
*
|
|
55
|
+
* @param clErrorCode - The iOS CLError code
|
|
56
|
+
* @returns The corresponding LocationErrorCode
|
|
57
|
+
*
|
|
58
|
+
* @see https://developer.apple.com/documentation/corelocation/clerror/code
|
|
59
|
+
*/
|
|
60
|
+
export function mapCLErrorCode(clErrorCode: number): LocationErrorCode {
|
|
61
|
+
switch (clErrorCode) {
|
|
62
|
+
case 0: // kCLErrorDenied
|
|
63
|
+
return LocationErrorCode.PERMISSION_DENIED;
|
|
64
|
+
case 1: // kCLErrorLocationUnknown
|
|
65
|
+
return LocationErrorCode.POSITION_UNAVAILABLE;
|
|
66
|
+
default:
|
|
67
|
+
return LocationErrorCode.POSITION_UNAVAILABLE;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Maps Android exception types to LocationErrorCode.
|
|
73
|
+
*
|
|
74
|
+
* @param exceptionType - The Android exception class name
|
|
75
|
+
* @returns The corresponding LocationErrorCode
|
|
76
|
+
*/
|
|
77
|
+
export function mapAndroidException(exceptionType: string): LocationErrorCode {
|
|
78
|
+
if (exceptionType === "SecurityException") {
|
|
79
|
+
return LocationErrorCode.PERMISSION_DENIED;
|
|
80
|
+
}
|
|
81
|
+
return LocationErrorCode.POSITION_UNAVAILABLE;
|
|
82
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure utility functions for geolocation operations.
|
|
3
|
+
* These functions are platform-independent and can be tested with Jest.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { isCachedLocationValid } from "./cache";
|
|
7
|
+
export {
|
|
8
|
+
LocationErrorCode,
|
|
9
|
+
createLocationError,
|
|
10
|
+
mapCLErrorCode,
|
|
11
|
+
mapAndroidException,
|
|
12
|
+
type LocationError
|
|
13
|
+
} from "./errors";
|
|
14
|
+
export {
|
|
15
|
+
isBetterLocation,
|
|
16
|
+
type LocationQuality
|
|
17
|
+
} from "./quality";
|
|
18
|
+
export {
|
|
19
|
+
selectProvider,
|
|
20
|
+
type Provider
|
|
21
|
+
} from "./provider";
|
|
22
|
+
export {
|
|
23
|
+
mergeConfigurations,
|
|
24
|
+
type LocationRequest,
|
|
25
|
+
type AccuracyLevel,
|
|
26
|
+
type MergedConfiguration
|
|
27
|
+
} from "./config";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location provider types supported on Android.
|
|
3
|
+
*/
|
|
4
|
+
export type Provider = "gps" | "network" | null;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Selects the best available location provider based on user preferences
|
|
8
|
+
* and provider availability.
|
|
9
|
+
*
|
|
10
|
+
* This function implements a fallback strategy:
|
|
11
|
+
* - If high accuracy is requested, prefer GPS, fallback to Network
|
|
12
|
+
* - If low power is preferred, prefer Network, fallback to GPS
|
|
13
|
+
*
|
|
14
|
+
* @param enableHighAccuracy - Whether high accuracy mode is requested
|
|
15
|
+
* @param gpsAvailable - Whether GPS provider is available and enabled
|
|
16
|
+
* @param networkAvailable - Whether Network provider is available and enabled
|
|
17
|
+
* @returns The selected provider, or null if no providers are available
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // High accuracy mode with both providers available
|
|
22
|
+
* selectProvider(true, true, true); // 'gps'
|
|
23
|
+
*
|
|
24
|
+
* // High accuracy mode but GPS is disabled
|
|
25
|
+
* selectProvider(true, false, true); // 'network'
|
|
26
|
+
*
|
|
27
|
+
* // Low power mode with both providers available
|
|
28
|
+
* selectProvider(false, true, true); // 'network'
|
|
29
|
+
*
|
|
30
|
+
* // No providers available
|
|
31
|
+
* selectProvider(true, false, false); // null
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function selectProvider(
|
|
35
|
+
enableHighAccuracy: boolean,
|
|
36
|
+
gpsAvailable: boolean,
|
|
37
|
+
networkAvailable: boolean
|
|
38
|
+
): Provider {
|
|
39
|
+
// Determine preferred and fallback providers based on accuracy requirement
|
|
40
|
+
const preferredProvider = enableHighAccuracy ? "gps" : "network";
|
|
41
|
+
const fallbackProvider = enableHighAccuracy ? "network" : "gps";
|
|
42
|
+
|
|
43
|
+
// Check if preferred provider is available
|
|
44
|
+
const isPreferredAvailable =
|
|
45
|
+
preferredProvider === "gps" ? gpsAvailable : networkAvailable;
|
|
46
|
+
|
|
47
|
+
// Check if fallback provider is available
|
|
48
|
+
const isFallbackAvailable =
|
|
49
|
+
fallbackProvider === "gps" ? gpsAvailable : networkAvailable;
|
|
50
|
+
|
|
51
|
+
// Return the best available provider
|
|
52
|
+
if (isPreferredAvailable) {
|
|
53
|
+
return preferredProvider;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (isFallbackAvailable) {
|
|
57
|
+
return fallbackProvider;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the quality characteristics of a location reading.
|
|
3
|
+
*/
|
|
4
|
+
export interface LocationQuality {
|
|
5
|
+
/** Timestamp in milliseconds since epoch */
|
|
6
|
+
timestampMs: number;
|
|
7
|
+
/** Horizontal accuracy in meters */
|
|
8
|
+
accuracyMeters: number;
|
|
9
|
+
/** Location provider type */
|
|
10
|
+
provider: "gps" | "network";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Time threshold for considering locations significantly newer/older (2 minutes) */
|
|
14
|
+
const TWO_MINUTES_MS = 2 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
/** Accuracy threshold for considering locations significantly less accurate (200 meters) */
|
|
17
|
+
const SIGNIFICANT_ACCURACY_DIFFERENCE_METERS = 200;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Determines whether a new location is better than the current best location.
|
|
21
|
+
* This algorithm considers both recency and accuracy of location readings.
|
|
22
|
+
*
|
|
23
|
+
* Based on Android's location quality evaluation best practices:
|
|
24
|
+
* @see https://developer.android.com/develop/sensors-and-location/location/strategies#BestEstimate
|
|
25
|
+
*
|
|
26
|
+
* @param newLocation - The new location to evaluate
|
|
27
|
+
* @param currentBest - The current best location, or null if none exists
|
|
28
|
+
* @returns true if the new location is better, false otherwise
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const newLoc: LocationQuality = {
|
|
33
|
+
* timestampMs: Date.now(),
|
|
34
|
+
* accuracyMeters: 10,
|
|
35
|
+
* provider: 'gps'
|
|
36
|
+
* };
|
|
37
|
+
*
|
|
38
|
+
* const currentBest: LocationQuality = {
|
|
39
|
+
* timestampMs: Date.now() - 60000, // 1 minute ago
|
|
40
|
+
* accuracyMeters: 50,
|
|
41
|
+
* provider: 'network'
|
|
42
|
+
* };
|
|
43
|
+
*
|
|
44
|
+
* isBetterLocation(newLoc, currentBest); // true (newer and more accurate)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function isBetterLocation(
|
|
48
|
+
newLocation: LocationQuality,
|
|
49
|
+
currentBest: LocationQuality | null
|
|
50
|
+
): boolean {
|
|
51
|
+
// If there's no current best location, the new location is always better
|
|
52
|
+
if (!currentBest) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Calculate time difference between locations
|
|
57
|
+
const timeDelta = newLocation.timestampMs - currentBest.timestampMs;
|
|
58
|
+
const isSignificantlyNewer = timeDelta > TWO_MINUTES_MS;
|
|
59
|
+
const isSignificantlyOlder = timeDelta < -TWO_MINUTES_MS;
|
|
60
|
+
|
|
61
|
+
// If the new location is significantly newer, it's better
|
|
62
|
+
if (isSignificantlyNewer) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// If the new location is significantly older, it's not better
|
|
67
|
+
if (isSignificantlyOlder) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Calculate accuracy difference
|
|
72
|
+
const accuracyDelta = newLocation.accuracyMeters - currentBest.accuracyMeters;
|
|
73
|
+
const isMoreAccurate = accuracyDelta < 0;
|
|
74
|
+
const isLessAccurate = accuracyDelta > 0;
|
|
75
|
+
const isSignificantlyLessAccurate =
|
|
76
|
+
accuracyDelta > SIGNIFICANT_ACCURACY_DIFFERENCE_METERS;
|
|
77
|
+
|
|
78
|
+
// Determine if location is newer
|
|
79
|
+
const isNewer = timeDelta > 0;
|
|
80
|
+
|
|
81
|
+
// Check if from same provider
|
|
82
|
+
const isFromSameProvider = newLocation.provider === currentBest.provider;
|
|
83
|
+
|
|
84
|
+
// Evaluate location quality based on accuracy and recency
|
|
85
|
+
if (isMoreAccurate) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (isNewer && !isLessAccurate) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return false;
|
|
98
|
+
}
|
package/src/clearWatch.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { NitroModules } from "react-native-nitro-modules";
|
|
2
|
-
import type { NitroGeolocation } from "./NitroGeolocation.nitro";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Clears a specific watch session identified by watchId.
|
|
6
|
-
*
|
|
7
|
-
* @param watchId - The ID returned by watchPosition()
|
|
8
|
-
*/
|
|
9
|
-
export function clearWatch(watchId: number): void {
|
|
10
|
-
const nitroGeolocation =
|
|
11
|
-
NitroModules.createHybridObject<NitroGeolocation>("NitroGeolocation");
|
|
12
|
-
nitroGeolocation.clearWatch(watchId);
|
|
13
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { NitroGeolocationHybridObject } from "./NitroGeolocationModule";
|
|
2
|
-
import type { GeolocationError } from "./types";
|
|
3
|
-
|
|
4
|
-
export function requestAuthorization(
|
|
5
|
-
success?: () => void,
|
|
6
|
-
error?: (error: GeolocationError) => void
|
|
7
|
-
): void {
|
|
8
|
-
NitroGeolocationHybridObject.requestAuthorization(success, error);
|
|
9
|
-
}
|