@capgo/background-geolocation 8.0.32 → 8.0.33

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/README.md CHANGED
@@ -6,8 +6,16 @@
6
6
  <h2><a href="https://capgo.app/consulting/?ref=plugin_background_geolocation"> Missing a feature? We’ll build the plugin for you 💪</a></h2>
7
7
  </div>
8
8
 
9
- A Capacitor plugin that lets you receive accurate geolocation updates even while the app is backgrounded.
10
- It has a web API to facilitate for a similar usage, but background geolocation is not supported in a regular browser, only in an app environment.
9
+ A Capacitor plugin for accurate background location tracking and native geofencing on iOS and Android.
10
+ Use it to stream precise location updates, monitor circular geofence regions, react to enter/exit events in JavaScript, and POST geofence transitions natively while the WebView is suspended.
11
+
12
+ ## Features
13
+
14
+ - Accurate foreground and background geolocation without a paid license.
15
+ - Native geofencing on iOS and Android for circular regions.
16
+ - Enter and exit events through `geofenceTransition` while the app is alive.
17
+ - Native webhook delivery for geofence transitions when the WebView is suspended.
18
+ - A web fallback for development and browser-based testing.
11
19
 
12
20
  ## This plugin's history
13
21
 
@@ -32,16 +40,17 @@ I hope you'll enjoy it!
32
40
 
33
41
  A short comparison between the three main background-geolocation plugins commonly used in Capacitor apps.
34
42
 
35
- | Plugin | Accuracy | Background | HTTP Upload | Pricing |
36
- |--------|----------|------------|-------------|---------|
37
- | `@capacitor-community/background-geolocation` (Community) | Not accurate | Yes | No | Free |
38
- | `@capgo/background-geolocation` (this plugin) | Accurate | Yes | No | Free |
39
- | Transistorsoft (original) | Accurate | Yes | Yes — built-in HTTP uploader to your API | Paid |
43
+ | Plugin | Accuracy | Background | Geofencing | Native transition POST | Pricing |
44
+ |--------|----------|------------|------------|------------------------|---------|
45
+ | `@capacitor-community/background-geolocation` (Community) | Not accurate | Yes | No | No | Free |
46
+ | `@capgo/background-geolocation` (this plugin) | Accurate | Yes | iOS and Android | Yes, for geofence transitions | Free |
47
+ | Transistorsoft (original) | Accurate | Yes | Yes | Yes, built-in HTTP uploader | Paid |
40
48
 
41
49
  Notes:
42
50
  - The Community plugin is lightweight and continues to work in the background, but it is known to be less accurate than the options below.
43
- - This Cap-go plugin aims to provide accurate location fixes and reliable background operation without requiring a paid license.
44
- - Transistorsoft's plugin is a mature, accurate solution that also includes an HTTP uploader (it can send location updates to your API). It is a commercial product and requires a paid license for full use.
51
+ - This Cap-go plugin aims to provide accurate location fixes, reliable background operation, and native geofence enter/exit handling without requiring a paid license.
52
+ - Native geofence POST delivery is useful when iOS or Android wakes native code for a region transition but the Capacitor WebView is not running.
53
+ - Transistorsoft's plugin is a mature, accurate solution that also includes a broader HTTP uploader. It is a commercial product and requires a paid license for full use.
45
54
 
46
55
 
47
56
  ## Usage
@@ -84,7 +93,51 @@ BackgroundGeolocation.start(
84
93
  // Set a planned route to get a notification sound when a new location arrives and it's not on the route:
85
94
 
86
95
  BackgroundGeolocation.setPlannedRoute({soundFile: "assets/myFile.mp3", route: [[1,2], [3,4]], distance: 30 });
96
+ ```
97
+
98
+ ## Native geofencing
99
+
100
+ Use native geofencing when you need lightweight location boundaries such as stores, job sites, delivery zones, campuses, or check-in areas. The plugin monitors geofences natively, emits JavaScript events while the app is active, and can send transition payloads directly to your backend while the WebView is suspended.
101
+
102
+ ```javascript
103
+ import { BackgroundGeolocation } from "@capgo/background-geolocation";
104
+
105
+ // Geofencing can notify JavaScript while the app is alive and can also POST
106
+ // transitions natively while the WebView is suspended.
107
+ await BackgroundGeolocation.setupGeofencing({
108
+ url: "https://api.example.com/geofences",
109
+ notifyOnEntry: true,
110
+ notifyOnExit: true,
111
+ payload: { userId: "123" }
112
+ });
113
+
114
+ await BackgroundGeolocation.addGeofence({
115
+ identifier: "office",
116
+ latitude: 37.33182,
117
+ longitude: -122.03118,
118
+ radius: 150
119
+ });
120
+
121
+ const handle = await BackgroundGeolocation.addListener(
122
+ "geofenceTransition",
123
+ (event) => console.log(event.identifier, event.transition)
124
+ );
125
+
126
+ await BackgroundGeolocation.removeGeofence({ identifier: "office" });
127
+ handle.remove();
128
+ ```
129
+
130
+ ### Android background geofence permission
131
+
132
+ The plugin does not add `ACCESS_BACKGROUND_LOCATION` by default. Add it to your app manifest only when you need background geofencing or background location updates:
87
133
 
134
+ ```xml
135
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
136
+ ```
137
+
138
+ Apps that only use foreground location can omit this permission.
139
+
140
+ ```javascript
88
141
  // If you just want the current location, try something like this. The longer
89
142
  // the timeout, the more accurate the guess will be. I wouldn't go below about 100ms.
90
143
  function guessLocation(callback, timeout) {
@@ -123,15 +176,15 @@ The most complete doc is available here: https://capgo.app/docs/plugins/backgrou
123
176
 
124
177
  ## Installation
125
178
 
126
- This plugin supports Capacitor v7:
179
+ This plugin supports Capacitor v8:
127
180
 
128
181
  | Capacitor | Plugin |
129
182
  |------------|--------|
130
- | v7 | v7 |
183
+ | v8 | v8 |
131
184
 
132
185
  ```sh
133
- npm install @capgo/background-geolocation
134
- npx cap update
186
+ bun add @capgo/background-geolocation
187
+ bunx cap update
135
188
  ```
136
189
 
137
190
  ### iOS
@@ -158,6 +211,8 @@ Set the the `android.useLegacyBridge` option to `true` in your Capacitor configu
158
211
 
159
212
  On Android 13+, the app needs the `POST_NOTIFICATIONS` runtime permission to show the persistent notification informing the user that their location is being used in the background. This runtime permission is requested after the location permission is granted.
160
213
 
214
+ For geofencing on Android 10+, the app also needs `ACCESS_BACKGROUND_LOCATION`. Android may require the user to grant this from system settings after foreground location is granted; use `openSettings()` if the permission remains denied.
215
+
161
216
  If your app forwards location updates to a server in real time, be aware that after 5 minutes in the background Android will throttle HTTP requests initiated from the WebView. The solution is to use a native HTTP plugin such as [CapacitorHttp](https://capacitorjs.com/docs/apis/http). See https://github.com/capacitor-community/background-geolocation/issues/14.
162
217
 
163
218
  Configuration specific to Android can be made in `strings.xml`:
@@ -212,8 +267,16 @@ Configuration specific to Android can be made in `strings.xml`:
212
267
  * [`stop()`](#stop)
213
268
  * [`openSettings()`](#opensettings)
214
269
  * [`setPlannedRoute(...)`](#setplannedroute)
270
+ * [`setupGeofencing(...)`](#setupgeofencing)
271
+ * [`addGeofence(...)`](#addgeofence)
272
+ * [`removeGeofence(...)`](#removegeofence)
273
+ * [`removeAllGeofences()`](#removeallgeofences)
274
+ * [`getMonitoredGeofences()`](#getmonitoredgeofences)
275
+ * [`addListener('geofenceTransition', ...)`](#addlistenergeofencetransition-)
276
+ * [`addListener('geofenceError', ...)`](#addlistenergeofenceerror-)
215
277
  * [`getPluginVersion()`](#getpluginversion)
216
278
  * [Interfaces](#interfaces)
279
+ * [Type Aliases](#type-aliases)
217
280
 
218
281
  </docgen-index>
219
282
 
@@ -288,6 +351,131 @@ This should be used to play a sound (in the background too, only for native).
288
351
  --------------------
289
352
 
290
353
 
354
+ ### setupGeofencing(...)
355
+
356
+ ```typescript
357
+ setupGeofencing(options: GeofenceSetupOptions) => Promise<void>
358
+ ```
359
+
360
+ Configures native geofence transition handling.
361
+
362
+ Call this before adding geofences when you need native background POSTs
363
+ or default entry/exit settings.
364
+
365
+ | Param | Type | Description |
366
+ | ------------- | --------------------------------------------------------------------- | ---------------------------------- |
367
+ | **`options`** | <code><a href="#geofencesetupoptions">GeofenceSetupOptions</a></code> | The geofence configuration options |
368
+
369
+ **Since:** 8.0.30
370
+
371
+ --------------------
372
+
373
+
374
+ ### addGeofence(...)
375
+
376
+ ```typescript
377
+ addGeofence(options: AddGeofenceOptions) => Promise<void>
378
+ ```
379
+
380
+ Starts monitoring a circular native geofence.
381
+
382
+ | Param | Type | Description |
383
+ | ------------- | ----------------------------------------------------------------- | --------------------------- |
384
+ | **`options`** | <code><a href="#addgeofenceoptions">AddGeofenceOptions</a></code> | The geofence region options |
385
+
386
+ **Since:** 8.0.30
387
+
388
+ --------------------
389
+
390
+
391
+ ### removeGeofence(...)
392
+
393
+ ```typescript
394
+ removeGeofence(options: RemoveGeofenceOptions) => Promise<void>
395
+ ```
396
+
397
+ Stops monitoring one geofence.
398
+
399
+ | Param | Type | Description |
400
+ | ------------- | ----------------------------------------------------------------------- | ----------------------- |
401
+ | **`options`** | <code><a href="#removegeofenceoptions">RemoveGeofenceOptions</a></code> | The geofence identifier |
402
+
403
+ **Since:** 8.0.30
404
+
405
+ --------------------
406
+
407
+
408
+ ### removeAllGeofences()
409
+
410
+ ```typescript
411
+ removeAllGeofences() => Promise<void>
412
+ ```
413
+
414
+ Stops monitoring every geofence registered by this plugin.
415
+
416
+ **Since:** 8.0.30
417
+
418
+ --------------------
419
+
420
+
421
+ ### getMonitoredGeofences()
422
+
423
+ ```typescript
424
+ getMonitoredGeofences() => Promise<MonitoredGeofencesResult>
425
+ ```
426
+
427
+ Lists the geofence identifiers currently monitored by this plugin.
428
+
429
+ **Returns:** <code>Promise&lt;<a href="#monitoredgeofencesresult">MonitoredGeofencesResult</a>&gt;</code>
430
+
431
+ **Since:** 8.0.30
432
+
433
+ --------------------
434
+
435
+
436
+ ### addListener('geofenceTransition', ...)
437
+
438
+ ```typescript
439
+ addListener(eventName: 'geofenceTransition', listenerFunc: (event: GeofenceTransitionEvent) => void) => Promise<PluginListenerHandle>
440
+ ```
441
+
442
+ Listens for geofence enter/exit transitions while the WebView is alive.
443
+
444
+ Native `url` delivery configured through `setupGeofencing` is used for
445
+ background-safe delivery.
446
+
447
+ | Param | Type |
448
+ | ------------------ | ----------------------------------------------------------------------------------------------- |
449
+ | **`eventName`** | <code>'geofenceTransition'</code> |
450
+ | **`listenerFunc`** | <code>(event: <a href="#geofencetransitionevent">GeofenceTransitionEvent</a>) =&gt; void</code> |
451
+
452
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
453
+
454
+ **Since:** 8.0.30
455
+
456
+ --------------------
457
+
458
+
459
+ ### addListener('geofenceError', ...)
460
+
461
+ ```typescript
462
+ addListener(eventName: 'geofenceError', listenerFunc: (event: GeofenceErrorEvent) => void) => Promise<PluginListenerHandle>
463
+ ```
464
+
465
+ Listens for native geofence monitoring errors while the WebView is alive.
466
+
467
+ | Param | Type |
468
+ | ------------------ | ------------------------------------------------------------------------------------- |
469
+ | **`eventName`** | <code>'geofenceError'</code> |
470
+ | **`listenerFunc`** | <code>(event: <a href="#geofenceerrorevent">GeofenceErrorEvent</a>) =&gt; void</code> |
471
+
472
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
473
+
474
+ **Since:** 8.0.30
475
+
476
+ --------------------
477
+
478
+
291
479
  ### getPluginVersion()
292
480
 
293
481
  ```typescript
@@ -353,4 +541,100 @@ Extends the standard Error with optional error codes.
353
541
  | **`route`** | <code>[number, number][]</code> | The planned route as an array of longitude and latitude pairs. Each pair represents a point on the route. This is used to define a route that the user can follow. The route is used to play a sound when the user deviates from it. | | 7.0.11 |
354
542
  | **`distance`** | <code>number</code> | The distance in meters that the user must deviate from the planned route to trigger the sound. This is used to determine how far off the route the user can be before the sound is played. If not specified, a default value of 50 meters is used. | <code>50</code> | 7.0.11 |
355
543
 
544
+
545
+ #### GeofenceSetupOptions
546
+
547
+ Options for configuring native geofence transition handling.
548
+
549
+ When `url` is provided, native iOS and Android code sends a JSON `POST`
550
+ whenever a monitored region is entered or exited. This keeps geofence
551
+ handling useful when the WebView is suspended.
552
+
553
+ | Prop | Type | Description | Default | Since |
554
+ | ------------------------ | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------ |
555
+ | **`url`** | <code>string</code> | Endpoint that receives geofence transition payloads. | | 8.0.30 |
556
+ | **`notifyOnEntry`** | <code>boolean</code> | Whether entry transitions should be monitored. | <code>true</code> | 8.0.30 |
557
+ | **`notifyOnExit`** | <code>boolean</code> | Whether exit transitions should be monitored. | <code>true</code> | 8.0.30 |
558
+ | **`payload`** | <code><a href="#record">Record</a>&lt;string, unknown&gt;</code> | Base JSON payload merged into every native transition POST and listener event. | | 8.0.30 |
559
+ | **`requestPermissions`** | <code>boolean</code> | Whether the plugin should request the native location permission needed for geofencing. iOS geofencing needs Always location authorization. Android background geofencing needs foreground location and, on Android 10+, background location permission. | <code>true</code> | 8.0.30 |
560
+
561
+
562
+ #### AddGeofenceOptions
563
+
564
+ A circular geofence region.
565
+
566
+ | Prop | Type | Description | Default | Since |
567
+ | ------------------- | ---------------------------------------------------------------- | -------------------------------------------------------- | --------------- | ------ |
568
+ | **`latitude`** | <code>number</code> | Latitude in degrees for the region center. | | 8.0.30 |
569
+ | **`longitude`** | <code>number</code> | Longitude in degrees for the region center. | | 8.0.30 |
570
+ | **`radius`** | <code>number</code> | Region radius in meters. | <code>50</code> | 8.0.30 |
571
+ | **`identifier`** | <code>string</code> | Stable identifier for the geofence. | | 8.0.30 |
572
+ | **`notifyOnEntry`** | <code>boolean</code> | Overrides the setup-level entry setting for this region. | | 8.0.30 |
573
+ | **`notifyOnExit`** | <code>boolean</code> | Overrides the setup-level exit setting for this region. | | 8.0.30 |
574
+ | **`payload`** | <code><a href="#record">Record</a>&lt;string, unknown&gt;</code> | Region-specific payload merged over the setup payload. | | 8.0.30 |
575
+
576
+
577
+ #### RemoveGeofenceOptions
578
+
579
+ Options for removing a monitored geofence.
580
+
581
+ | Prop | Type | Description | Since |
582
+ | ---------------- | ------------------- | ----------------------------------- | ------ |
583
+ | **`identifier`** | <code>string</code> | Identifier passed to `addGeofence`. | 8.0.30 |
584
+
585
+
586
+ #### MonitoredGeofencesResult
587
+
588
+ Result returned when listing monitored geofences.
589
+
590
+ | Prop | Type | Description | Since |
591
+ | ------------- | --------------------- | ----------------------------------------------------------------- | ------ |
592
+ | **`regions`** | <code>string[]</code> | Identifiers for all geofences currently monitored by this plugin. | 8.0.30 |
593
+
594
+
595
+ #### PluginListenerHandle
596
+
597
+ | Prop | Type |
598
+ | ------------ | ----------------------------------------- |
599
+ | **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
600
+
601
+
602
+ #### GeofenceTransitionEvent
603
+
604
+ Event emitted when a monitored geofence is entered or exited.
605
+
606
+ The same data is also sent to the configured `url`, when one is set.
607
+
608
+ | Prop | Type | Description | Since |
609
+ | ---------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------- | ------ |
610
+ | **`identifier`** | <code>string</code> | Identifier of the geofence that changed state. | 8.0.30 |
611
+ | **`transition`** | <code>'enter' \| 'exit'</code> | Transition name. | 8.0.30 |
612
+ | **`enter`** | <code>boolean</code> | `true` for entry transitions, `false` for exit transitions. | 8.0.30 |
613
+ | **`latitude`** | <code>number</code> | Latitude in degrees for the monitored region center, when available. | 8.0.30 |
614
+ | **`longitude`** | <code>number</code> | Longitude in degrees for the monitored region center, when available. | 8.0.30 |
615
+ | **`radius`** | <code>number</code> | Region radius in meters, when available. | 8.0.30 |
616
+ | **`payload`** | <code><a href="#record">Record</a>&lt;string, unknown&gt;</code> | Merged setup and region payload. | 8.0.30 |
617
+
618
+
619
+ #### GeofenceErrorEvent
620
+
621
+ Event emitted when native geofence monitoring fails.
622
+
623
+ | Prop | Type | Description | Since |
624
+ | ---------------- | ------------------- | -------------------------------------------------------------------- | ------ |
625
+ | **`identifier`** | <code>string</code> | Identifier of the geofence that failed, when native APIs provide it. | 8.0.30 |
626
+ | **`code`** | <code>number</code> | Native platform error code. | 8.0.30 |
627
+ | **`message`** | <code>string</code> | Native platform error message. | 8.0.30 |
628
+ | **`domain`** | <code>string</code> | Native error domain, when available. | 8.0.30 |
629
+
630
+
631
+ ### Type Aliases
632
+
633
+
634
+ #### Record
635
+
636
+ Construct a type with a set of properties K of type T
637
+
638
+ <code>{
356
639
  [P in K]: T;
357
640
  }</code>
641
+
358
642
  </docgen-api>
@@ -4,6 +4,7 @@ ext {
4
4
  androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
5
  androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
6
  androidxLocalbroadcastmanagerVersion = project.hasProperty('androidxLocalbroadcastmanagerVersion') ? rootProject.ext.androidxLocalbroadcastmanagerVersion : '1.0.0'
7
+ androidxWorkRuntimeVersion = project.hasProperty('androidxWorkRuntimeVersion') ? rootProject.ext.androidxWorkRuntimeVersion : '2.11.2'
7
8
  playServicesLocationVersion = project.hasProperty('playServicesLocationVersion') ? rootProject.ext.playServicesLocationVersion : '21.3.0'
8
9
  }
9
10
 
@@ -55,6 +56,7 @@ dependencies {
55
56
  implementation project(':capacitor-android')
56
57
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
57
58
  implementation "androidx.localbroadcastmanager:localbroadcastmanager:$androidxLocalbroadcastmanagerVersion"
59
+ implementation "androidx.work:work-runtime:$androidxWorkRuntimeVersion"
58
60
  testImplementation "junit:junit:$junitVersion"
59
61
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
60
62
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -5,6 +5,21 @@
5
5
  android:enabled="true"
6
6
  android:exported="true"
7
7
  android:foregroundServiceType="location" />
8
+
9
+ <receiver
10
+ android:name="com.capgo.capacitor_background_geolocation.GeofenceBroadcastReceiver"
11
+ android:enabled="true"
12
+ android:exported="false" />
13
+
14
+ <receiver
15
+ android:name="com.capgo.capacitor_background_geolocation.GeofenceBootReceiver"
16
+ android:enabled="true"
17
+ android:exported="false">
18
+ <intent-filter>
19
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
20
+ <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
21
+ </intent-filter>
22
+ </receiver>
8
23
  </application>
9
24
 
10
25
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
@@ -18,6 +33,8 @@
18
33
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
19
34
  <!-- See https://github.com/Cap-go/capacitor-background-geolocation/issues/12 for more details-->
20
35
  <uses-permission android:name="android.permission.WAKE_LOCK" />
36
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
37
+ <uses-permission android:name="android.permission.INTERNET" />
21
38
  <uses-feature android:name="android.hardware.location.gps" />
22
39
  </manifest>
23
40