@capgo/capacitor-ibeacon 8.1.2 → 8.1.4
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/Package.swift +1 -1
- package/README.md +28 -0
- package/android/src/main/java/ee/forgr/plugin/capacitor_ibeacon/CapacitorIbeaconPlugin.java +94 -39
- package/dist/docs.json +7 -0
- package/dist/esm/definitions.d.ts +5 -0
- package/ios/Sources/CapacitorIbeaconPlugin/CapacitorIbeaconPlugin.swift +1 -1
- package/package.json +1 -1
package/Package.swift
CHANGED
|
@@ -10,7 +10,7 @@ let package = Package(
|
|
|
10
10
|
targets: ["CapacitorIbeaconPlugin"])
|
|
11
11
|
],
|
|
12
12
|
dependencies: [
|
|
13
|
-
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
|
|
14
14
|
],
|
|
15
15
|
targets: [
|
|
16
16
|
.target(
|
package/README.md
CHANGED
|
@@ -194,6 +194,34 @@ Enable ARMA filtering for distance calculations (Android only).
|
|
|
194
194
|
await CapacitorIbeacon.enableARMAFilter({ enabled: true });
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
+
### Android background scanning
|
|
198
|
+
|
|
199
|
+
Android 8+ requires a foreground service to keep Bluetooth scanning alive in the background. You can opt in once and the plugin will automatically
|
|
200
|
+
toggle background scanning when the app moves between foreground and background.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Enable background scanning globally (Android only)
|
|
204
|
+
await CapacitorIbeacon.enableBackgroundMode({ enabled: true });
|
|
205
|
+
|
|
206
|
+
// Or opt in per call
|
|
207
|
+
await CapacitorIbeacon.startMonitoringForRegion({
|
|
208
|
+
identifier: 'MyBeaconRegion',
|
|
209
|
+
uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D',
|
|
210
|
+
enableBackgroundMode: true,
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
You can also enable it via Capacitor config:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// capacitor.config.ts
|
|
218
|
+
plugins: {
|
|
219
|
+
CapacitorIbeacon: {
|
|
220
|
+
enableBackgroundMode: true,
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
197
225
|
## Events
|
|
198
226
|
|
|
199
227
|
Listen to beacon events using Capacitor's event system:
|
|
@@ -43,11 +43,16 @@ import org.altbeacon.beacon.Region;
|
|
|
43
43
|
)
|
|
44
44
|
public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
45
45
|
|
|
46
|
-
private final String pluginVersion = "8.1.
|
|
46
|
+
private final String pluginVersion = "8.1.4";
|
|
47
|
+
private static final String FOREGROUND_CHANNEL_ID = "beacon_service_channel";
|
|
48
|
+
private static final int FOREGROUND_NOTIFICATION_ID = 456;
|
|
47
49
|
private BeaconManager beaconManager;
|
|
48
50
|
private Map<String, Region> monitoredRegions = new HashMap<>();
|
|
49
51
|
private Map<String, Region> rangedRegions = new HashMap<>();
|
|
50
52
|
private boolean beaconManagerBound = false;
|
|
53
|
+
private boolean backgroundModeEnabled = false;
|
|
54
|
+
private boolean foregroundServiceEnabled = false;
|
|
55
|
+
private boolean isInBackground = false;
|
|
51
56
|
|
|
52
57
|
@Override
|
|
53
58
|
public void load() {
|
|
@@ -102,10 +107,16 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
102
107
|
}
|
|
103
108
|
}
|
|
104
109
|
);
|
|
110
|
+
|
|
111
|
+
Boolean configBackgroundMode = getConfig().getBoolean("enableBackgroundMode", false);
|
|
112
|
+
if (configBackgroundMode != null && configBackgroundMode) {
|
|
113
|
+
backgroundModeEnabled = true;
|
|
114
|
+
}
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
@Override
|
|
108
118
|
protected void handleOnDestroy() {
|
|
119
|
+
applyBackgroundMode(false);
|
|
109
120
|
if (beaconManager != null && beaconManagerBound) {
|
|
110
121
|
beaconManager.unbind(this);
|
|
111
122
|
beaconManagerBound = false;
|
|
@@ -113,6 +124,20 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
113
124
|
super.handleOnDestroy();
|
|
114
125
|
}
|
|
115
126
|
|
|
127
|
+
@Override
|
|
128
|
+
protected void handleOnPause() {
|
|
129
|
+
super.handleOnPause();
|
|
130
|
+
isInBackground = true;
|
|
131
|
+
applyBackgroundMode(backgroundModeEnabled);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@Override
|
|
135
|
+
protected void handleOnResume() {
|
|
136
|
+
super.handleOnResume();
|
|
137
|
+
isInBackground = false;
|
|
138
|
+
applyBackgroundMode(backgroundModeEnabled);
|
|
139
|
+
}
|
|
140
|
+
|
|
116
141
|
@Override
|
|
117
142
|
public void onBeaconServiceConnect() {
|
|
118
143
|
beaconManagerBound = true;
|
|
@@ -139,6 +164,7 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
139
164
|
String uuid = call.getString("uuid");
|
|
140
165
|
Integer major = call.getInt("major");
|
|
141
166
|
Integer minor = call.getInt("minor");
|
|
167
|
+
Boolean enableBackgroundMode = call.getBoolean("enableBackgroundMode");
|
|
142
168
|
|
|
143
169
|
if (identifier == null || uuid == null) {
|
|
144
170
|
call.reject("Missing required parameters");
|
|
@@ -146,6 +172,9 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
146
172
|
}
|
|
147
173
|
|
|
148
174
|
try {
|
|
175
|
+
if (enableBackgroundMode != null) {
|
|
176
|
+
setBackgroundModeEnabled(enableBackgroundMode);
|
|
177
|
+
}
|
|
149
178
|
Region region = createRegion(identifier, uuid, major, minor);
|
|
150
179
|
monitoredRegions.put(identifier, region);
|
|
151
180
|
beaconManager.startMonitoring(region);
|
|
@@ -183,6 +212,7 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
183
212
|
String uuid = call.getString("uuid");
|
|
184
213
|
Integer major = call.getInt("major");
|
|
185
214
|
Integer minor = call.getInt("minor");
|
|
215
|
+
Boolean enableBackgroundMode = call.getBoolean("enableBackgroundMode");
|
|
186
216
|
|
|
187
217
|
if (identifier == null || uuid == null) {
|
|
188
218
|
call.reject("Missing required parameters");
|
|
@@ -190,6 +220,9 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
190
220
|
}
|
|
191
221
|
|
|
192
222
|
try {
|
|
223
|
+
if (enableBackgroundMode != null) {
|
|
224
|
+
setBackgroundModeEnabled(enableBackgroundMode);
|
|
225
|
+
}
|
|
193
226
|
Region region = createRegion(identifier, uuid, major, minor);
|
|
194
227
|
rangedRegions.put(identifier, region);
|
|
195
228
|
beaconManager.startRangingBeacons(region);
|
|
@@ -525,44 +558,7 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
525
558
|
public void enableBackgroundMode(PluginCall call) {
|
|
526
559
|
Boolean enabled = call.getBoolean("enabled", true);
|
|
527
560
|
try {
|
|
528
|
-
|
|
529
|
-
// Enable foreground service for background beacon scanning
|
|
530
|
-
// This is required on Android 8+ for reliable background operation
|
|
531
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
532
|
-
// Create notification channel for foreground service
|
|
533
|
-
android.app.NotificationChannel channel = new android.app.NotificationChannel(
|
|
534
|
-
"beacon_service_channel",
|
|
535
|
-
"Beacon Service",
|
|
536
|
-
android.app.NotificationManager.IMPORTANCE_LOW
|
|
537
|
-
);
|
|
538
|
-
channel.setDescription("Background beacon monitoring service");
|
|
539
|
-
|
|
540
|
-
android.app.NotificationManager notificationManager = getContext().getSystemService(
|
|
541
|
-
android.app.NotificationManager.class
|
|
542
|
-
);
|
|
543
|
-
if (notificationManager != null) {
|
|
544
|
-
notificationManager.createNotificationChannel(channel);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// Build notification for foreground service
|
|
548
|
-
android.app.Notification.Builder builder = new android.app.Notification.Builder(getContext(), "beacon_service_channel");
|
|
549
|
-
builder.setSmallIcon(android.R.drawable.ic_dialog_info);
|
|
550
|
-
builder.setContentTitle("Beacon Monitoring");
|
|
551
|
-
builder.setContentText("Scanning for nearby beacons");
|
|
552
|
-
|
|
553
|
-
// Enable foreground service mode in AltBeacon
|
|
554
|
-
beaconManager.enableForegroundServiceScanning(builder.build(), 456);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// Set background mode
|
|
558
|
-
beaconManager.setBackgroundMode(true);
|
|
559
|
-
} else {
|
|
560
|
-
// Disable background mode
|
|
561
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
562
|
-
beaconManager.disableForegroundServiceScanning();
|
|
563
|
-
}
|
|
564
|
-
beaconManager.setBackgroundMode(false);
|
|
565
|
-
}
|
|
561
|
+
setBackgroundModeEnabled(enabled != null && enabled);
|
|
566
562
|
call.resolve();
|
|
567
563
|
} catch (Exception e) {
|
|
568
564
|
call.reject("Failed to enable background mode", e);
|
|
@@ -690,4 +686,63 @@ public class CapacitorIbeaconPlugin extends Plugin implements BeaconConsumer {
|
|
|
690
686
|
return "far";
|
|
691
687
|
}
|
|
692
688
|
}
|
|
689
|
+
|
|
690
|
+
private void setBackgroundModeEnabled(boolean enabled) {
|
|
691
|
+
backgroundModeEnabled = enabled;
|
|
692
|
+
applyBackgroundMode(enabled);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
private void applyBackgroundMode(boolean enabled) {
|
|
696
|
+
if (beaconManager == null) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
boolean shouldEnableBackgroundMode = enabled && isInBackground;
|
|
701
|
+
|
|
702
|
+
if (shouldEnableBackgroundMode) {
|
|
703
|
+
enableForegroundServiceIfNeeded();
|
|
704
|
+
beaconManager.setBackgroundMode(true);
|
|
705
|
+
} else {
|
|
706
|
+
disableForegroundServiceIfNeeded();
|
|
707
|
+
beaconManager.setBackgroundMode(false);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private void enableForegroundServiceIfNeeded() {
|
|
712
|
+
if (foregroundServiceEnabled || Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// Create notification channel for foreground service
|
|
717
|
+
android.app.NotificationChannel channel = new android.app.NotificationChannel(
|
|
718
|
+
FOREGROUND_CHANNEL_ID,
|
|
719
|
+
"Beacon Service",
|
|
720
|
+
android.app.NotificationManager.IMPORTANCE_LOW
|
|
721
|
+
);
|
|
722
|
+
channel.setDescription("Background beacon monitoring service");
|
|
723
|
+
|
|
724
|
+
android.app.NotificationManager notificationManager = getContext().getSystemService(android.app.NotificationManager.class);
|
|
725
|
+
if (notificationManager != null) {
|
|
726
|
+
notificationManager.createNotificationChannel(channel);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Build notification for foreground service
|
|
730
|
+
android.app.Notification.Builder builder = new android.app.Notification.Builder(getContext(), FOREGROUND_CHANNEL_ID);
|
|
731
|
+
builder.setSmallIcon(android.R.drawable.ic_dialog_info);
|
|
732
|
+
builder.setContentTitle("Beacon Monitoring");
|
|
733
|
+
builder.setContentText("Scanning for nearby beacons");
|
|
734
|
+
|
|
735
|
+
// Enable foreground service mode in AltBeacon
|
|
736
|
+
beaconManager.enableForegroundServiceScanning(builder.build(), FOREGROUND_NOTIFICATION_ID);
|
|
737
|
+
foregroundServiceEnabled = true;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
private void disableForegroundServiceIfNeeded() {
|
|
741
|
+
if (!foregroundServiceEnabled || Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
beaconManager.disableForegroundServiceScanning();
|
|
746
|
+
foregroundServiceEnabled = false;
|
|
747
|
+
}
|
|
693
748
|
}
|
package/dist/docs.json
CHANGED
|
@@ -820,6 +820,13 @@
|
|
|
820
820
|
"docs": "Notify when device enters region (iOS only).",
|
|
821
821
|
"complexTypes": [],
|
|
822
822
|
"type": "boolean | undefined"
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
"name": "enableBackgroundMode",
|
|
826
|
+
"tags": [],
|
|
827
|
+
"docs": "Enable Android background mode for this monitoring/ranging call.\nWhen true, the plugin will keep scanning in background using a foreground service.",
|
|
828
|
+
"complexTypes": [],
|
|
829
|
+
"type": "boolean | undefined"
|
|
823
830
|
}
|
|
824
831
|
]
|
|
825
832
|
},
|
|
@@ -374,6 +374,11 @@ export interface BeaconRegion {
|
|
|
374
374
|
* Notify when device enters region (iOS only).
|
|
375
375
|
*/
|
|
376
376
|
notifyEntryStateOnDisplay?: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Enable Android background mode for this monitoring/ranging call.
|
|
379
|
+
* When true, the plugin will keep scanning in background using a foreground service.
|
|
380
|
+
*/
|
|
381
|
+
enableBackgroundMode?: boolean;
|
|
377
382
|
}
|
|
378
383
|
/**
|
|
379
384
|
* Background scan period configuration options (Android only).
|
|
@@ -4,7 +4,7 @@ import CoreLocation
|
|
|
4
4
|
|
|
5
5
|
@objc(CapacitorIbeaconPlugin)
|
|
6
6
|
public class CapacitorIbeaconPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
7
|
-
private let pluginVersion: String = "8.1.
|
|
7
|
+
private let pluginVersion: String = "8.1.4"
|
|
8
8
|
public let identifier = "CapacitorIbeaconPlugin"
|
|
9
9
|
public let jsName = "CapacitorIbeacon"
|
|
10
10
|
public let pluginMethods: [CAPPluginMethod] = [
|
package/package.json
CHANGED