@azatek/background-geolocation 1.0.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/CapacitorCommunityBackgroundGeolocation.podspec +16 -0
- package/LICENSE +18 -0
- package/Package.swift +29 -0
- package/README.md +242 -0
- package/android/build.gradle +51 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/android/gradle.properties +20 -0
- package/android/proguard-rules.pro +21 -0
- package/android/settings.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +21 -0
- package/android/src/main/java/com/equimaps/capacitor_background_geolocation/BackgroundGeolocation.java +348 -0
- package/android/src/main/java/com/equimaps/capacitor_background_geolocation/BackgroundGeolocationService.java +204 -0
- package/definitions.d.ts +157 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Plugin.h +10 -0
- package/ios/Plugin/Plugin.m +8 -0
- package/ios/Plugin/Swift/Plugin.swift +263 -0
- package/ios/Podfile +16 -0
- package/package.json +56 -0
package/definitions.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location accuracy levels for power management.
|
|
3
|
+
* Higher accuracy = more battery consumption.
|
|
4
|
+
*/
|
|
5
|
+
export enum LocationAccuracy {
|
|
6
|
+
/**
|
|
7
|
+
* Highest accuracy (GPS) - High battery consumption
|
|
8
|
+
* Android: PRIORITY_HIGH_ACCURACY
|
|
9
|
+
* iOS: kCLLocationAccuracyBest
|
|
10
|
+
*/
|
|
11
|
+
HIGH = 100,
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Balanced accuracy (GPS + Network) - Medium battery consumption
|
|
15
|
+
* Android: PRIORITY_BALANCED_POWER_ACCURACY
|
|
16
|
+
* iOS: kCLLocationAccuracyNearestTenMeters
|
|
17
|
+
*/
|
|
18
|
+
BALANCED = 102,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Low accuracy (Network) - Low battery consumption
|
|
22
|
+
* Android: PRIORITY_LOW_POWER
|
|
23
|
+
* iOS: kCLLocationAccuracyHundredMeters
|
|
24
|
+
*/
|
|
25
|
+
LOW = 104,
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Passive updates - Minimal battery consumption
|
|
29
|
+
* Android: PRIORITY_PASSIVE
|
|
30
|
+
* iOS: kCLLocationAccuracyThreeKilometers
|
|
31
|
+
*/
|
|
32
|
+
PASSIVE = 105
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The options for configuring a watcher that listens for location updates.
|
|
37
|
+
*/
|
|
38
|
+
export interface WatcherOptions {
|
|
39
|
+
/**
|
|
40
|
+
* If the "backgroundMessage" option is defined, the watcher will
|
|
41
|
+
* provide location updates whether the app is in the background or the
|
|
42
|
+
* foreground. If it is not defined, location updates are only
|
|
43
|
+
* guaranteed in the foreground. This is true on both platforms.
|
|
44
|
+
*
|
|
45
|
+
* On Android, a notification must be shown to continue receiving
|
|
46
|
+
* location updates in the background. This option specifies the text of
|
|
47
|
+
* that notification.
|
|
48
|
+
*/
|
|
49
|
+
backgroundMessage?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The title of the notification mentioned above.
|
|
52
|
+
* @default "Using your location"
|
|
53
|
+
*/
|
|
54
|
+
backgroundTitle?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Whether permissions should be requested from the user automatically,
|
|
57
|
+
* if they are not already granted.
|
|
58
|
+
* @default true
|
|
59
|
+
*/
|
|
60
|
+
requestPermissions?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* If "true", stale locations may be delivered while the device
|
|
63
|
+
* obtains a GPS fix. You are responsible for checking the "time"
|
|
64
|
+
* property. If "false", locations are guaranteed to be up to date.
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
stale?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* The distance in meters that the device must move before a new location update is triggered.
|
|
70
|
+
* This is used to filter out small movements and reduce the number of updates.
|
|
71
|
+
* @default 0
|
|
72
|
+
*/
|
|
73
|
+
distanceFilter?: number;
|
|
74
|
+
/**
|
|
75
|
+
* The desired accuracy level for location updates.
|
|
76
|
+
* Higher accuracy levels consume more battery power.
|
|
77
|
+
* @default LocationAccuracy.BALANCED
|
|
78
|
+
*/
|
|
79
|
+
accuracy?: LocationAccuracy;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Represents a geographical location with various attributes.
|
|
84
|
+
*/
|
|
85
|
+
export interface Location {
|
|
86
|
+
/**
|
|
87
|
+
* Longitude in degrees.
|
|
88
|
+
*/
|
|
89
|
+
latitude: number;
|
|
90
|
+
/**
|
|
91
|
+
* Latitude in degrees.
|
|
92
|
+
*/
|
|
93
|
+
longitude: number;
|
|
94
|
+
/**
|
|
95
|
+
* Radius of horizontal uncertainty in metres, with 68% confidence.
|
|
96
|
+
*/
|
|
97
|
+
accuracy: number;
|
|
98
|
+
/**
|
|
99
|
+
* Metres above sea level (or null).
|
|
100
|
+
*/
|
|
101
|
+
altitude: number | null;
|
|
102
|
+
/**
|
|
103
|
+
* Vertical uncertainty in metres, with 68% confidence (or null).
|
|
104
|
+
*/
|
|
105
|
+
altitudeAccuracy: number | null;
|
|
106
|
+
/**
|
|
107
|
+
* `true` if the location was simulated by software, rather than GPS.
|
|
108
|
+
*/
|
|
109
|
+
simulated: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Deviation from true north in degrees (or null).
|
|
112
|
+
*/
|
|
113
|
+
bearing: number | null;
|
|
114
|
+
/**
|
|
115
|
+
* Speed in metres per second (or null).
|
|
116
|
+
*/
|
|
117
|
+
speed: number | null;
|
|
118
|
+
/**
|
|
119
|
+
* Time the location was produced, in milliseconds since the unix epoch.
|
|
120
|
+
*/
|
|
121
|
+
time: number | null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface CallbackError extends Error {
|
|
125
|
+
code?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface BackgroundGeolocationPlugin {
|
|
129
|
+
/**
|
|
130
|
+
* Adds a watcher for location updates.
|
|
131
|
+
* The watcher will be invoked with the latest location whenever it is available.
|
|
132
|
+
* If an error occurs, the callback will be invoked with the error.
|
|
133
|
+
*
|
|
134
|
+
* @param options the watcher options
|
|
135
|
+
* @param callback the callback to be invoked when a new location is available or an error occurs
|
|
136
|
+
* @returns a promise that resolves to a unique identifier for the watcher ID
|
|
137
|
+
*/
|
|
138
|
+
addWatcher(
|
|
139
|
+
options: WatcherOptions,
|
|
140
|
+
callback: (
|
|
141
|
+
position?: Location,
|
|
142
|
+
error?: CallbackError
|
|
143
|
+
) => void
|
|
144
|
+
): Promise<string>;
|
|
145
|
+
/**
|
|
146
|
+
* Removes a watcher by its unique identifier.
|
|
147
|
+
* @param options the options for removing the watcher
|
|
148
|
+
* @returns a promise that resolves when the watcher is successfully removed
|
|
149
|
+
*/
|
|
150
|
+
removeWatcher(options: {
|
|
151
|
+
id: string
|
|
152
|
+
}): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Opens the settings page of the app.
|
|
155
|
+
*/
|
|
156
|
+
openSettings(): Promise<void>;
|
|
157
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>FMWK</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
21
|
+
<key>NSPrincipalClass</key>
|
|
22
|
+
<string></string>
|
|
23
|
+
</dict>
|
|
24
|
+
</plist>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
//! Project version number for Plugin.
|
|
4
|
+
FOUNDATION_EXPORT double PluginVersionNumber;
|
|
5
|
+
|
|
6
|
+
//! Project version string for Plugin.
|
|
7
|
+
FOUNDATION_EXPORT const unsigned char PluginVersionString[];
|
|
8
|
+
|
|
9
|
+
// In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>
|
|
10
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <Capacitor/Capacitor.h>
|
|
3
|
+
|
|
4
|
+
CAP_PLUGIN(BackgroundGeolocation, "BackgroundGeolocation",
|
|
5
|
+
CAP_PLUGIN_METHOD(addWatcher, CAPPluginReturnCallback);
|
|
6
|
+
CAP_PLUGIN_METHOD(removeWatcher, CAPPluginReturnPromise);
|
|
7
|
+
CAP_PLUGIN_METHOD(openSettings, CAPPluginReturnPromise);
|
|
8
|
+
)
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import Capacitor
|
|
2
|
+
import Foundation
|
|
3
|
+
import UIKit
|
|
4
|
+
import CoreLocation
|
|
5
|
+
|
|
6
|
+
// Avoids a bewildering type warning.
|
|
7
|
+
let null = Optional<Double>.none as Any
|
|
8
|
+
|
|
9
|
+
func formatLocation(_ location: CLLocation) -> PluginCallResultData {
|
|
10
|
+
var simulated = false;
|
|
11
|
+
if #available(iOS 15, *) {
|
|
12
|
+
// Prior to iOS 15, it was not possible to detect simulated locations.
|
|
13
|
+
// But in general, it is very difficult to simulate locations on iOS in
|
|
14
|
+
// production.
|
|
15
|
+
if location.sourceInformation != nil {
|
|
16
|
+
simulated = location.sourceInformation!.isSimulatedBySoftware;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return [
|
|
20
|
+
"latitude": location.coordinate.latitude,
|
|
21
|
+
"longitude": location.coordinate.longitude,
|
|
22
|
+
"accuracy": location.horizontalAccuracy,
|
|
23
|
+
"altitude": location.altitude,
|
|
24
|
+
"altitudeAccuracy": location.verticalAccuracy,
|
|
25
|
+
"simulated": simulated,
|
|
26
|
+
"speed": location.speed < 0 ? null : location.speed,
|
|
27
|
+
"bearing": location.course < 0 ? null : location.course,
|
|
28
|
+
"time": NSNumber(
|
|
29
|
+
value: Int(
|
|
30
|
+
location.timestamp.timeIntervalSince1970 * 1000
|
|
31
|
+
)
|
|
32
|
+
),
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class Watcher {
|
|
37
|
+
let callbackId: String
|
|
38
|
+
let locationManager: CLLocationManager = CLLocationManager()
|
|
39
|
+
private let created = Date()
|
|
40
|
+
private let allowStale: Bool
|
|
41
|
+
private var isUpdatingLocation: Bool = false
|
|
42
|
+
init(_ id: String, stale: Bool) {
|
|
43
|
+
callbackId = id
|
|
44
|
+
allowStale = stale
|
|
45
|
+
}
|
|
46
|
+
func start() {
|
|
47
|
+
// Avoid unnecessary calls to startUpdatingLocation, which can
|
|
48
|
+
// result in extraneous invocations of didFailWithError.
|
|
49
|
+
if !isUpdatingLocation {
|
|
50
|
+
locationManager.startUpdatingLocation()
|
|
51
|
+
isUpdatingLocation = true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
func stop() {
|
|
55
|
+
if isUpdatingLocation {
|
|
56
|
+
locationManager.stopUpdatingLocation()
|
|
57
|
+
isUpdatingLocation = false
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
func isLocationValid(_ location: CLLocation) -> Bool {
|
|
61
|
+
return (
|
|
62
|
+
allowStale ||
|
|
63
|
+
location.timestamp >= created
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@objc(BackgroundGeolocation)
|
|
69
|
+
public class BackgroundGeolocation: CAPPlugin,
|
|
70
|
+
CAPBridgedPlugin,
|
|
71
|
+
CLLocationManagerDelegate {
|
|
72
|
+
private var watchers = [Watcher]()
|
|
73
|
+
public let identifier = "BackgroundGeolocation"
|
|
74
|
+
public let jsName = "BackgroundGeolocation"
|
|
75
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
76
|
+
CAPPluginMethod(name: "addWatcher", returnType: CAPPluginReturnCallback),
|
|
77
|
+
CAPPluginMethod(name: "removeWatcher", returnType: CAPPluginReturnPromise),
|
|
78
|
+
CAPPluginMethod(name: "openSettings", returnType: CAPPluginReturnPromise)
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
@objc public override func load() {
|
|
82
|
+
UIDevice.current.isBatteryMonitoringEnabled = true
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@objc func addWatcher(_ call: CAPPluginCall) {
|
|
86
|
+
call.keepAlive = true
|
|
87
|
+
|
|
88
|
+
// CLLocationManager requires main thread
|
|
89
|
+
DispatchQueue.main.async {
|
|
90
|
+
let background = call.getString("backgroundMessage") != nil
|
|
91
|
+
let watcher = Watcher(
|
|
92
|
+
call.callbackId,
|
|
93
|
+
stale: call.getBool("stale") ?? false
|
|
94
|
+
)
|
|
95
|
+
let manager = watcher.locationManager
|
|
96
|
+
manager.delegate = self
|
|
97
|
+
|
|
98
|
+
// Configure accuracy based on parameter (default: BALANCED = 102)
|
|
99
|
+
let accuracy = call.getInt("accuracy") ?? 102
|
|
100
|
+
|
|
101
|
+
switch accuracy {
|
|
102
|
+
case 100: // HIGH
|
|
103
|
+
let isCharging = [
|
|
104
|
+
.charging,
|
|
105
|
+
.full
|
|
106
|
+
].contains(UIDevice.current.batteryState)
|
|
107
|
+
|
|
108
|
+
if isCharging {
|
|
109
|
+
manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
|
|
110
|
+
} else {
|
|
111
|
+
manager.desiredAccuracy = kCLLocationAccuracyBest
|
|
112
|
+
}
|
|
113
|
+
manager.activityType = .otherNavigation
|
|
114
|
+
case 102: // BALANCED (Default)
|
|
115
|
+
manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
|
116
|
+
manager.activityType = .other
|
|
117
|
+
case 104: // LOW
|
|
118
|
+
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
|
119
|
+
manager.activityType = .other
|
|
120
|
+
case 105: // PASSIVE
|
|
121
|
+
manager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
|
|
122
|
+
manager.activityType = .other
|
|
123
|
+
default:
|
|
124
|
+
manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
|
125
|
+
manager.activityType = .other
|
|
126
|
+
}
|
|
127
|
+
var distanceFilter = call.getDouble("distanceFilter")
|
|
128
|
+
// It appears that setting manager.distanceFilter to 0 can prevent
|
|
129
|
+
// subsequent location updates. See issue #88.
|
|
130
|
+
if distanceFilter == nil || distanceFilter == 0 {
|
|
131
|
+
distanceFilter = kCLDistanceFilterNone
|
|
132
|
+
}
|
|
133
|
+
manager.distanceFilter = distanceFilter!
|
|
134
|
+
manager.allowsBackgroundLocationUpdates = background
|
|
135
|
+
manager.showsBackgroundLocationIndicator = background
|
|
136
|
+
manager.pausesLocationUpdatesAutomatically = false
|
|
137
|
+
self.watchers.append(watcher)
|
|
138
|
+
if call.getBool("requestPermissions") != false {
|
|
139
|
+
let status = CLLocationManager.authorizationStatus()
|
|
140
|
+
if [
|
|
141
|
+
.notDetermined,
|
|
142
|
+
.denied,
|
|
143
|
+
.restricted,
|
|
144
|
+
].contains(status) {
|
|
145
|
+
return (
|
|
146
|
+
background
|
|
147
|
+
? manager.requestAlwaysAuthorization()
|
|
148
|
+
: manager.requestWhenInUseAuthorization()
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
if (
|
|
152
|
+
background && status == .authorizedWhenInUse
|
|
153
|
+
) {
|
|
154
|
+
// Attempt to escalate.
|
|
155
|
+
manager.requestAlwaysAuthorization()
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return watcher.start()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@objc func removeWatcher(_ call: CAPPluginCall) {
|
|
163
|
+
// CLLocationManager requires main thread
|
|
164
|
+
DispatchQueue.main.async {
|
|
165
|
+
if let callbackId = call.getString("id") {
|
|
166
|
+
if let index = self.watchers.firstIndex(
|
|
167
|
+
where: { $0.callbackId == callbackId }
|
|
168
|
+
) {
|
|
169
|
+
self.watchers[index].locationManager.stopUpdatingLocation()
|
|
170
|
+
self.watchers.remove(at: index)
|
|
171
|
+
}
|
|
172
|
+
if let savedCall = self.bridge?.savedCall(withID: callbackId) {
|
|
173
|
+
self.bridge?.releaseCall(savedCall)
|
|
174
|
+
}
|
|
175
|
+
return call.resolve()
|
|
176
|
+
}
|
|
177
|
+
return call.reject("No callback ID")
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@objc func openSettings(_ call: CAPPluginCall) {
|
|
182
|
+
DispatchQueue.main.async {
|
|
183
|
+
guard let settingsUrl = URL(
|
|
184
|
+
string: UIApplication.openSettingsURLString
|
|
185
|
+
) else {
|
|
186
|
+
return call.reject("No link to settings available")
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if UIApplication.shared.canOpenURL(settingsUrl) {
|
|
190
|
+
UIApplication.shared.open(settingsUrl, completionHandler: {
|
|
191
|
+
(success) in
|
|
192
|
+
if (success) {
|
|
193
|
+
return call.resolve()
|
|
194
|
+
} else {
|
|
195
|
+
return call.reject("Failed to open settings")
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
} else {
|
|
199
|
+
return call.reject("Cannot open settings")
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public func locationManager(
|
|
205
|
+
_ manager: CLLocationManager,
|
|
206
|
+
didFailWithError error: Error
|
|
207
|
+
) {
|
|
208
|
+
if let watcher = self.watchers.first(
|
|
209
|
+
where: { $0.locationManager == manager }
|
|
210
|
+
) {
|
|
211
|
+
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
|
|
212
|
+
if let clErr = error as? CLError {
|
|
213
|
+
if clErr.code == .locationUnknown {
|
|
214
|
+
// This error is sometimes sent by the manager if
|
|
215
|
+
// it cannot get a fix immediately.
|
|
216
|
+
return
|
|
217
|
+
} else if (clErr.code == .denied) {
|
|
218
|
+
watcher.stop()
|
|
219
|
+
return call.reject(
|
|
220
|
+
"Permission denied.",
|
|
221
|
+
"NOT_AUTHORIZED"
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return call.reject(error.localizedDescription, nil, error)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
public func locationManager(
|
|
231
|
+
_ manager: CLLocationManager,
|
|
232
|
+
didUpdateLocations locations: [CLLocation]
|
|
233
|
+
) {
|
|
234
|
+
if let location = locations.last {
|
|
235
|
+
if let watcher = self.watchers.first(
|
|
236
|
+
where: { $0.locationManager == manager }
|
|
237
|
+
) {
|
|
238
|
+
if watcher.isLocationValid(location) {
|
|
239
|
+
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
|
|
240
|
+
return call.resolve(formatLocation(location))
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
public func locationManager(
|
|
248
|
+
_ manager: CLLocationManager,
|
|
249
|
+
didChangeAuthorization status: CLAuthorizationStatus
|
|
250
|
+
) {
|
|
251
|
+
// If this method is called before the user decides on a permission, as
|
|
252
|
+
// it is on iOS 14 when the permissions dialog is presented, we ignore
|
|
253
|
+
// it.
|
|
254
|
+
if status != .notDetermined {
|
|
255
|
+
if let watcher = self.watchers.first(
|
|
256
|
+
where: { $0.locationManager == manager }
|
|
257
|
+
) {
|
|
258
|
+
return watcher.start()
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
package/ios/Podfile
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
platform :ios, '12.0'
|
|
2
|
+
|
|
3
|
+
def capacitor_pods
|
|
4
|
+
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
|
|
5
|
+
use_frameworks!
|
|
6
|
+
pod 'Capacitor', :path => '../node_modules/@capacitor/ios'
|
|
7
|
+
pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
target 'Plugin' do
|
|
11
|
+
capacitor_pods
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
target 'PluginTests' do
|
|
15
|
+
capacitor_pods
|
|
16
|
+
end
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@azatek/background-geolocation",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Capacitor plugin for background geolocation tracking with configurable GPS accuracy modes (HIGH/BALANCED/LOW/PASSIVE) for battery optimization. Fork of @capacitor-community/background-geolocation with enhanced accuracy control.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"capacitor",
|
|
7
|
+
"plugin",
|
|
8
|
+
"geolocation",
|
|
9
|
+
"background",
|
|
10
|
+
"gps",
|
|
11
|
+
"location",
|
|
12
|
+
"tracking",
|
|
13
|
+
"accuracy",
|
|
14
|
+
"battery-optimization",
|
|
15
|
+
"android",
|
|
16
|
+
"ios"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/AzaTek61/background-geolocation.git"
|
|
21
|
+
},
|
|
22
|
+
"author": "AzaTek",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"types": "definitions.d.ts",
|
|
25
|
+
"files": [
|
|
26
|
+
"CapacitorCommunityBackgroundGeolocation.podspec",
|
|
27
|
+
"Package.swift",
|
|
28
|
+
"android/build.gradle",
|
|
29
|
+
"android/gradle.properties",
|
|
30
|
+
"android/gradle/wrapper/gradle-wrapper.properties",
|
|
31
|
+
"android/proguard-rules.pro",
|
|
32
|
+
"android/settings.gradle",
|
|
33
|
+
"android/src/main/",
|
|
34
|
+
"definitions.d.ts",
|
|
35
|
+
"ios/Plugin/Info.plist",
|
|
36
|
+
"ios/Plugin/Plugin.*",
|
|
37
|
+
"ios/Plugin/Swift/Plugin.swift",
|
|
38
|
+
"ios/Podfile*"
|
|
39
|
+
],
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@capacitor/android": "^7.0.0",
|
|
42
|
+
"@capacitor/core": "^7.0.0",
|
|
43
|
+
"@capacitor/ios": "^7.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@capacitor/core": ">=3.0.0"
|
|
47
|
+
},
|
|
48
|
+
"capacitor": {
|
|
49
|
+
"ios": {
|
|
50
|
+
"src": "ios"
|
|
51
|
+
},
|
|
52
|
+
"android": {
|
|
53
|
+
"src": "android"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|