@josuelmm/cordova-background-geolocation 3.0.0 → 3.0.1
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
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.0.1](https://github.com/josuelmm/cordova-background-geolocation/tree/3.0.1) (2026-02-21)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Android (API 34+):** Foreground service type mismatch crash (`IllegalArgumentException: foregroundServiceType 0x00000004 is not a subset of ...`). The type passed to `startForeground()` now matches the merged app manifest:
|
|
8
|
+
- Read `foregroundServiceType` from the running service’s manifest at runtime and pass that value to `startForeground()` (so it works whether the merged manifest is `location`, `location|dataSync`, or overridden by the app to another type).
|
|
9
|
+
- On API 33+, use `getServiceInfo(ComponentName, ComponentInfoFlags)` (via reflection) instead of the deprecated `getServiceInfo(component, int)`, which could return an incomplete `ServiceInfo` and force an incorrect fallback to 4 (location) while the system validated against the real manifest (e.g. 0x9).
|
|
10
|
+
- Use `getClass()` for `ComponentName` so the manifest read corresponds to the actual running service instance.
|
|
11
|
+
- Debug log before `startForeground`: `startForeground serviceType=0x…` in logcat to confirm the type used.
|
|
12
|
+
- **Android:** Avoid starting the foreground service when location permission is not granted: check in `LocationServiceImpl.startForeground()`, and in `BootCompletedReceiver` / `LocationServiceProxy` before calling `startForegroundService()` to prevent `SecurityException` and `ForegroundServiceDidNotStartInTimeException` when the app has no location permission at boot or when starting from background.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **Android:** Plugin manifests now declare the service with `foregroundServiceType`: `plugin.xml` uses `location|dataSync`; `android/common/AndroidManifest.xml` uses `location`.
|
|
17
|
+
- **Angular:** Wrapper is built with **ng-packagr** (Ivy/AOT) so the service works in production without requiring the JIT compiler (fixes “The injectable 'BackgroundGeolocationService' needs to be compiled using the JIT compiler” when `@angular/compiler` is not available). Entry point is `angular/public-api.ts`; package exports point to `angular/dist/`.
|
|
18
|
+
- **Angular:** Removed redundant files: `angular/index.ts`, `angular/tsconfig.lib.json`, and legacy tsc output (root-level `*.js` / `*.d.ts` in `angular/`). Only the ng-packagr build in `angular/dist/` is used.
|
|
19
|
+
- **README:** New section *“Android: configuring your app (recommended)”*: how to force `foregroundServiceType="location"` in the app’s AndroidManifest with `tools:replace`, optionally disable `BootCompletedReceiver` at boot, and required `strings.xml` entries for the plugin’s sync account (`plugin_bgloc_account_name`, `plugin_bgloc_account_type`, `plugin_bgloc_content_authority`).
|
|
20
|
+
- **package-lock.json:** Kept in sync with `package.json` (e.g. zone.js) so `npm ci` succeeds in CI.
|
|
21
|
+
|
|
22
|
+
[Full Changelog](https://github.com/josuelmm/cordova-background-geolocation/compare/3.0.0...3.0.1)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
3
26
|
## [3.0.0](https://github.com/josuelmm/cordova-background-geolocation/tree/3.0.0) (2026-02-20)
|
|
4
27
|
|
|
5
28
|
### Added
|
package/README.md
CHANGED
|
@@ -63,6 +63,40 @@ cordova plugin add @josuelmm/cordova-background-geolocation \
|
|
|
63
63
|
- **Android 13+:** Request runtime `POST_NOTIFICATION` permission if you want the tracking notification to show.
|
|
64
64
|
- After changing plugin options, remove and reinstall the plugin for changes to take effect.
|
|
65
65
|
|
|
66
|
+
### Android: configuring your app (recommended)
|
|
67
|
+
|
|
68
|
+
If your app’s merged manifest ends up with a `foregroundServiceType` other than `location` (e.g. due to other libraries or templates), you may see *"foregroundServiceType 0x00000004 is not a subset of ..."* and the tracking notification may not show. To **force** the correct type and avoid starting the service at boot without permissions, add the following in **your** Android project (the app that consumes the plugin).
|
|
69
|
+
|
|
70
|
+
**1. AndroidManifest.xml** (inside `<application>`, and add `xmlns:tools="http://schemas.android.com/tools"` on the root `<manifest>` if not already present):
|
|
71
|
+
|
|
72
|
+
```xml
|
|
73
|
+
<!-- Background Location Service: force foregroundServiceType="location" in the merged manifest -->
|
|
74
|
+
<service
|
|
75
|
+
android:name="com.marianhello.bgloc.service.LocationServiceImpl"
|
|
76
|
+
android:exported="false"
|
|
77
|
+
android:foregroundServiceType="location"
|
|
78
|
+
tools:replace="android:foregroundServiceType" />
|
|
79
|
+
|
|
80
|
+
<!-- Optional: disable start on boot to avoid ForegroundServiceDidNotStartInTimeException when location permission is not granted -->
|
|
81
|
+
<receiver
|
|
82
|
+
android:name="com.marianhello.bgloc.BootCompletedReceiver"
|
|
83
|
+
android:enabled="false"
|
|
84
|
+
tools:replace="android:enabled" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`tools:replace="android:foregroundServiceType"` makes the merged manifest use your `location` value instead of whatever another dependency might declare, so the type matches what the plugin uses in `startForeground()`.
|
|
88
|
+
|
|
89
|
+
**2. res/values/strings.xml** (required by the plugin for the sync account; replace `site.seelight.client` with your app’s package or identifier if different):
|
|
90
|
+
|
|
91
|
+
```xml
|
|
92
|
+
<!-- Required by cordova-background-geolocation-plugin (sync account) -->
|
|
93
|
+
<string name="plugin_bgloc_account_name">Background location</string>
|
|
94
|
+
<string name="plugin_bgloc_account_type">site.seelight.client.bgloc.account</string>
|
|
95
|
+
<string name="plugin_bgloc_content_authority">site.seelight.client.bgloc</string>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This makes your app enforce the correct foreground service type and defines the strings the plugin needs for the sync account.
|
|
99
|
+
|
|
66
100
|
---
|
|
67
101
|
|
|
68
102
|
## Usage (with or without Angular)
|
|
@@ -45,7 +45,11 @@
|
|
|
45
45
|
android:authorities="@string/plugin_bgloc_content_authority"
|
|
46
46
|
android:exported="false"
|
|
47
47
|
android:syncable="true"/>
|
|
48
|
-
<service
|
|
48
|
+
<service
|
|
49
|
+
android:enabled="true"
|
|
50
|
+
android:exported="false"
|
|
51
|
+
android:name="com.marianhello.bgloc.service.LocationServiceImpl"
|
|
52
|
+
android:foregroundServiceType="location" />
|
|
49
53
|
<receiver android:enabled="true" android:exported="true" android:name="com.marianhello.bgloc.BootCompletedReceiver">
|
|
50
54
|
<intent-filter>
|
|
51
55
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
@@ -18,7 +18,9 @@ import android.content.ContentResolver;
|
|
|
18
18
|
import android.content.Context;
|
|
19
19
|
import android.content.Intent;
|
|
20
20
|
import android.content.IntentFilter;
|
|
21
|
+
import android.content.ComponentName;
|
|
21
22
|
import android.content.pm.PackageManager;
|
|
23
|
+
import android.content.pm.ServiceInfo;
|
|
22
24
|
import android.Manifest;
|
|
23
25
|
import android.net.ConnectivityManager;
|
|
24
26
|
import android.net.NetworkInfo;
|
|
@@ -475,6 +477,61 @@ public class LocationServiceImpl extends Service implements ProviderDelegate, Lo
|
|
|
475
477
|
|| checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
|
476
478
|
}
|
|
477
479
|
|
|
480
|
+
/** FOREGROUND_SERVICE_TYPE_LOCATION = 4 when compileSdk >= 34. */
|
|
481
|
+
private static final int FOREGROUND_SERVICE_TYPE_LOCATION = 4;
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Reads this service's foregroundServiceType from the merged AndroidManifest (API 34+).
|
|
485
|
+
* The type passed to startForeground() must be a subset of the value declared in the manifest.
|
|
486
|
+
* On API 33+ we use getServiceInfo(ComponentName, ComponentInfoFlags) because the deprecated
|
|
487
|
+
* getServiceInfo(component, int) can return an incomplete ServiceInfo (foregroundServiceType=0),
|
|
488
|
+
* which would make us fall back to 4 while the system validates against the real manifest (e.g. 0x9) and crash.
|
|
489
|
+
*/
|
|
490
|
+
private int getForegroundServiceTypeFromManifest() {
|
|
491
|
+
if (Build.VERSION.SDK_INT < 34) {
|
|
492
|
+
return FOREGROUND_SERVICE_TYPE_LOCATION;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
ComponentName component = new ComponentName(this, getClass());
|
|
496
|
+
ServiceInfo info = getServiceInfoApi33Plus(component);
|
|
497
|
+
if (info != null) {
|
|
498
|
+
int type = getForegroundServiceTypeFromServiceInfo(info);
|
|
499
|
+
if (type != 0) return type;
|
|
500
|
+
}
|
|
501
|
+
} catch (Throwable e) {
|
|
502
|
+
logger.warn("Could not read foregroundServiceType from manifest: {}", e.getMessage());
|
|
503
|
+
}
|
|
504
|
+
return FOREGROUND_SERVICE_TYPE_LOCATION;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** Calls getServiceInfo with ComponentInfoFlags on API 33+ so the result includes foregroundServiceType. */
|
|
508
|
+
private ServiceInfo getServiceInfoApi33Plus(ComponentName component) throws Exception {
|
|
509
|
+
if (Build.VERSION.SDK_INT < 33) {
|
|
510
|
+
return getPackageManager().getServiceInfo(component, PackageManager.GET_META_DATA);
|
|
511
|
+
}
|
|
512
|
+
// API 33+: use ComponentInfoFlags so getServiceInfo returns complete ServiceInfo (avoid deprecated int overload).
|
|
513
|
+
Class<?> flagsClass = Class.forName("android.content.pm.PackageManager$ComponentInfoFlags");
|
|
514
|
+
java.lang.reflect.Method ofMethod = flagsClass.getMethod("of", long.class);
|
|
515
|
+
Object flags = ofMethod.invoke(null, (long) PackageManager.GET_META_DATA);
|
|
516
|
+
java.lang.reflect.Method getServiceInfoMethod = getPackageManager().getClass().getMethod("getServiceInfo", ComponentName.class, flagsClass);
|
|
517
|
+
return (ServiceInfo) getServiceInfoMethod.invoke(getPackageManager(), component, flags);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Reads foregroundServiceType from ServiceInfo (API 34 field; use reflection to compile with any compileSdk). */
|
|
521
|
+
private int getForegroundServiceTypeFromServiceInfo(ServiceInfo info) {
|
|
522
|
+
try {
|
|
523
|
+
java.lang.reflect.Field f = ServiceInfo.class.getField("foregroundServiceType");
|
|
524
|
+
Object v = f.get(info);
|
|
525
|
+
if (v instanceof Integer) {
|
|
526
|
+
int type = (Integer) v;
|
|
527
|
+
if (type != 0) return type;
|
|
528
|
+
}
|
|
529
|
+
} catch (Throwable ignored) {
|
|
530
|
+
// field not present on older compileSdk / runtime
|
|
531
|
+
}
|
|
532
|
+
return 0;
|
|
533
|
+
}
|
|
534
|
+
|
|
478
535
|
@Override
|
|
479
536
|
public void startForeground() {
|
|
480
537
|
if (sIsRunning && !mIsInForeground) {
|
|
@@ -494,10 +551,12 @@ public class LocationServiceImpl extends Service implements ProviderDelegate, Lo
|
|
|
494
551
|
mProvider.onCommand(LocationProvider.CMD_SWITCH_MODE,
|
|
495
552
|
LocationProvider.FOREGROUND_MODE);
|
|
496
553
|
}
|
|
497
|
-
// Android 14+ (API 34)
|
|
498
|
-
//
|
|
554
|
+
// Android 14+ (API 34): type passed to startForeground() must match the service's
|
|
555
|
+
// foregroundServiceType in the merged manifest (e.g. "location"=4 or "dataSync|specialUse"=0x9).
|
|
499
556
|
if (Build.VERSION.SDK_INT >= 34) {
|
|
500
|
-
|
|
557
|
+
int serviceType = getForegroundServiceTypeFromManifest();
|
|
558
|
+
logger.info("startForeground serviceType=0x{}", Integer.toHexString(serviceType));
|
|
559
|
+
super.startForeground(NOTIFICATION_ID, notification, serviceType);
|
|
501
560
|
} else {
|
|
502
561
|
super.startForeground(NOTIFICATION_ID, notification);
|
|
503
562
|
}
|
package/package.json
CHANGED
package/plugin.xml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
|
|
3
3
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
4
|
id="cordova-background-geolocation"
|
|
5
|
-
version="3.0.
|
|
5
|
+
version="3.0.1">
|
|
6
6
|
<name>cordova-background-geolocation</name>
|
|
7
7
|
<description>Cordova Background Geolocation Plugin</description>
|
|
8
8
|
<license>Apache-2.0</license>
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
android:enabled="true"
|
|
158
158
|
android:exported="false"
|
|
159
159
|
android:name="com.marianhello.bgloc.service.LocationServiceImpl"
|
|
160
|
-
android:foregroundServiceType="location"
|
|
160
|
+
android:foregroundServiceType="location|dataSync"
|
|
161
161
|
/>
|
|
162
162
|
<receiver
|
|
163
163
|
android:name="com.marianhello.bgloc.BootCompletedReceiver"
|
|
@@ -184,6 +184,7 @@
|
|
|
184
184
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
185
185
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
186
186
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
187
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
|
187
188
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
188
189
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
189
190
|
<uses-permission android:name="android.hardware.location" />
|