Skip to content

Commit 09277b7

Browse files
feat(android): Fallback option for no network or Play Services (#53)
* feat(android): Fallback option for no network or Play Services * docs: Add additional error code * chore: update example app * chore: fix lint issues
1 parent 2bb0af4 commit 09277b7

File tree

7 files changed

+53
-23
lines changed

7 files changed

+53
-23
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,13 @@ Not available on web.
167167

168168
#### PositionOptions
169169

170-
| Prop | Type | Description | Default | Since |
171-
| --------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
172-
| **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173-
| **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174-
| **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175-
| **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
170+
| Prop | Type | Description | Default | Since |
171+
| ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- |
172+
| **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173+
| **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174+
| **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175+
| **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
176+
| **`enableLocationFallback`** | <code>boolean</code> | This option applies to Android only. Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail. This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode) If set to `false`, failures are propagated to the caller. Note that `LocationManager` may not be as effective as Google Play Services implementation. If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal. This means that to receive location in such circumstances, you may need to provide a higher timeout. | <code>true</code> | 8.0.0 |
176177

177178

178179
#### ClearWatchOptions
@@ -244,3 +245,4 @@ The following table list all the plugin errors:
244245
| OS-PLUG-GLOC-0014 | Android | Google Play Services error user resolvable. |
245246
| OS-PLUG-GLOC-0015 | Android | Google Play Services error. |
246247
| OS-PLUG-GLOC-0016 | Android | Location settings error. |
248+
| OS-PLUG-GLOC-0017 | Android | Unable to retrieve location because device has both Network and Location turned off. |

packages/capacitor-plugin/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,13 @@ Not available on web.
167167

168168
#### PositionOptions
169169

170-
| Prop | Type | Description | Default | Since |
171-
| --------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
172-
| **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173-
| **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174-
| **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175-
| **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
170+
| Prop | Type | Description | Default | Since |
171+
| ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- |
172+
| **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173+
| **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174+
| **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175+
| **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
176+
| **`enableLocationFallback`** | <code>boolean</code> | This option applies to Android only. Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail. This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode) If set to `false`, failures are propagated to the caller. Note that `LocationManager` may not be as effective as Google Play Services implementation. If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal. This means that to receive location in such circumstances, you may need to provide a higher timeout. | <code>true</code> | 8.0.0 |
176177

177178

178179
#### ClearWatchOptions
@@ -244,3 +245,4 @@ The following table list all the plugin errors:
244245
| OS-PLUG-GLOC-0014 | Android | Google Play Services error user resolvable. |
245246
| OS-PLUG-GLOC-0015 | Android | Google Play Services error. |
246247
| OS-PLUG-GLOC-0016 | Android | Location settings error. |
248+
| OS-PLUG-GLOC-0017 | Android | Unable to retrieve location because device has both Network and Location turned off. |

packages/capacitor-plugin/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ repositories {
5858

5959
dependencies {
6060
implementation fileTree(dir: 'libs', include: ['*.jar'])
61-
implementation("io.ionic.libs:iongeolocation-android:1.0.0")
61+
implementation("io.ionic.libs:iongeolocation-android:2.0.0")
6262
implementation project(':capacitor-android')
6363
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
6464

packages/capacitor-plugin/android/src/main/kotlin/com/capacitorjs/plugins/geolocation/GeolocationErrors.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,9 @@ object GeolocationErrors {
6868
code = formatErrorCode(16),
6969
message = "Location settings error."
7070
)
71+
72+
val NETWORK_LOCATION_DISABLED_ERROR = ErrorInfo(
73+
code = formatErrorCode(17),
74+
message = "Unable to retrieve location because device has both Network and Location turned off."
75+
)
7176
}

packages/capacitor-plugin/android/src/main/kotlin/com/capacitorjs/plugins/geolocation/GeolocationPlugin.kt

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,7 @@ class GeolocationPlugin : Plugin() {
5454
}
5555
}
5656

57-
this.controller = IONGLOCController(
58-
LocationServices.getFusedLocationProviderClient(context),
59-
activityLauncher
60-
)
61-
57+
this.controller = IONGLOCController(context, activityLauncher)
6258
}
6359

6460
override fun handleOnDestroy() {
@@ -82,7 +78,7 @@ class GeolocationPlugin : Plugin() {
8278
* @param onLocationEnabled lambda function to use in case location services are enabled
8379
*/
8480
private fun checkLocationState(call: PluginCall, onLocationEnabled: () -> Unit) {
85-
if (controller.areLocationServicesEnabled(context)) {
81+
if (controller.areLocationServicesEnabled()) {
8682
onLocationEnabled()
8783
} else {
8884
call.sendError(GeolocationErrors.LOCATION_DISABLED)
@@ -279,6 +275,9 @@ class GeolocationPlugin : Plugin() {
279275
is IONGLOCException.IONGLOCSettingsException -> {
280276
call.sendError(GeolocationErrors.LOCATION_SETTINGS_ERROR)
281277
}
278+
is IONGLOCException.IONGLOCLocationAndNetworkDisabledException -> {
279+
call.sendError(GeolocationErrors.NETWORK_LOCATION_DISABLED_ERROR)
280+
}
282281
is IONGLOCException.IONGLOCInvalidTimeoutException -> {
283282
call.sendError(GeolocationErrors.INVALID_TIMEOUT)
284283
}
@@ -330,8 +329,15 @@ class GeolocationPlugin : Plugin() {
330329
val maximumAge = call.getNumber("maximumAge", 0)
331330
val enableHighAccuracy = call.getBoolean("enableHighAccuracy", false) ?: false
332331
val minimumUpdateInterval = call.getNumber("minimumUpdateInterval", 5000)
333-
334-
val locationOptions = IONGLOCLocationOptions(timeout, maximumAge, enableHighAccuracy, minimumUpdateInterval)
332+
val enableLocationFallback = call.getBoolean("enableLocationFallback", true) ?: true
333+
334+
val locationOptions = IONGLOCLocationOptions(
335+
timeout,
336+
maximumAge,
337+
enableHighAccuracy,
338+
enableLocationFallback,
339+
minimumUpdateInterval
340+
)
335341

336342
return locationOptions
337343
}

packages/capacitor-plugin/src/definitions.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,21 @@ export interface PositionOptions {
191191
* @since 6.1.0
192192
*/
193193
minimumUpdateInterval?: number;
194+
195+
/**
196+
* This option applies to Android only.
197+
*
198+
* Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail.
199+
* This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode)
200+
* If set to `false`, failures are propagated to the caller.
201+
* Note that `LocationManager` may not be as effective as Google Play Services implementation.
202+
* If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal.
203+
* This means that to receive location in such circumstances, you may need to provide a higher timeout.
204+
*
205+
* @default true
206+
* @since 8.0.0
207+
*/
208+
enableLocationFallback?: boolean;
194209
}
195210

196211
export type WatchPositionCallback = (position: Position | null, err?: any) => void;

0 commit comments

Comments
 (0)