@capgo/background-geolocation 7.0.8 → 7.0.10
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 +163 -70
- package/android/src/main/java/com/capgo/capacitor_background_geolocation/BackgroundGeolocation.java +46 -103
- package/android/src/main/java/com/capgo/capacitor_background_geolocation/BackgroundGeolocationService.java +192 -54
- package/dist/docs.json +106 -56
- package/dist/esm/definitions.d.ts +65 -42
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +5 -7
- package/dist/esm/web.js +27 -16
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +27 -16
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +27 -16
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/Plugin.m +3 -2
- package/ios/Plugin/Plugin.swift +114 -93
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,48 +9,39 @@
|
|
|
9
9
|
A Capacitor plugin that lets you receive geolocation updates even while the app is backgrounded.
|
|
10
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.
|
|
11
11
|
|
|
12
|
+
## This plugin's history
|
|
13
|
+
|
|
14
|
+
Interestingly enough, this plugin has a lot of history. The initial solution from [Transistorsoft](https://github.com/transistorsoft) was a great piece of software, and I encourage using it if it fits your needs.
|
|
15
|
+
I tried it and understood that it prioritizes battery life over accuracy, which wasn't the right fit for my hiking app.
|
|
16
|
+
There was a very good fork maintained by **mauron85** specifically for that use case, and I was happy to help maintain it.
|
|
17
|
+
But at some point, **mauron85** stopped responding to messages on GitHub, and no one could continue maintaining it.
|
|
18
|
+
I hope mauron85 is safe and sound somewhere.
|
|
19
|
+
|
|
20
|
+
So I created a fork and started maintaining it [here](https://github.com/HaylLtd/cordova-background-geolocation-plugin).
|
|
21
|
+
It served me well for over half a decade, but I felt it was hard to maintain due to all its history, features, and bug fixes.
|
|
22
|
+
I also felt like there was a barrier to introducing new features because of its complexity.
|
|
23
|
+
|
|
24
|
+
So I started exploring what it would take to reduce that complexity—at the same time, I was envious of how small [`@capacitor-community/background-geolocation`](https://github.com/capacitor-community/background-geolocation) is.
|
|
25
|
+
I took the best of both worlds: tried to reduce the codebase in the original Cordova plugin and add some robustness to the Capacitor plugin.
|
|
26
|
+
|
|
27
|
+
That's how I ended up maintaining this one.
|
|
28
|
+
I hope you'll enjoy it!
|
|
29
|
+
|
|
30
|
+
|
|
12
31
|
## Usage
|
|
13
32
|
|
|
14
33
|
```javascript
|
|
15
34
|
import { BackgroundGeolocation } from "@capgo/background-geolocation";
|
|
16
35
|
|
|
17
|
-
|
|
18
|
-
// You do this by calling 'addWatcher' with an options object and a callback. A
|
|
19
|
-
// Promise is returned, which resolves to the callback ID used to remove the
|
|
20
|
-
// watcher in the future. The callback will be called every time a new location
|
|
21
|
-
// is available. Watchers can not be paused, only removed. Multiple watchers may
|
|
22
|
-
// exist simultaneously.
|
|
23
|
-
BackgroundGeolocation.addWatcher(
|
|
36
|
+
BackgroundGeolocation.start(
|
|
24
37
|
{
|
|
25
|
-
// If the "backgroundMessage" option is defined, the watcher will
|
|
26
|
-
// provide location updates whether the app is in the background or the
|
|
27
|
-
// foreground. If it is not defined, location updates are only
|
|
28
|
-
// guaranteed in the foreground. This is true on both platforms.
|
|
29
|
-
|
|
30
|
-
// On Android, a notification must be shown to continue receiving
|
|
31
|
-
// location updates in the background. This option specifies the text of
|
|
32
|
-
// that notification.
|
|
33
38
|
backgroundMessage: "Cancel to prevent battery drain.",
|
|
34
|
-
|
|
35
|
-
// The title of the notification mentioned above. Defaults to "Using
|
|
36
|
-
// your location".
|
|
37
39
|
backgroundTitle: "Tracking You.",
|
|
38
|
-
|
|
39
|
-
// Whether permissions should be requested from the user automatically,
|
|
40
|
-
// if they are not already granted. Defaults to "true".
|
|
41
40
|
requestPermissions: true,
|
|
42
|
-
|
|
43
|
-
// If "true", stale locations may be delivered while the device
|
|
44
|
-
// obtains a GPS fix. You are responsible for checking the "time"
|
|
45
|
-
// property. If "false", locations are guaranteed to be up to date.
|
|
46
|
-
// Defaults to "false".
|
|
47
41
|
stale: false,
|
|
48
|
-
|
|
49
|
-
// The minimum number of metres between subsequent locations. Defaults
|
|
50
|
-
// to 0.
|
|
51
42
|
distanceFilter: 50
|
|
52
43
|
},
|
|
53
|
-
|
|
44
|
+
(location, error) => {
|
|
54
45
|
if (error) {
|
|
55
46
|
if (error.code === "NOT_AUTHORIZED") {
|
|
56
47
|
if (window.confirm(
|
|
@@ -67,56 +58,31 @@ BackgroundGeolocation.addWatcher(
|
|
|
67
58
|
}
|
|
68
59
|
return console.error(error);
|
|
69
60
|
}
|
|
70
|
-
|
|
61
|
+
// in case of off-track for example, play a sound:
|
|
62
|
+
BackgroundGeolocation.playSound({soundFile: "assets/myFile.mp3" });
|
|
71
63
|
return console.log(location);
|
|
72
64
|
}
|
|
73
|
-
).then(
|
|
74
|
-
// When
|
|
75
|
-
|
|
76
|
-
BackgroundGeolocation.removeWatcher({
|
|
77
|
-
id: watcher_id
|
|
78
|
-
});
|
|
65
|
+
).then(() => {
|
|
66
|
+
// When location updates are no longer needed, the plugin should be stopped by calling
|
|
67
|
+
BackgroundGeolocation.stop();
|
|
79
68
|
});
|
|
80
69
|
|
|
81
|
-
// The location object.
|
|
82
|
-
{
|
|
83
|
-
// Longitude in degrees.
|
|
84
|
-
longitude: 131.723423719132,
|
|
85
|
-
// Latitude in degrees.
|
|
86
|
-
latitude: -22.40106297456,
|
|
87
|
-
// Radius of horizontal uncertainty in metres, with 68% confidence.
|
|
88
|
-
accuracy: 11,
|
|
89
|
-
// Metres above sea level (or null).
|
|
90
|
-
altitude: 65,
|
|
91
|
-
// Vertical uncertainty in metres, with 68% confidence (or null).
|
|
92
|
-
altitudeAccuracy: 4,
|
|
93
|
-
// Deviation from true north in degrees (or null).
|
|
94
|
-
bearing: 159.60000610351562,
|
|
95
|
-
// True if the location was simulated by software, rather than GPS.
|
|
96
|
-
simulated: false,
|
|
97
|
-
// Speed in metres per second (or null).
|
|
98
|
-
speed: 23.51068878173828,
|
|
99
|
-
// Time the location was produced, in milliseconds since the unix epoch.
|
|
100
|
-
time: 1562731602000
|
|
101
|
-
}
|
|
102
|
-
|
|
103
70
|
// If you just want the current location, try something like this. The longer
|
|
104
|
-
// the timeout, the more accurate the guess will be. I wouldn't go below about
|
|
105
|
-
|
|
106
|
-
function guess_location(callback, timeout) {
|
|
71
|
+
// the timeout, the more accurate the guess will be. I wouldn't go below about 100ms.
|
|
72
|
+
function guessLocation(callback, timeout) {
|
|
107
73
|
let last_location;
|
|
108
|
-
BackgroundGeolocation.
|
|
74
|
+
BackgroundGeolocation.start(
|
|
109
75
|
{
|
|
110
76
|
requestPermissions: false,
|
|
111
77
|
stale: true
|
|
112
78
|
},
|
|
113
|
-
|
|
79
|
+
(location) => {
|
|
114
80
|
last_location = location || undefined;
|
|
115
81
|
}
|
|
116
|
-
).then(
|
|
117
|
-
setTimeout(
|
|
82
|
+
).then(() => {
|
|
83
|
+
setTimeout(() => {
|
|
118
84
|
callback(last_location);
|
|
119
|
-
BackgroundGeolocation.
|
|
85
|
+
BackgroundGeolocation.stop();
|
|
120
86
|
}, timeout);
|
|
121
87
|
});
|
|
122
88
|
}
|
|
@@ -128,7 +94,7 @@ This plugin supports Capacitor v7:
|
|
|
128
94
|
|
|
129
95
|
| Capacitor | Plugin |
|
|
130
96
|
|------------|--------|
|
|
131
|
-
| v7 |
|
|
97
|
+
| v7 | v7 |
|
|
132
98
|
|
|
133
99
|
```sh
|
|
134
100
|
npm install @capgo/background-geolocation
|
|
@@ -208,9 +174,136 @@ Configration specific to Android can be made in `strings.xml`:
|
|
|
208
174
|
|
|
209
175
|
<docgen-index>
|
|
210
176
|
|
|
211
|
-
* [`
|
|
212
|
-
* [`
|
|
177
|
+
* [`start(...)`](#start)
|
|
178
|
+
* [`stop()`](#stop)
|
|
213
179
|
* [`openSettings()`](#opensettings)
|
|
180
|
+
* [`playSound(...)`](#playsound)
|
|
214
181
|
* [Interfaces](#interfaces)
|
|
215
182
|
|
|
216
183
|
</docgen-index>
|
|
184
|
+
|
|
185
|
+
<docgen-api>
|
|
186
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
187
|
+
|
|
188
|
+
Main plugin interface for background geolocation functionality.
|
|
189
|
+
Provides methods to manage location updates and access device settings.
|
|
190
|
+
|
|
191
|
+
### start(...)
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
start(options: StartOptions, callback: (position?: Location | undefined, error?: CallbackError | undefined) => void) => Promise<void>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
To start listening for changes in the device's location, call this method.
|
|
198
|
+
A Promise is returned to indicate that it finished the call. The callback will be called every time a new location
|
|
199
|
+
is available, or if there was an error when calling this method. Don't rely on promise rejection for this.
|
|
200
|
+
|
|
201
|
+
| Param | Type | Description |
|
|
202
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
203
|
+
| **`options`** | <code><a href="#startoptions">StartOptions</a></code> | The configuration options |
|
|
204
|
+
| **`callback`** | <code>(position?: <a href="#location">Location</a>, error?: <a href="#callbackerror">CallbackError</a>) => void</code> | The callback function invoked when a new location is available or an error occurs |
|
|
205
|
+
|
|
206
|
+
**Since:** 7.0.9
|
|
207
|
+
|
|
208
|
+
--------------------
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
### stop()
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
stop() => Promise<void>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Stops location updates.
|
|
218
|
+
|
|
219
|
+
**Since:** 7.0.9
|
|
220
|
+
|
|
221
|
+
--------------------
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
### openSettings()
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
openSettings() => Promise<void>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Opens the device's location settings page.
|
|
231
|
+
Useful for directing users to enable location services or adjust permissions.
|
|
232
|
+
|
|
233
|
+
**Since:** 7.0.0
|
|
234
|
+
|
|
235
|
+
--------------------
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
### playSound(...)
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
playSound(options: PlaySoundOptions) => Promise<void>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Plays a sound file.
|
|
245
|
+
This should be used to play a sound, in the background too.
|
|
246
|
+
The idea behind this is to allow the user to hear a sound when a new location is available or when going off track.
|
|
247
|
+
If you simply need to play a sound, you can use `@capgo/native-audio` plugin instead.
|
|
248
|
+
For Android, there's a need to start monitoring location updates first, otherwise the sound will not play.
|
|
249
|
+
|
|
250
|
+
| Param | Type | Description |
|
|
251
|
+
| ------------- | ------------------------------------------------------------- | --------------------------------- |
|
|
252
|
+
| **`options`** | <code><a href="#playsoundoptions">PlaySoundOptions</a></code> | The options for playing the sound |
|
|
253
|
+
|
|
254
|
+
**Since:** 7.0.10
|
|
255
|
+
|
|
256
|
+
--------------------
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
### Interfaces
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
#### StartOptions
|
|
263
|
+
|
|
264
|
+
The options for configuring for location updates.
|
|
265
|
+
|
|
266
|
+
| Prop | Type | Description | Default | Since |
|
|
267
|
+
| ------------------------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | ----- |
|
|
268
|
+
| **`backgroundMessage`** | <code>string</code> | If the "backgroundMessage" option is defined, the plugin will provide location updates whether the app is in the background or the foreground. If it is not defined, location updates are only guaranteed in the foreground. This is true on both platforms. On Android, a notification must be shown to continue receiving location updates in the background. This option specifies the text of that notification. | | 7.0.9 |
|
|
269
|
+
| **`backgroundTitle`** | <code>string</code> | The title of the notification mentioned above. | <code>"Using your location"</code> | 7.0.9 |
|
|
270
|
+
| **`requestPermissions`** | <code>boolean</code> | Whether permissions should be requested from the user automatically, if they are not already granted. | <code>true</code> | 7.0.9 |
|
|
271
|
+
| **`stale`** | <code>boolean</code> | If "true", stale locations may be delivered while the device obtains a GPS fix. You are responsible for checking the "time" property. If "false", locations are guaranteed to be up to date. | <code>false</code> | 7.0.9 |
|
|
272
|
+
| **`distanceFilter`** | <code>number</code> | The distance in meters that the device must move before a new location update is triggered. This is used to filter out small movements and reduce the number of updates. | <code>0</code> | 7.0.9 |
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
#### Location
|
|
276
|
+
|
|
277
|
+
Represents a geographical location with various attributes.
|
|
278
|
+
Contains all the standard location properties returned by GPS/network providers.
|
|
279
|
+
|
|
280
|
+
| Prop | Type | Description | Since |
|
|
281
|
+
| ---------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----- |
|
|
282
|
+
| **`latitude`** | <code>number</code> | Latitude in degrees. Range: -90.0 to +90.0 | 7.0.0 |
|
|
283
|
+
| **`longitude`** | <code>number</code> | Longitude in degrees. Range: -180.0 to +180.0 | 7.0.0 |
|
|
284
|
+
| **`accuracy`** | <code>number</code> | Radius of horizontal uncertainty in metres, with 68% confidence. Lower values indicate more accurate location. | 7.0.0 |
|
|
285
|
+
| **`altitude`** | <code>number \| null</code> | Metres above sea level (or null if not available). | 7.0.0 |
|
|
286
|
+
| **`altitudeAccuracy`** | <code>number \| null</code> | Vertical uncertainty in metres, with 68% confidence (or null if not available). | 7.0.0 |
|
|
287
|
+
| **`simulated`** | <code>boolean</code> | `true` if the location was simulated by software, rather than GPS. Useful for detecting mock locations in development or testing. | 7.0.0 |
|
|
288
|
+
| **`bearing`** | <code>number \| null</code> | Deviation from true north in degrees (or null if not available). Range: 0.0 to 360.0 | 7.0.0 |
|
|
289
|
+
| **`speed`** | <code>number \| null</code> | Speed in metres per second (or null if not available). | 7.0.0 |
|
|
290
|
+
| **`time`** | <code>number \| null</code> | Time the location was produced, in milliseconds since the unix epoch. Use this to check if a location is stale when using stale: true. | 7.0.0 |
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
#### CallbackError
|
|
294
|
+
|
|
295
|
+
Error object that may be passed to the location start callback.
|
|
296
|
+
Extends the standard Error with optional error codes.
|
|
297
|
+
|
|
298
|
+
| Prop | Type | Description | Since |
|
|
299
|
+
| ---------- | ------------------- | ----------------------------------------------------- | ----- |
|
|
300
|
+
| **`code`** | <code>string</code> | Optional error code for more specific error handling. | 7.0.0 |
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
#### PlaySoundOptions
|
|
304
|
+
|
|
305
|
+
| Prop | Type | Description | Since |
|
|
306
|
+
| --------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
|
|
307
|
+
| **`soundFile`** | <code>string</code> | The name of the sound file to play. Must be a valid sound relative path in the app's public folder to work for both web and native platforms. There's no need to include the public folder in the path. | 7.0.10 |
|
|
308
|
+
|
|
309
|
+
</docgen-api>
|
package/android/src/main/java/com/capgo/capacitor_background_geolocation/BackgroundGeolocation.java
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
package com.capgo.capacitor_background_geolocation;
|
|
2
2
|
|
|
3
3
|
import android.Manifest;
|
|
4
|
-
import android.app.Notification;
|
|
5
4
|
import android.app.NotificationChannel;
|
|
6
5
|
import android.app.NotificationManager;
|
|
7
|
-
import android.app.PendingIntent;
|
|
8
6
|
import android.content.BroadcastReceiver;
|
|
9
7
|
import android.content.ComponentName;
|
|
10
8
|
import android.content.Context;
|
|
11
9
|
import android.content.Intent;
|
|
12
10
|
import android.content.IntentFilter;
|
|
13
11
|
import android.content.ServiceConnection;
|
|
14
|
-
import android.graphics.Color;
|
|
15
12
|
import android.location.Location;
|
|
16
13
|
import android.location.LocationManager;
|
|
17
14
|
import android.net.Uri;
|
|
@@ -68,7 +65,7 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
@PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
|
|
71
|
-
public void
|
|
68
|
+
public void start(final PluginCall call) {
|
|
72
69
|
if (
|
|
73
70
|
getPermissionState("location") != PermissionState.GRANTED &&
|
|
74
71
|
!call.getBoolean("requestPermissions", true)
|
|
@@ -77,6 +74,11 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
77
74
|
return;
|
|
78
75
|
}
|
|
79
76
|
|
|
77
|
+
if (serviceConnectionFuture != null) {
|
|
78
|
+
call.reject("Service already started", "ALREADY_STARTED");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
80
82
|
if (
|
|
81
83
|
getPermissionState("location") != PermissionState.GRANTED &&
|
|
82
84
|
call.getBoolean("requestPermissions", true)
|
|
@@ -84,7 +86,7 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
84
86
|
call.setKeepAlive(true);
|
|
85
87
|
requestLocationPermissions(call)
|
|
86
88
|
.thenRun(() -> {
|
|
87
|
-
|
|
89
|
+
proceedWithStart(call);
|
|
88
90
|
})
|
|
89
91
|
.exceptionally(throwable -> {
|
|
90
92
|
call.reject("User denied location permission", "NOT_AUTHORIZED");
|
|
@@ -101,17 +103,18 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
101
103
|
|
|
102
104
|
// Everything is OK, continuing to adding a watcher
|
|
103
105
|
call.setKeepAlive(true);
|
|
104
|
-
|
|
106
|
+
proceedWithStart(call);
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
private void
|
|
109
|
+
private void proceedWithStart(PluginCall call) {
|
|
108
110
|
if (call.getBoolean("stale", false)) {
|
|
109
111
|
fetchLastLocation(call);
|
|
110
112
|
}
|
|
111
113
|
getServiceConnection().thenAccept(serviceBinder -> {
|
|
112
|
-
serviceBinder.
|
|
114
|
+
serviceBinder.start(
|
|
113
115
|
call.getCallbackId(),
|
|
114
|
-
|
|
116
|
+
call.getString("backgroundTitle", "Using your location"),
|
|
117
|
+
call.getString("backgroundMessage", ""),
|
|
115
118
|
call.getFloat("distanceFilter", 0f)
|
|
116
119
|
);
|
|
117
120
|
});
|
|
@@ -126,67 +129,6 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
126
129
|
return locationPermissionFuture;
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
private Notification createBackgroundNotification(PluginCall call) {
|
|
130
|
-
String backgroundMessage = call.getString("backgroundMessage", "");
|
|
131
|
-
|
|
132
|
-
Notification.Builder builder = new Notification.Builder(getContext())
|
|
133
|
-
.setContentTitle(call.getString("backgroundTitle", "Using your location"))
|
|
134
|
-
.setContentText(backgroundMessage)
|
|
135
|
-
.setOngoing(true)
|
|
136
|
-
.setPriority(Notification.PRIORITY_HIGH)
|
|
137
|
-
.setWhen(System.currentTimeMillis());
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
String name = getAppString(
|
|
141
|
-
"capacitor_background_geolocation_notification_icon",
|
|
142
|
-
"mipmap/ic_launcher"
|
|
143
|
-
);
|
|
144
|
-
String[] parts = name.split("/");
|
|
145
|
-
// It is actually necessary to set a valid icon for the notification to behave
|
|
146
|
-
// correctly when tapped. If there is no icon specified, tapping it will open the
|
|
147
|
-
// app's settings, rather than bringing the application to the foreground.
|
|
148
|
-
builder.setSmallIcon(getAppResourceIdentifier(parts[1], parts[0]));
|
|
149
|
-
} catch (Exception e) {
|
|
150
|
-
Logger.error("Could not set notification icon", e);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
String color = getAppString(
|
|
155
|
-
"capacitor_background_geolocation_notification_color",
|
|
156
|
-
null
|
|
157
|
-
);
|
|
158
|
-
if (color != null) {
|
|
159
|
-
builder.setColor(Color.parseColor(color));
|
|
160
|
-
}
|
|
161
|
-
} catch (Exception e) {
|
|
162
|
-
Logger.error("Could not set notification color", e);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
Intent launchIntent = getContext()
|
|
166
|
-
.getPackageManager()
|
|
167
|
-
.getLaunchIntentForPackage(getContext().getPackageName());
|
|
168
|
-
if (launchIntent != null) {
|
|
169
|
-
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
|
170
|
-
builder.setContentIntent(
|
|
171
|
-
PendingIntent.getActivity(
|
|
172
|
-
getContext(),
|
|
173
|
-
0,
|
|
174
|
-
launchIntent,
|
|
175
|
-
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE
|
|
176
|
-
)
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Set the Channel ID for Android O.
|
|
181
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
182
|
-
builder.setChannelId(
|
|
183
|
-
BackgroundGeolocationService.class.getPackage().getName()
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return builder.build();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
132
|
@PermissionCallback
|
|
191
133
|
private void locationPermissionsCallback(PluginCall call) {
|
|
192
134
|
if (locationPermissionFuture == null) {
|
|
@@ -217,21 +159,19 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
217
159
|
}
|
|
218
160
|
|
|
219
161
|
@PluginMethod
|
|
220
|
-
public void
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
call.reject("Missing id.");
|
|
224
|
-
return;
|
|
162
|
+
public void stop(PluginCall call) {
|
|
163
|
+
if (serviceConnectionFuture == null) {
|
|
164
|
+
call.resolve();
|
|
225
165
|
}
|
|
226
|
-
|
|
227
166
|
getServiceConnection()
|
|
228
167
|
.thenAccept(service -> {
|
|
229
|
-
service.
|
|
168
|
+
var callbackId = service.stop();
|
|
230
169
|
PluginCall savedCall = getBridge().getSavedCall(callbackId);
|
|
231
170
|
if (savedCall != null) {
|
|
232
171
|
savedCall.release(getBridge());
|
|
233
172
|
}
|
|
234
173
|
call.resolve();
|
|
174
|
+
serviceConnectionFuture = null;
|
|
235
175
|
})
|
|
236
176
|
.exceptionally(throwable -> {
|
|
237
177
|
call.reject("Service connection failed: " + throwable.getMessage());
|
|
@@ -248,6 +188,31 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
248
188
|
call.resolve();
|
|
249
189
|
}
|
|
250
190
|
|
|
191
|
+
@PluginMethod
|
|
192
|
+
public void playSound(PluginCall call) {
|
|
193
|
+
String soundFile = call.getString("soundFile");
|
|
194
|
+
if (soundFile == null || soundFile.isEmpty()) {
|
|
195
|
+
call.reject("Sound file is required");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (serviceConnectionFuture == null) {
|
|
199
|
+
call.reject(
|
|
200
|
+
"Service not started, make sure to call start() first",
|
|
201
|
+
"NOT_STARTED"
|
|
202
|
+
);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
serviceConnectionFuture
|
|
206
|
+
.thenAccept(service -> {
|
|
207
|
+
service.playSound(soundFile);
|
|
208
|
+
call.resolve();
|
|
209
|
+
})
|
|
210
|
+
.exceptionally(throwable -> {
|
|
211
|
+
call.reject("Failed to play sound: " + throwable.getMessage());
|
|
212
|
+
return null;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
251
216
|
// Checks if device-wide location services are disabled
|
|
252
217
|
private static Boolean isLocationEnabled(Context context) {
|
|
253
218
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
@@ -321,19 +286,6 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
321
286
|
}
|
|
322
287
|
}
|
|
323
288
|
|
|
324
|
-
// Gets the identifier of the app's resource by name, returning 0 if not found.
|
|
325
|
-
private int getAppResourceIdentifier(String name, String defType) {
|
|
326
|
-
return getContext()
|
|
327
|
-
.getResources()
|
|
328
|
-
.getIdentifier(name, defType, getContext().getPackageName());
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// Gets a string from the app's strings.xml file, resorting to a fallback if it is not defined.
|
|
332
|
-
private String getAppString(String name, String fallback) {
|
|
333
|
-
int id = getAppResourceIdentifier(name, "string");
|
|
334
|
-
return id == 0 ? fallback : getContext().getString(id);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
289
|
@Override
|
|
338
290
|
public void load() {
|
|
339
291
|
super.load();
|
|
@@ -346,9 +298,10 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
346
298
|
);
|
|
347
299
|
NotificationChannel channel = new NotificationChannel(
|
|
348
300
|
BackgroundGeolocationService.class.getPackage().getName(),
|
|
349
|
-
getAppString(
|
|
301
|
+
BackgroundGeolocationService.getAppString(
|
|
350
302
|
"capacitor_background_geolocation_notification_channel_name",
|
|
351
|
-
"Background Tracking"
|
|
303
|
+
"Background Tracking",
|
|
304
|
+
getContext()
|
|
352
305
|
),
|
|
353
306
|
NotificationManager.IMPORTANCE_DEFAULT
|
|
354
307
|
);
|
|
@@ -407,21 +360,11 @@ public class BackgroundGeolocation extends Plugin {
|
|
|
407
360
|
return serviceConnectionFuture;
|
|
408
361
|
}
|
|
409
362
|
|
|
410
|
-
@Override
|
|
411
|
-
protected void handleOnResume() {
|
|
412
|
-
super.handleOnResume();
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
@Override
|
|
416
|
-
protected void handleOnPause() {
|
|
417
|
-
super.handleOnPause();
|
|
418
|
-
}
|
|
419
|
-
|
|
420
363
|
@Override
|
|
421
364
|
protected void handleOnDestroy() {
|
|
422
365
|
if (serviceConnectionFuture != null) {
|
|
423
366
|
serviceConnectionFuture.thenAccept(
|
|
424
|
-
BackgroundGeolocationService.LocalBinder::
|
|
367
|
+
BackgroundGeolocationService.LocalBinder::stop
|
|
425
368
|
);
|
|
426
369
|
}
|
|
427
370
|
|