expo-location 18.0.8 → 18.0.9-canary-20250320-7a205d3
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/CHANGELOG.md +13 -12
- package/android/build.gradle +7 -11
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/expo/modules/location/LocationHelpers.kt +12 -41
- package/android/src/main/java/expo/modules/location/LocationModule.kt +63 -28
- package/android/src/main/java/expo/modules/location/LocationParams.kt +14 -0
- package/build/LocationEventEmitter.web.d.ts +1 -1
- package/build/LocationEventEmitter.web.d.ts.map +1 -1
- package/expo-module.config.json +3 -16
- package/ios/LocationModule.swift +5 -1
- package/ios/TaskConsumers/EXLocationTaskConsumer.m +16 -15
- package/package.json +4 -5
- package/android/libs/io.nlopez.smartlocation-3.3.3-jetified.aar +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,42 +8,43 @@
|
|
|
8
8
|
|
|
9
9
|
### 🐛 Bug fixes
|
|
10
10
|
|
|
11
|
+
- [iOS] Remove restarting all services when CLLocationManager reports an error ([#35478](https://github.com/expo/expo/pull/35478) by [@chrfalch](https://github.com/chrfalch))
|
|
12
|
+
- [Android] Add missing ProGuard rule to fix task consumer failed ([#34098](https://github.com/expo/expo/pull/34098) by [@cornejobarraza](https://github.com/cornejobarraza))
|
|
13
|
+
- [iOS] `startLocationUpdatesAsync` should not require background permissions ([#33617](https://github.com/expo/expo/pull/33617) by [@andrejpavlovic](https://github.com/andrejpavlovic)
|
|
14
|
+
|
|
11
15
|
### 💡 Others
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
- On Android, remove dependency on `smart-location-lib`. ([#33609](https://github.com/expo/expo/pull/33609) by [@alanjhughes](https://github.com/alanjhughes))
|
|
18
|
+
- [Android] Started using expo modules gradle plugin. ([#34176](https://github.com/expo/expo/pull/34176) by [@lukmccall](https://github.com/lukmccall))
|
|
19
|
+
|
|
20
|
+
## 18.0.8 - 2025-03-14
|
|
14
21
|
|
|
15
22
|
### 💡 Others
|
|
16
23
|
|
|
17
24
|
- On iOS, added setting the scope value as per our documentation. ([#35452](https://github.com/expo/expo/pull/35452) by [@chrfalch](https://github.com/chrfalch))
|
|
18
25
|
|
|
19
|
-
## 18.0.7 — 2025-02-19
|
|
20
|
-
|
|
21
|
-
- On Android, remove dependency on `smart-location-lib`. ([#33609](https://github.com/expo/expo/pull/33609) by [@alanjhughes](https://github.com/alanjhughes))
|
|
22
|
-
- [Android] Started using expo modules gradle plugin. ([#34176](https://github.com/expo/expo/pull/34176) by [@lukmccall](https://github.com/lukmccall))
|
|
23
|
-
|
|
24
26
|
## 18.0.7 - 2025-02-19
|
|
25
27
|
|
|
26
|
-
- ([iOS][location] Add scope to foreground and background iOS permissions as pr. documentation (#35452))
|
|
27
|
-
|
|
28
28
|
### 🐛 Bug fixes
|
|
29
29
|
|
|
30
|
+
- [iOS] Added guards to avoid task options to crash the app. ([#35477](https://github.com/expo/expo/pull/35477) by [@chrfalch](https://github.com/chrfalch))
|
|
30
31
|
- [iOS] Added error handler to the streaming location/heading methods since these can fail while streaming ([#35004](https://github.com/expo/expo/pull/35004) by [@chrfalch](https://github.com/chrfalch))
|
|
31
32
|
|
|
32
|
-
## 18.0.6
|
|
33
|
+
## 18.0.6 - 2025-02-10
|
|
33
34
|
|
|
34
35
|
### 🐛 Bug fixes
|
|
35
36
|
|
|
36
37
|
- [Android] Use less specific exception in catch block of `resolveUserSettingsForRequest`. ([#34784](https://github.com/expo/expo/pull/34784) by [@alanjhughes](https://github.com/alanjhughes))
|
|
37
38
|
|
|
38
|
-
## 18.0.5
|
|
39
|
+
## 18.0.5 - 2025-01-10
|
|
39
40
|
|
|
40
41
|
_This version does not introduce any user-facing changes._
|
|
41
42
|
|
|
42
|
-
## 18.0.4
|
|
43
|
+
## 18.0.4 - 2024-12-10
|
|
43
44
|
|
|
44
45
|
_This version does not introduce any user-facing changes._
|
|
45
46
|
|
|
46
|
-
## 18.0.3
|
|
47
|
+
## 18.0.3 - 2024-11-29
|
|
47
48
|
|
|
48
49
|
_This version does not introduce any user-facing changes._
|
|
49
50
|
|
package/android/build.gradle
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
plugins {
|
|
2
|
+
id 'com.android.library'
|
|
3
|
+
id 'expo-module-gradle-plugin'
|
|
4
|
+
}
|
|
2
5
|
|
|
3
6
|
group = 'host.exp.exponent'
|
|
4
|
-
version = '18.0.
|
|
5
|
-
|
|
6
|
-
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
|
-
apply from: expoModulesCorePlugin
|
|
8
|
-
applyKotlinExpoModulesCorePlugin()
|
|
9
|
-
useCoreDependencies()
|
|
10
|
-
useDefaultAndroidSdkVersions()
|
|
11
|
-
useExpoPublishing()
|
|
7
|
+
version = '18.0.2'
|
|
12
8
|
|
|
13
9
|
android {
|
|
14
10
|
namespace "expo.modules.location"
|
|
15
11
|
defaultConfig {
|
|
16
12
|
versionCode 29
|
|
17
|
-
versionName "18.0.
|
|
13
|
+
versionName "18.0.2"
|
|
14
|
+
consumerProguardFiles("proguard-rules.pro")
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
dependencies {
|
|
22
19
|
api 'com.google.android.gms:play-services-location:21.0.1'
|
|
23
|
-
implementation project(":${project.name}\$io.nlopez.smartlocation-jetified-aar")
|
|
24
20
|
}
|
|
@@ -16,8 +16,6 @@ import expo.modules.location.records.LocationLastKnownOptions
|
|
|
16
16
|
import expo.modules.location.records.LocationOptions
|
|
17
17
|
import expo.modules.location.records.LocationResponse
|
|
18
18
|
import expo.modules.location.records.PermissionRequestResponse
|
|
19
|
-
import io.nlopez.smartlocation.location.config.LocationAccuracy
|
|
20
|
-
import io.nlopez.smartlocation.location.config.LocationParams
|
|
21
19
|
import kotlin.coroutines.resume
|
|
22
20
|
import kotlin.coroutines.resumeWithException
|
|
23
21
|
import kotlin.coroutines.suspendCoroutine
|
|
@@ -110,16 +108,16 @@ class LocationHelpers {
|
|
|
110
108
|
|
|
111
109
|
private fun mapOptionsToLocationParams(options: LocationOptions): LocationParams {
|
|
112
110
|
val accuracy = options.accuracy
|
|
113
|
-
val
|
|
111
|
+
val locationParams = buildLocationParamsForAccuracy(accuracy)
|
|
114
112
|
|
|
115
113
|
options.timeInterval?.let {
|
|
116
|
-
|
|
114
|
+
locationParams.interval = it
|
|
117
115
|
}
|
|
118
116
|
options.distanceInterval?.let {
|
|
119
|
-
|
|
117
|
+
locationParams.distance = it.toFloat()
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
return
|
|
120
|
+
return locationParams
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
private fun mapAccuracyToPriority(accuracy: Int): Int {
|
|
@@ -131,42 +129,15 @@ class LocationHelpers {
|
|
|
131
129
|
}
|
|
132
130
|
}
|
|
133
131
|
|
|
134
|
-
private fun buildLocationParamsForAccuracy(accuracy: Int): LocationParams
|
|
132
|
+
private fun buildLocationParamsForAccuracy(accuracy: Int): LocationParams {
|
|
135
133
|
return when (accuracy) {
|
|
136
|
-
LocationModule.ACCURACY_LOWEST -> LocationParams.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
LocationModule.
|
|
142
|
-
|
|
143
|
-
.setDistance(1000f)
|
|
144
|
-
.setInterval(5000)
|
|
145
|
-
|
|
146
|
-
LocationModule.ACCURACY_BALANCED -> LocationParams.Builder()
|
|
147
|
-
.setAccuracy(LocationAccuracy.MEDIUM)
|
|
148
|
-
.setDistance(100f)
|
|
149
|
-
.setInterval(3000)
|
|
150
|
-
|
|
151
|
-
LocationModule.ACCURACY_HIGH -> LocationParams.Builder()
|
|
152
|
-
.setAccuracy(LocationAccuracy.HIGH)
|
|
153
|
-
.setDistance(50f)
|
|
154
|
-
.setInterval(2000)
|
|
155
|
-
|
|
156
|
-
LocationModule.ACCURACY_HIGHEST -> LocationParams.Builder()
|
|
157
|
-
.setAccuracy(LocationAccuracy.HIGH)
|
|
158
|
-
.setDistance(25f)
|
|
159
|
-
.setInterval(1000)
|
|
160
|
-
|
|
161
|
-
LocationModule.ACCURACY_BEST_FOR_NAVIGATION -> LocationParams.Builder()
|
|
162
|
-
.setAccuracy(LocationAccuracy.HIGH)
|
|
163
|
-
.setDistance(0f)
|
|
164
|
-
.setInterval(500)
|
|
165
|
-
|
|
166
|
-
else -> LocationParams.Builder()
|
|
167
|
-
.setAccuracy(LocationAccuracy.MEDIUM)
|
|
168
|
-
.setDistance(100f)
|
|
169
|
-
.setInterval(3000)
|
|
134
|
+
LocationModule.ACCURACY_LOWEST -> LocationParams(accuracy = LocationAccuracy.LOWEST, distance = 3000f, interval = 10000)
|
|
135
|
+
LocationModule.ACCURACY_LOW -> LocationParams(accuracy = LocationAccuracy.LOW, distance = 1000f, interval = 5000)
|
|
136
|
+
LocationModule.ACCURACY_BALANCED -> LocationParams(accuracy = LocationAccuracy.MEDIUM, distance = 100f, interval = 3000)
|
|
137
|
+
LocationModule.ACCURACY_HIGH -> LocationParams(accuracy = LocationAccuracy.HIGH, distance = 50f, interval = 2000)
|
|
138
|
+
LocationModule.ACCURACY_HIGHEST -> LocationParams(accuracy = LocationAccuracy.HIGH, distance = 25f, interval = 1000)
|
|
139
|
+
LocationModule.ACCURACY_BEST_FOR_NAVIGATION -> LocationParams(accuracy = LocationAccuracy.HIGH, distance = 0f, interval = 500)
|
|
140
|
+
else -> LocationParams(accuracy = LocationAccuracy.MEDIUM, distance = 100f, interval = 3000)
|
|
170
141
|
}
|
|
171
142
|
}
|
|
172
143
|
|
|
@@ -12,11 +12,14 @@ import android.hardware.SensorEventListener
|
|
|
12
12
|
import android.hardware.SensorManager
|
|
13
13
|
import android.location.Geocoder
|
|
14
14
|
import android.location.Location
|
|
15
|
+
import android.location.LocationManager
|
|
15
16
|
import android.os.Build
|
|
16
17
|
import android.os.Bundle
|
|
17
18
|
import android.os.Looper
|
|
18
19
|
import android.util.Log
|
|
19
20
|
import androidx.annotation.ChecksSdkIntAtLeast
|
|
21
|
+
import androidx.core.app.ActivityCompat
|
|
22
|
+
import androidx.core.location.LocationManagerCompat
|
|
20
23
|
import androidx.core.os.bundleOf
|
|
21
24
|
import com.google.android.gms.common.api.ApiException
|
|
22
25
|
import com.google.android.gms.common.api.CommonStatusCodes
|
|
@@ -52,9 +55,6 @@ import expo.modules.location.records.ReverseGeocodeLocation
|
|
|
52
55
|
import expo.modules.location.records.ReverseGeocodeResponse
|
|
53
56
|
import expo.modules.location.taskConsumers.GeofencingTaskConsumer
|
|
54
57
|
import expo.modules.location.taskConsumers.LocationTaskConsumer
|
|
55
|
-
import io.nlopez.smartlocation.SmartLocation
|
|
56
|
-
import io.nlopez.smartlocation.geocoding.utils.LocationAddress
|
|
57
|
-
import io.nlopez.smartlocation.location.config.LocationParams
|
|
58
58
|
import java.util.Locale
|
|
59
59
|
import kotlin.coroutines.resume
|
|
60
60
|
import kotlin.coroutines.resumeWithException
|
|
@@ -158,21 +158,12 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
AsyncFunction<LocationProviderStatus>("getProviderStatusAsync") {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return@AsyncFunction LocationProviderStatus().apply {
|
|
164
|
-
backgroundModeEnabled = state.locationServicesEnabled()
|
|
165
|
-
gpsAvailable = state.isGpsAvailable
|
|
166
|
-
networkAvailable = state.isNetworkAvailable
|
|
167
|
-
locationServicesEnabled = state.locationServicesEnabled()
|
|
168
|
-
passiveAvailable = state.isPassiveAvailable
|
|
169
|
-
}
|
|
161
|
+
return@AsyncFunction getProviderStatus()
|
|
170
162
|
}
|
|
171
163
|
|
|
172
164
|
AsyncFunction("watchDeviceHeading") { watchId: Int ->
|
|
173
165
|
mHeadingId = watchId
|
|
174
|
-
startHeadingUpdate()
|
|
175
|
-
return@AsyncFunction
|
|
166
|
+
return@AsyncFunction startHeadingUpdate()
|
|
176
167
|
}
|
|
177
168
|
|
|
178
169
|
AsyncFunction("watchPositionImplAsync") { watchId: Int, options: LocationOptions, promise: Promise ->
|
|
@@ -215,7 +206,6 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
215
206
|
} else {
|
|
216
207
|
removeLocationUpdatesForRequest(watchId)
|
|
217
208
|
}
|
|
218
|
-
return@AsyncFunction
|
|
219
209
|
}
|
|
220
210
|
|
|
221
211
|
AsyncFunction("geocodeAsync") Coroutine { address: String ->
|
|
@@ -342,6 +332,23 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
342
332
|
} ?: throw NoPermissionsModuleException()
|
|
343
333
|
}
|
|
344
334
|
|
|
335
|
+
private fun getProviderStatus(): LocationProviderStatus {
|
|
336
|
+
val manager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
337
|
+
|
|
338
|
+
val isGpsAvailable = manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|
|
339
|
+
val isNetworkAvailable = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
|
|
340
|
+
val isLocationServicesEnabled = LocationManagerCompat.isLocationEnabled(manager)
|
|
341
|
+
val isPassiveAvailable = manager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)
|
|
342
|
+
|
|
343
|
+
return LocationProviderStatus().apply {
|
|
344
|
+
backgroundModeEnabled = isLocationServicesEnabled
|
|
345
|
+
gpsAvailable = isGpsAvailable
|
|
346
|
+
networkAvailable = isNetworkAvailable
|
|
347
|
+
locationServicesEnabled = isLocationServicesEnabled
|
|
348
|
+
passiveAvailable = isPassiveAvailable
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
345
352
|
private suspend fun requestBackgroundPermissionsAsync(): PermissionRequestResponse {
|
|
346
353
|
if (!isBackgroundPermissionInManifest()) {
|
|
347
354
|
throw NoPermissionInManifestException("ACCESS_BACKGROUND_LOCATION")
|
|
@@ -501,27 +508,54 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
501
508
|
}
|
|
502
509
|
|
|
503
510
|
private fun startHeadingUpdate() {
|
|
504
|
-
val
|
|
505
|
-
|
|
506
|
-
|
|
511
|
+
val locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
512
|
+
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
|
|
513
|
+
ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
|
|
514
|
+
) {
|
|
515
|
+
return
|
|
516
|
+
}
|
|
517
|
+
val lastLocation =
|
|
518
|
+
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
|
519
|
+
?: locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
|
|
520
|
+
|
|
521
|
+
if (lastLocation != null) {
|
|
507
522
|
mGeofield = GeomagneticField(
|
|
508
|
-
|
|
523
|
+
lastLocation.latitude.toFloat(),
|
|
524
|
+
lastLocation.longitude.toFloat(),
|
|
525
|
+
lastLocation.altitude.toFloat(),
|
|
509
526
|
System.currentTimeMillis()
|
|
510
527
|
)
|
|
511
528
|
} else {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
)
|
|
529
|
+
val locationRequest = LocationRequest.Builder(
|
|
530
|
+
LocationRequest.PRIORITY_HIGH_ACCURACY,
|
|
531
|
+
0L
|
|
532
|
+
).setMaxUpdates(1)
|
|
533
|
+
.build()
|
|
534
|
+
|
|
535
|
+
val locationCallback = object : LocationCallback() {
|
|
536
|
+
override fun onLocationResult(locationResult: LocationResult) {
|
|
537
|
+
locationResult.lastLocation?.let {
|
|
538
|
+
mGeofield = GeomagneticField(
|
|
539
|
+
it.latitude.toFloat(),
|
|
540
|
+
it.longitude.toFloat(),
|
|
541
|
+
it.altitude.toFloat(),
|
|
542
|
+
System.currentTimeMillis()
|
|
543
|
+
)
|
|
544
|
+
}
|
|
545
|
+
}
|
|
517
546
|
}
|
|
547
|
+
mLocationProvider.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
|
|
518
548
|
}
|
|
519
549
|
mSensorManager.registerListener(
|
|
520
550
|
this,
|
|
521
551
|
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
|
|
522
552
|
SensorManager.SENSOR_DELAY_NORMAL
|
|
523
553
|
)
|
|
524
|
-
mSensorManager.registerListener(
|
|
554
|
+
mSensorManager.registerListener(
|
|
555
|
+
this,
|
|
556
|
+
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
|
|
557
|
+
SensorManager.SENSOR_DELAY_NORMAL
|
|
558
|
+
)
|
|
525
559
|
}
|
|
526
560
|
|
|
527
561
|
private fun sendUpdate() {
|
|
@@ -599,7 +633,6 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
599
633
|
private fun stopWatching() {
|
|
600
634
|
// if permissions not granted it won't work anyway, but this can be invoked when permission dialog appears
|
|
601
635
|
if (Geocoder.isPresent() && !isMissingForegroundPermissions()) {
|
|
602
|
-
SmartLocation.with(mContext).geocoding().stop()
|
|
603
636
|
mGeocoderPaused = true
|
|
604
637
|
}
|
|
605
638
|
for (requestId in mLocationCallbacks.keys) {
|
|
@@ -666,8 +699,10 @@ class LocationModule : Module(), LifecycleEventListener, SensorEventListener, Ac
|
|
|
666
699
|
locations?.let { location ->
|
|
667
700
|
location.let {
|
|
668
701
|
val results = it.mapNotNull { address ->
|
|
669
|
-
val
|
|
670
|
-
|
|
702
|
+
val newLocation = Location(LocationManager.GPS_PROVIDER)
|
|
703
|
+
newLocation.latitude = address.latitude
|
|
704
|
+
newLocation.longitude = address.longitude
|
|
705
|
+
GeocodeResponse.from(newLocation)
|
|
671
706
|
}
|
|
672
707
|
continuation.resume(results)
|
|
673
708
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const LocationEventEmitter: import("expo
|
|
1
|
+
export declare const LocationEventEmitter: import("expo").EventEmitterType<Record<never, never>>;
|
|
2
2
|
//# sourceMappingURL=LocationEventEmitter.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationEventEmitter.web.d.ts","sourceRoot":"","sources":["../src/LocationEventEmitter.web.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"LocationEventEmitter.web.d.ts","sourceRoot":"","sources":["../src/LocationEventEmitter.web.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,uDAAqB,CAAC"}
|
package/expo-module.config.json
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"platforms": [
|
|
3
|
-
"apple",
|
|
4
|
-
"android"
|
|
5
|
-
],
|
|
2
|
+
"platforms": ["apple", "android"],
|
|
6
3
|
"apple": {
|
|
7
|
-
"modules": [
|
|
8
|
-
"LocationModule"
|
|
9
|
-
]
|
|
4
|
+
"modules": ["LocationModule"]
|
|
10
5
|
},
|
|
11
6
|
"android": {
|
|
12
|
-
"modules": [
|
|
13
|
-
"expo.modules.location.LocationModule"
|
|
14
|
-
],
|
|
15
|
-
"gradleAarProjects": [
|
|
16
|
-
{
|
|
17
|
-
"name": "io.nlopez.smartlocation-jetified-aar",
|
|
18
|
-
"aarFilePath": "android/libs/io.nlopez.smartlocation-3.3.3-jetified.aar"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
7
|
+
"modules": ["expo.modules.location.LocationModule"]
|
|
21
8
|
}
|
|
22
9
|
}
|
package/ios/LocationModule.swift
CHANGED
|
@@ -163,9 +163,13 @@ public final class LocationModule: Module {
|
|
|
163
163
|
// Background location
|
|
164
164
|
|
|
165
165
|
AsyncFunction("startLocationUpdatesAsync") { (taskName: String, options: [String: Any]) in
|
|
166
|
+
// There are two ways of starting this service.
|
|
167
|
+
// 1. As a background location service, this requires the background location permission.
|
|
168
|
+
// 2. As a user-initiated foreground service, this does NOT require the background location permission.
|
|
169
|
+
// Unfortunately, we cannot distinguish between those cases.
|
|
170
|
+
// So we only check foreground permission which needs to be granted in both cases.
|
|
166
171
|
try ensureLocationServicesEnabled()
|
|
167
172
|
try ensureForegroundLocationPermissions(appContext)
|
|
168
|
-
try ensureBackgroundLocationPermissions(appContext)
|
|
169
173
|
|
|
170
174
|
guard CLLocationManager.significantLocationChangeMonitoringAvailable() else {
|
|
171
175
|
throw Exceptions.LocationUpdatesUnavailable()
|
|
@@ -68,11 +68,10 @@
|
|
|
68
68
|
EXLocationAccuracy accuracy = [options[@"accuracy"] unsignedIntegerValue] ?: EXLocationAccuracyBalanced;
|
|
69
69
|
|
|
70
70
|
locationManager.desiredAccuracy = [EXLocation CLLocationAccuracyFromOption:accuracy];
|
|
71
|
-
locationManager.distanceFilter = [options[@"distanceInterval"]
|
|
72
|
-
locationManager.activityType = [EXLocation CLActivityTypeFromOption:[options[@"activityType"]
|
|
73
|
-
locationManager.pausesLocationUpdatesAutomatically = [options[@"pausesUpdatesAutomatically"]
|
|
74
|
-
|
|
75
|
-
locationManager.showsBackgroundLocationIndicator = [options[@"showsBackgroundLocationIndicator"] boolValue];
|
|
71
|
+
locationManager.distanceFilter = [self numberToDouble:options[@"distanceInterval"] defaultValue:kCLDistanceFilterNone];
|
|
72
|
+
locationManager.activityType = [EXLocation CLActivityTypeFromOption:[self numberToInteger:options[@"activityType"] defaultValue:CLActivityTypeOther]];
|
|
73
|
+
locationManager.pausesLocationUpdatesAutomatically = [self numberToBool:options[@"pausesUpdatesAutomatically"] defaultValue:true];
|
|
74
|
+
locationManager.showsBackgroundLocationIndicator = [self numberToBool:options[@"showsBackgroundLocationIndicator"] defaultValue:false];
|
|
76
75
|
|
|
77
76
|
[locationManager startUpdatingLocation];
|
|
78
77
|
[locationManager startMonitoringSignificantLocationChanges];
|
|
@@ -91,15 +90,7 @@
|
|
|
91
90
|
|
|
92
91
|
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
|
|
93
92
|
{
|
|
94
|
-
|
|
95
|
-
// This error might happen when the device is not able to find out the location. Try to restart monitoring location.
|
|
96
|
-
[manager stopUpdatingLocation];
|
|
97
|
-
[manager stopMonitoringSignificantLocationChanges];
|
|
98
|
-
[manager startUpdatingLocation];
|
|
99
|
-
[manager startMonitoringSignificantLocationChanges];
|
|
100
|
-
} else {
|
|
101
|
-
[_task executeWithData:nil withError:error];
|
|
102
|
-
}
|
|
93
|
+
[_task executeWithData:nil withError:error];
|
|
103
94
|
}
|
|
104
95
|
|
|
105
96
|
# pragma mark - internal
|
|
@@ -172,7 +163,17 @@
|
|
|
172
163
|
|
|
173
164
|
- (double)numberToDouble:(NSNumber *)number defaultValue:(double)defaultValue
|
|
174
165
|
{
|
|
175
|
-
return number == nil ? defaultValue : [number doubleValue];
|
|
166
|
+
return [number isEqual:[NSNull null]] || number == nil ? defaultValue : [number doubleValue];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
- (NSInteger)numberToInteger:(NSNumber *)number defaultValue:(NSInteger)defaultValue
|
|
170
|
+
{
|
|
171
|
+
return [number isEqual:[NSNull null]] || number == nil ? defaultValue : [number integerValue];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
- (BOOL)numberToBool:(NSNumber *)number defaultValue:(BOOL)defaultValue
|
|
175
|
+
{
|
|
176
|
+
return [number isEqual:[NSNull null]] || number == nil ? defaultValue : [number boolValue];
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
+ (NSArray<NSDictionary *> *)_exportLocations:(NSArray<CLLocation *> *)locations
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-location",
|
|
3
|
-
"version": "18.0.
|
|
3
|
+
"version": "18.0.9-canary-20250320-7a205d3",
|
|
4
4
|
"description": "Allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -39,10 +39,9 @@
|
|
|
39
39
|
"preset": "expo-module-scripts"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"expo-module-scripts": "
|
|
42
|
+
"expo-module-scripts": "4.0.5-canary-20250320-7a205d3"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"expo": "
|
|
46
|
-
}
|
|
47
|
-
"gitHead": "ee33df50fbe6bf9bb5d772e7f341f85a27cf9993"
|
|
45
|
+
"expo": "53.0.0-canary-20250320-7a205d3"
|
|
46
|
+
}
|
|
48
47
|
}
|
|
Binary file
|