Skip to content

Commit cbdc5e3

Browse files
authored
Merge pull request #37 from GeoTecINIT/ble-support
Support for BLE scanning
2 parents 2ba9d01 + 81d7413 commit cbdc5e3

22 files changed

+11133
-1245
lines changed

README.md

Lines changed: 234 additions & 25 deletions
Large diffs are not rendered by default.

azure-pipelines.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ steps:
3232

3333
- script: |
3434
cd src
35-
npm install
35+
npm run setup
3636
npm run ci.tslint
3737
displayName: 'Lint'
3838

3939
- script: |
4040
cd demo
41-
npm install
41+
npm run setup
4242
ns build android --bundle --env.uglify --env.snapshot
4343
displayName: 'Build'
4444

demo/app/App_Resources/Android/app.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Add your native dependencies here:
22

33
// Uncomment to add recyclerview-v7 dependency
4-
//dependencies {
4+
dependencies {
55
// implementation 'com.android.support:recyclerview-v7:+'
6-
//}
6+
implementation 'no.nordicsemi.android.support.v18:scanner:1.6.0'
7+
}
78

89
// If you want to add something to be applied before applying plugins' include.gradle files
910
// e.g. project.ext.googlePlayServicesVersion = "15.0.1"

demo/app/App_Resources/Android/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
3131
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
3232

33+
<!-- The following two permissions are required in order to ask and retrieve BLE scan updates -->
34+
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
35+
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
36+
3337
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3438
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3539
<uses-permission android:name="android.permission.INTERNET"/>

demo/app/home/home-page.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@ import { of, Subscription } from "rxjs";
1616
import {
1717
FingerprintGrouping,
1818
WifiScanProvider,
19-
} from "nativescript-context-apis/internal/wifi";
19+
} from "nativescript-context-apis/wifi";
20+
import { BleScanProvider, BleScanMode } from "nativescript-context-apis/ble";
21+
22+
const I_BEACON_UUIDS = [
23+
// Place your iBeacon UUIDs here to just report beacon updates!
24+
];
2025

2126
const activityRecognizers = [Resolution.LOW, Resolution.MEDIUM];
2227

2328
let locationSubscription: Subscription;
2429
let wifiScanSubscription: Subscription;
30+
let bleScanSubscription: Subscription;
2531
export function onNavigatingTo(args: NavigatedData) {
2632
const page = <Page>args.object;
2733

@@ -40,6 +46,7 @@ export function onNavigatingTo(args: NavigatedData) {
4046
if (!preparing) {
4147
locationSubscription?.unsubscribe();
4248
wifiScanSubscription?.unsubscribe();
49+
bleScanSubscription?.unsubscribe();
4350
stopListeningToChanges();
4451
}
4552
});
@@ -54,10 +61,17 @@ async function showUpdates(addListeners = false): Promise<void> {
5461
printCurrentLocation().catch((err) => {
5562
console.error("Could not print current location. Reason:", err);
5663
}),
64+
() =>
65+
printBleScanResult().catch((err) => {
66+
console.error(
67+
"Could not print current nearby BLE devices. Reason:",
68+
err
69+
);
70+
}),
5771
() =>
5872
printWifiScanResult().catch((err) => {
5973
console.error(
60-
"Could not print current nearby wifi scan. Reason:",
74+
"Could not print current nearby wifi APs. Reason:",
6175
err
6276
);
6377
}),
@@ -70,6 +84,15 @@ async function showUpdates(addListeners = false): Promise<void> {
7084
err
7185
)
7286
),
87+
() =>
88+
printBleScanUpdates()
89+
.then((subscription) => (bleScanSubscription = subscription))
90+
.catch((err) =>
91+
console.error(
92+
"An error occurred while getting ble scan updates. Reason:",
93+
err
94+
)
95+
),
7396
() =>
7497
printWifiScanUpdates()
7598
.then((subscription) => (wifiScanSubscription = subscription))
@@ -106,6 +129,19 @@ async function printWifiScanResult() {
106129
}
107130
}
108131

132+
async function printBleScanResult() {
133+
const provider = contextApis.bleScanProvider;
134+
const ok = await prepareBleScanProvider(provider);
135+
if (ok) {
136+
const bleScanResult = await provider.acquireBleScan({
137+
scanTime: 5000,
138+
scanMode: BleScanMode.BALANCED,
139+
iBeaconUuids: I_BEACON_UUIDS,
140+
});
141+
console.log(`Last ble scan result: ${JSON.stringify(bleScanResult)}`);
142+
}
143+
}
144+
109145
async function printLocationUpdates(): Promise<Subscription> {
110146
const provider = contextApis.geolocationProvider;
111147
const ok = await prepareGeolocationProvider(provider);
@@ -152,6 +188,28 @@ async function printWifiScanUpdates(): Promise<Subscription> {
152188
});
153189
}
154190

191+
async function printBleScanUpdates(): Promise<Subscription> {
192+
const provider = contextApis.bleScanProvider;
193+
const ok = await prepareBleScanProvider(provider);
194+
195+
const stream = ok
196+
? provider.bleScanStream({
197+
reportInterval: 2000,
198+
scanMode: BleScanMode.LOW_LATENCY,
199+
iBeaconUuids: I_BEACON_UUIDS,
200+
})
201+
: of(null);
202+
203+
return stream.subscribe({
204+
next: (bleScanResult) =>
205+
console.log(
206+
`New ble scan result!: ${JSON.stringify(bleScanResult)}`
207+
),
208+
error: (error) =>
209+
console.error(`Ble scan result could not be acquired: ${error}`),
210+
});
211+
}
212+
155213
export async function listenToActivityChanges(addListener = false) {
156214
for (const recognizerType of activityRecognizers) {
157215
try {
@@ -257,3 +315,28 @@ async function prepareWifiScanProvider(
257315
_preparingWifiProv = null;
258316
}
259317
}
318+
319+
let _preparingBleProv: Promise<any>;
320+
async function prepareBleScanProvider(
321+
provider: BleScanProvider
322+
): Promise<boolean> {
323+
const isReady = await provider.isReady();
324+
if (isReady) {
325+
return true;
326+
}
327+
328+
try {
329+
if (!_preparingBleProv) {
330+
_preparingBleProv = provider.prepare();
331+
}
332+
await _preparingBleProv;
333+
return true;
334+
} catch (e) {
335+
console.error(
336+
`BleScanProvider couldn't be prepared: ${JSON.stringify(e)}`
337+
);
338+
return false;
339+
} finally {
340+
_preparingBleProv = null;
341+
}
342+
}

0 commit comments

Comments
 (0)