Skip to content

Commit 63b8750

Browse files
committed
fix(android): make it clearer how to use permissions in the doc. Also code changed a bit to reflect that. NOW YOU NEED TO DEFINE PERMISSIONS IN YOUR MANIFEST. The plugin wont do it anymore to not add unecessary permissions
1 parent c17d2cc commit 63b8750

File tree

5 files changed

+56
-32
lines changed

5 files changed

+56
-32
lines changed

packages/ble/blueprint.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ bluetooth.isBluetoothEnabled().then(
5151
}
5252
);
5353
```
54-
### hasLocationPermission
55-
__Since plugin version 1.2.0 the `startScanning` function will handle this internally so it's no longer mandatory to add permission checks to your code.__
54+
### Permissions (Android)
5655

57-
On Android 6 you need to request permission to be able to interact with a Bluetooth peripheral (when the app is in the background) when targeting API level 23+. Even if the `uses-permission` tag for `ACCESS_COARSE_LOCATION` is present in `AndroidManifest.xml`.
56+
On Android >= 6 and < 12 you need to request permissions to be able to interact with a Bluetooth peripheral (when the app is in the background) when targeting API level 23+. You need `BLUETOOTH` and `ACCESS_FINE_LOCATION`. You should read the doc [here](https://developer.android.com/develop/connectivity/bluetooth/bt-permissions)
5857

59-
Note that for `BLUETOOTH` and `BLUETOOTH_ADMIN` you don't require runtime permission; adding those to `AndroidManifest.xml` suffices (which the plugin does for you).
58+
On android >= 12 you need new permissions. You should read the doc [here](https://developer.android.com/develop/connectivity/bluetooth/bt-permissions)
59+
Note that for `BLUETOOTH` and `BLUETOOTH_ADMIN` you don't require runtime permission; adding those to `AndroidManifest.xml` suffices.
6060

6161
Note that `hasLocationPermission ` will return true when:
6262
* You're running this on iOS, or
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
33

4-
<uses-permission android:name="android.permission.BLUETOOTH"/>
4+
<!-- Required for Android >= 12. You need to add that yourself now -->
5+
<!-- <uses-permission android:name="android.permission.BLUETOOTH"/>
56
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
67
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
7-
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
8+
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/> -->
89

9-
<!-- Required for Android 6+ when scanning for peripherals in the background -->
10-
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
10+
<!-- Required for Android 6+ and < 12. You need to add that yourself now -->
11+
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> -->
1112

1213
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
1314
</manifest>

src/ble/index.android.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* eslint-disable no-caller */
22
import { arrayToNativeArray } from '@nativescript-community/arraybuffers';
33
import { Application, Device, Trace, Utils } from '@nativescript/core';
4+
import { check, request } from '@nativescript-community/perms';
45
import { AndroidActivityResultEventData, AndroidApplication } from '@nativescript/core/application';
56
import PQueue from 'p-queue';
67
import {
78
AdvertismentData,
8-
BleTraceCategory,
99
BluetoothCommon,
1010
BluetoothError,
1111
BluetoothOptions,
@@ -38,7 +38,7 @@ export function getBluetoothInstance() {
3838
return _bluetoothInstance;
3939
}
4040

41-
export { BleTraceCategory, BluetoothError };
41+
export * from './index.common';
4242

4343
const sdkVersion = parseInt(Device.sdkVersion, 10);
4444
let context: android.content.Context;
@@ -1214,9 +1214,29 @@ export class Bluetooth extends BluetoothCommon {
12141214
}
12151215

12161216
getAndroidLocationManager(): android.location.LocationManager {
1217-
return (Utils.android.getApplicationContext() as android.content.Context).getSystemService(android.content.Context.LOCATION_SERVICE);
1217+
return Utils.android.getApplicationContext().getSystemService(android.content.Context.LOCATION_SERVICE);
12181218
}
1219-
public isGPSEnabled() {
1219+
1220+
async hasLocationPermission() {
1221+
if (sdkVersion >= 31) {
1222+
// location permission not needed anymore
1223+
return true;
1224+
}
1225+
return check('location', { coarse: false, precise: true }).then((r) => r[1]);
1226+
}
1227+
1228+
async requestLocationPermission() {
1229+
if (sdkVersion >= 31) {
1230+
// location permission not needed anymore
1231+
return true;
1232+
}
1233+
return request('location', { coarse: false, precise: true }).then((r) => r[1]);
1234+
}
1235+
async isGPSEnabled() {
1236+
if (sdkVersion >= 31) {
1237+
// location permission not needed anymore
1238+
return true;
1239+
}
12201240
if (!this.hasLocationPermission()) {
12211241
return this.requestLocationPermission().then(() => this.isGPSEnabled());
12221242
}
@@ -1226,7 +1246,7 @@ export class Bluetooth extends BluetoothCommon {
12261246
CLog(CLogTypes.info, 'isGPSEnabled providers', providers);
12271247
CLog(CLogTypes.info, 'isGPSEnabled: ', result);
12281248
}
1229-
return Promise.resolve(result);
1249+
return result;
12301250
}
12311251
public enableGPS(): Promise<void> {
12321252
if (Trace.isEnabled()) {
@@ -1236,7 +1256,7 @@ export class Bluetooth extends BluetoothCommon {
12361256
const activity = Application.android.foregroundActivity || Application.android.startActivity;
12371257
if (!this.isGPSEnabled()) {
12381258
const onActivityResultHandler = (data: AndroidActivityResultEventData) => {
1239-
Application.android.off(AndroidApplication.activityResultEvent, onActivityResultHandler);
1259+
Application.android.off(Application.android.activityResultEvent, onActivityResultHandler);
12401260
if (data.requestCode === 0) {
12411261
if (this.isGPSEnabled()) {
12421262
resolve();
@@ -1245,7 +1265,7 @@ export class Bluetooth extends BluetoothCommon {
12451265
}
12461266
}
12471267
};
1248-
Application.android.on(AndroidApplication.activityResultEvent, onActivityResultHandler);
1268+
Application.android.on(Application.android.activityResultEvent, onActivityResultHandler);
12491269
activity.startActivityForResult(new android.content.Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
12501270
} else {
12511271
resolve();
@@ -1275,7 +1295,7 @@ export class Bluetooth extends BluetoothCommon {
12751295
if (args.requestCode === ACTION_REQUEST_ENABLE_BLUETOOTH_REQUEST_CODE) {
12761296
try {
12771297
// remove the event listener
1278-
Application.android.off(AndroidApplication.activityResultEvent, onBluetoothEnableResult);
1298+
Application.android.off(Application.android.activityResultEvent, onBluetoothEnableResult);
12791299

12801300
// RESULT_OK = -1
12811301
if (args.resultCode === android.app.Activity.RESULT_OK) {
@@ -1287,19 +1307,19 @@ export class Bluetooth extends BluetoothCommon {
12871307
if (Trace.isEnabled()) {
12881308
CLog(CLogTypes.error, ex);
12891309
}
1290-
Application.android.off(AndroidApplication.activityResultEvent, onBluetoothEnableResult);
1310+
Application.android.off(Application.android.activityResultEvent, onBluetoothEnableResult);
12911311
reject(ex);
12921312
return;
12931313
}
12941314
} else {
1295-
Application.android.off(AndroidApplication.activityResultEvent, onBluetoothEnableResult);
1315+
Application.android.off(Application.android.activityResultEvent, onBluetoothEnableResult);
12961316
resolve(false);
12971317
return;
12981318
}
12991319
};
13001320

13011321
// set the onBluetoothEnableResult for the intent
1302-
Application.android.on(AndroidApplication.activityResultEvent, onBluetoothEnableResult);
1322+
Application.android.on(Application.android.activityResultEvent, onBluetoothEnableResult);
13031323

13041324
// create the intent to start the bluetooth enable request
13051325
const intent = new android.content.Intent(android.bluetooth.BluetoothAdapter.ACTION_REQUEST_ENABLE);
@@ -1379,7 +1399,7 @@ export class Bluetooth extends BluetoothCommon {
13791399
});
13801400
}
13811401
scanningReferTimer: {
1382-
timer?: NodeJS.Timeout;
1402+
timer?: number;
13831403
resolve?: Function;
13841404
};
13851405

src/ble/index.common.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import Observable from '@nativescript-community/observable';
22
import { Trace } from '@nativescript/core';
33
import { BaseError } from 'make-error';
4-
import { check, request } from '@nativescript-community/perms';
54

65
export const BleTraceCategory = 'NativescriptBle';
76
export enum CLogTypes {
@@ -26,7 +25,7 @@ export class BluetoothError extends BaseError {
2625
Object.assign(this, properties);
2726
}
2827
}
29-
28+
3029
toString() {
3130
return `[BluetoothError]:${this.message}${Object.keys(this).map((k) => {
3231
if (k === 'message') {
@@ -150,12 +149,12 @@ export abstract class BluetoothCommon extends Observable {
150149
return Promise.resolve(); // we dont need to check for GPS in the bluetooth iOS module
151150
}
152151

153-
public hasLocationPermission() {
154-
return check('location').then((r) => r[1]);
152+
async hasLocationPermission() {
153+
return true;
155154
}
156155

157-
public async requestLocationPermission() {
158-
return request('location').then((r) => r[1]);
156+
async requestLocationPermission() {
157+
return true;
159158
}
160159

161160
/**

src/ble/index.ios.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { Trace } from '@nativescript/core';
12
import {
2-
BleTraceCategory,
33
BluetoothCommon,
44
BluetoothError,
55
BluetoothOptions,
@@ -22,9 +22,9 @@ import {
2222
prepareArgs,
2323
shortenUuidIfAssignedNumber
2424
} from './index.common';
25-
import { Trace } from '@nativescript/core';
2625

27-
export { BleTraceCategory, BluetoothError };
26+
export * from './index.common';
27+
export { Peripheral, ReadResult, Service };
2828

2929
function nativeEncoding(encoding: string) {
3030
switch (encoding) {
@@ -612,7 +612,6 @@ export function getBluetoothInstance() {
612612
}
613613
return _bluetoothInstance;
614614
}
615-
export { Peripheral, ReadResult, Service };
616615

617616
export function toArrayBuffer(value) {
618617
return value ? interop.bufferFromData(value) : null;
@@ -703,7 +702,10 @@ export class Bluetooth extends BluetoothCommon {
703702

704703
private restoreIdentifier: string;
705704

706-
constructor(restoreIdentifierOrOptions: string | Partial<BluetoothOptions> | null = 'ns_bluetooth', private showPowerAlertPopup = false) {
705+
constructor(
706+
restoreIdentifierOrOptions: string | Partial<BluetoothOptions> | null = 'ns_bluetooth',
707+
private showPowerAlertPopup = false
708+
) {
707709
super();
708710
if (typeof restoreIdentifierOrOptions === 'object') {
709711
if (restoreIdentifierOrOptions.restoreIdentifier === undefined) {
@@ -797,7 +799,7 @@ export class Bluetooth extends BluetoothCommon {
797799
return this._isEnabled();
798800
}
799801
scanningReferTimer: {
800-
timer?: NodeJS.Timeout;
802+
timer?: number;
801803
resolve?: Function;
802804
};
803805

@@ -844,6 +846,8 @@ export class Bluetooth extends BluetoothCommon {
844846
} else {
845847
resolve();
846848
}
849+
if (__DEV__) {
850+
}
847851
} catch (ex) {
848852
if (Trace.isEnabled()) {
849853
CLog(CLogTypes.error, methodName, '---- error:', ex);

0 commit comments

Comments
 (0)