@capacitor-community/bluetooth-le 3.0.1 → 3.1.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/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  <a href="https://www.npmjs.com/package/@capacitor-community/bluetooth-le"><img src="https://img.shields.io/npm/dw/@capacitor-community/bluetooth-le?style=flat-square" /></a>
14
14
  <a href="https://www.npmjs.com/package/@capacitor-community/bluetooth-le"><img src="https://img.shields.io/npm/v/@capacitor-community/bluetooth-le?style=flat-square" /></a>
15
15
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
16
- <a href="#contributors-"><img src="https://img.shields.io/badge/all%20contributors-11-orange?style=flat-square" /></a>
16
+ <a href="#contributors-"><img src="https://img.shields.io/badge/all%20contributors-14-orange?style=flat-square" /></a>
17
17
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
18
18
  </p>
19
19
 
@@ -51,6 +51,7 @@ Below is an index of all the methods available.
51
51
 
52
52
  - [`initialize(...)`](#initialize)
53
53
  - [`isEnabled()`](#isenabled)
54
+ - [`requestEnable()`](#requestenable)
54
55
  - [`enable()`](#enable)
55
56
  - [`disable()`](#disable)
56
57
  - [`startEnabledNotifications(...)`](#startenablednotifications)
@@ -207,6 +208,8 @@ import { BleClient } from '@capacitor-community/bluetooth-le';
207
208
  import { BluetoothLe } from '@capacitor-community/bluetooth-le';
208
209
  ```
209
210
 
211
+ ### Heart rate monitor
212
+
210
213
  Here is an example of how to use the plugin. It shows how to read the heart rate from a BLE heart rate monitor such as the Polar H10.
211
214
 
212
215
  ```typescript
@@ -279,7 +282,9 @@ function parseHeartRate(value: DataView): number {
279
282
  }
280
283
  ```
281
284
 
282
- An example of using the scanning API:
285
+ ### Scanning API
286
+
287
+ Here is an example of using the scanning API.
283
288
 
284
289
  ```typescript
285
290
  import { BleClient, numberToUUID } from '@capacitor-community/bluetooth-le';
@@ -323,6 +328,7 @@ _Note_: web support depends on the browser, see [implementation status](https://
323
328
  | -------------------------------------------------------------- | :-----: | :-: | :-: |
324
329
  | [`initialize()`](#initialize) | ✅ | ✅ | ✅ |
325
330
  | [`isEnabled()`](#isenabled) | ✅ | ✅ | -- |
331
+ | [`requestEnable()`](#requestEnable) | ✅ | ❌ | ❌ |
326
332
  | [`enable()`](#enable) | ✅ | ❌ | ❌ |
327
333
  | [`disable()`](#disable) | ✅ | ❌ | ❌ |
328
334
  | [`startEnabledNotifications(...)`](#startenablednotifications) | ✅ | ✅ | -- |
@@ -395,6 +401,17 @@ Always returns `true` on **web**.
395
401
 
396
402
  ---
397
403
 
404
+ ### requestEnable()
405
+
406
+ ```typescript
407
+ requestEnable() => Promise<void>
408
+ ```
409
+
410
+ Request enabling Bluetooth. Show a system activity that allows the user to turn on Bluetooth. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#ACTION_REQUEST_ENABLE
411
+ Only available on **Android**.
412
+
413
+ ---
414
+
398
415
  ### enable()
399
416
 
400
417
  ```typescript
@@ -403,7 +420,7 @@ enable() => Promise<void>
403
420
 
404
421
  Enable Bluetooth.
405
422
  Only available on **Android**.
406
- _deprecated_ See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
423
+ **Deprecated** Will fail on Android SDK &gt;= 33. Use `requestEnable` instead. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
407
424
 
408
425
  ---
409
426
 
@@ -415,7 +432,7 @@ disable() => Promise<void>
415
432
 
416
433
  Disable Bluetooth.
417
434
  Only available on **Android**.
418
- _deprecated_ See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
435
+ **Deprecated** Will fail on Android SDK &gt;= 33. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
419
436
 
420
437
  ---
421
438
 
@@ -608,15 +625,16 @@ Connect to a peripheral BLE device. For an example, see [usage](#usage).
608
625
  ### createBond(...)
609
626
 
610
627
  ```typescript
611
- createBond(deviceId: string) => Promise<void>
628
+ createBond(deviceId: string, options?: TimeoutOptions | undefined) => Promise<void>
612
629
  ```
613
630
 
614
631
  Create a bond with a peripheral BLE device.
615
632
  Only available on **Android**. On iOS bonding is handled by the OS.
616
633
 
617
- | Param | Type | Description |
618
- | -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------- |
619
- | **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
634
+ | Param | Type | Description |
635
+ | -------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
636
+ | **`deviceId`** | <code>string</code> | The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan)) |
637
+ | **`options`** | <code><a href="#timeoutoptions">TimeoutOptions</a></code> | Options for plugin call |
620
638
 
621
639
  ---
622
640
 
@@ -1046,6 +1064,23 @@ await BleClient.disconnect(device.deviceId);
1046
1064
  await BleClient.connect(device.deviceId);
1047
1065
  ```
1048
1066
 
1067
+ #### No devices found on Android
1068
+
1069
+ On Android, the `initialize` call requests the location permission. However, if location services are disable on the OS level, the app will not find any devices. You can check if the location is enabled and open the settings when not.
1070
+
1071
+ ```typescript
1072
+ async function initialize() {
1073
+ // Check if location is enabled
1074
+ if (this.platform.is('android')) {
1075
+ const isLocationEnabled = await BleClient.isLocationEnabled();
1076
+ if (!isLocationEnabled) {
1077
+ await BleClient.openLocationSettings();
1078
+ }
1079
+ }
1080
+ await BleClient.initialize();
1081
+ }
1082
+ ```
1083
+
1049
1084
  ## Contributors ✨
1050
1085
 
1051
1086
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -1069,6 +1104,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
1069
1104
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/aadito123"><img src="https://avatars.githubusercontent.com/u/63646058?v=4?s=100" width="100px;" alt="Aadit Olkar"/><br /><sub><b>Aadit Olkar</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=aadito123" title="Code">💻</a></td>
1070
1105
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/y3nd"><img src="https://avatars.githubusercontent.com/u/18102153?v=4?s=100" width="100px;" alt="Yoann N."/><br /><sub><b>Yoann N.</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=y3nd" title="Code">💻</a></td>
1071
1106
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Andy3189"><img src="https://avatars.githubusercontent.com/u/2084016?v=4?s=100" width="100px;" alt="Andy3189"/><br /><sub><b>Andy3189</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=Andy3189" title="Code">💻</a></td>
1107
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/RFM69CW"><img src="https://avatars.githubusercontent.com/u/20404734?v=4?s=100" width="100px;" alt="Sammy"/><br /><sub><b>Sammy</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=RFM69CW" title="Documentation">📖</a></td>
1108
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/td-tomasz-joniec"><img src="https://avatars.githubusercontent.com/u/109506928?v=4?s=100" width="100px;" alt="td-tomasz-joniec"/><br /><sub><b>td-tomasz-joniec</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=td-tomasz-joniec" title="Code">💻</a></td>
1109
+ <td align="center" valign="top" width="14.28%"><a href="https://fanxj.com"><img src="https://avatars.githubusercontent.com/u/10436013?v=4?s=100" width="100px;" alt="Michele Ferrari"/><br /><sub><b>Michele Ferrari</b></sub></a><br /><a href="https://github.com/capacitor-community/bluetooth-le/commits?author=micheleypf" title="Code">💻</a></td>
1072
1110
  </tr>
1073
1111
  </tbody>
1074
1112
  </table>
@@ -1,7 +1,9 @@
1
1
  package com.capacitorjs.community.plugins.bluetoothle
2
2
 
3
3
  import android.Manifest
4
+ import android.annotation.SuppressLint
4
5
  import android.bluetooth.BluetoothAdapter
6
+ import android.bluetooth.BluetoothAdapter.ACTION_REQUEST_ENABLE
5
7
  import android.bluetooth.BluetoothDevice
6
8
  import android.bluetooth.BluetoothGatt
7
9
  import android.bluetooth.BluetoothGattCharacteristic
@@ -36,6 +38,7 @@ import com.getcapacitor.annotation.PermissionCallback
36
38
  import java.util.UUID
37
39
 
38
40
 
41
+ @SuppressLint("MissingPermission")
39
42
  @CapacitorPlugin(
40
43
  name = "BluetoothLe",
41
44
  permissions = [
@@ -96,8 +99,7 @@ class BluetoothLe : Plugin() {
96
99
 
97
100
  @PluginMethod
98
101
  fun initialize(call: PluginCall) {
99
- // Build.VERSION_CODES.S = 31
100
- if (Build.VERSION.SDK_INT >= 31) {
102
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
101
103
  val neverForLocation = call.getBoolean("androidNeverForLocation", false) as Boolean
102
104
  aliases = if (neverForLocation) {
103
105
  arrayOf(
@@ -160,6 +162,13 @@ class BluetoothLe : Plugin() {
160
162
  call.resolve(result)
161
163
  }
162
164
 
165
+ @PluginMethod
166
+ fun requestEnable(call: PluginCall) {
167
+ val intent = Intent(ACTION_REQUEST_ENABLE)
168
+ activity.startActivity(intent)
169
+ call.resolve()
170
+ }
171
+
163
172
  @PluginMethod
164
173
  fun enable(call: PluginCall) {
165
174
  assertBluetoothAdapter(call) ?: return
@@ -439,7 +448,8 @@ class BluetoothLe : Plugin() {
439
448
  @PluginMethod
440
449
  fun createBond(call: PluginCall) {
441
450
  val device = getOrCreateDevice(call) ?: return
442
- device.createBond { response ->
451
+ val timeout = call.getFloat("timeout", DEFAULT_TIMEOUT)!!.toLong()
452
+ device.createBond(timeout) { response ->
443
453
  run {
444
454
  if (response.success) {
445
455
  call.resolve()
@@ -1,5 +1,7 @@
1
1
  package com.capacitorjs.community.plugins.bluetoothle
2
2
 
3
+ import android.annotation.SuppressLint
4
+ import android.annotation.TargetApi
3
5
  import android.bluetooth.BluetoothAdapter
4
6
  import android.bluetooth.BluetoothDevice
5
7
  import android.bluetooth.BluetoothGatt
@@ -8,6 +10,7 @@ import android.bluetooth.BluetoothGattCharacteristic
8
10
  import android.bluetooth.BluetoothGattDescriptor
9
11
  import android.bluetooth.BluetoothGattService
10
12
  import android.bluetooth.BluetoothProfile
13
+ import android.bluetooth.BluetoothStatusCodes
11
14
  import android.content.BroadcastReceiver
12
15
  import android.content.Context
13
16
  import android.content.Intent
@@ -15,6 +18,7 @@ import android.content.IntentFilter
15
18
  import android.os.Build
16
19
  import android.os.Handler
17
20
  import android.os.Looper
21
+ import androidx.annotation.RequiresApi
18
22
  import com.getcapacitor.Logger
19
23
  import java.util.UUID
20
24
  import java.util.concurrent.ConcurrentLinkedQueue
@@ -43,6 +47,7 @@ fun <T> ConcurrentLinkedQueue<T>.popFirstMatch(predicate: (T) -> Boolean): T? {
43
47
  }
44
48
  }
45
49
 
50
+ @SuppressLint("MissingPermission")
46
51
  class Device(
47
52
  private val context: Context,
48
53
  bluetoothAdapter: BluetoothAdapter,
@@ -123,9 +128,15 @@ class Device(
123
128
  }
124
129
  }
125
130
 
131
+ @TargetApi(Build.VERSION_CODES.S_V2)
126
132
  override fun onCharacteristicRead(
127
133
  gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int
128
134
  ) {
135
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
136
+ // handled by new callback below
137
+ return
138
+ }
139
+ Logger.verbose(TAG, "Using deprecated onCharacteristicRead.")
129
140
  super.onCharacteristicRead(gatt, characteristic, status)
130
141
  val key = "read|${characteristic.service.uuid}|${characteristic.uuid}"
131
142
  if (status == BluetoothGatt.GATT_SUCCESS) {
@@ -141,6 +152,24 @@ class Device(
141
152
  }
142
153
  }
143
154
 
155
+ @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
156
+ override fun onCharacteristicRead(
157
+ gatt: BluetoothGatt,
158
+ characteristic: BluetoothGattCharacteristic,
159
+ data: ByteArray,
160
+ status: Int
161
+ ) {
162
+ Logger.verbose(TAG, "Using onCharacteristicRead from API level 33.")
163
+ super.onCharacteristicRead(gatt, characteristic, data, status)
164
+ val key = "read|${characteristic.service.uuid}|${characteristic.uuid}"
165
+ if (status == BluetoothGatt.GATT_SUCCESS) {
166
+ val value = bytesToString(data)
167
+ resolve(key, value)
168
+ } else {
169
+ reject(key, "Reading characteristic failed.")
170
+ }
171
+ }
172
+
144
173
  override fun onCharacteristicWrite(
145
174
  gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int
146
175
  ) {
@@ -154,9 +183,15 @@ class Device(
154
183
 
155
184
  }
156
185
 
186
+ @TargetApi(Build.VERSION_CODES.S_V2)
157
187
  override fun onCharacteristicChanged(
158
188
  gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic
159
189
  ) {
190
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
191
+ // handled by new callback below
192
+ return
193
+ }
194
+ Logger.verbose(TAG, "Using deprecated onCharacteristicChanged.")
160
195
  super.onCharacteristicChanged(gatt, characteristic)
161
196
  val notifyKey = "notification|${characteristic.service.uuid}|${characteristic.uuid}"
162
197
  val data = characteristic.value
@@ -166,9 +201,26 @@ class Device(
166
201
  }
167
202
  }
168
203
 
204
+ @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
205
+ override fun onCharacteristicChanged(
206
+ gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, data: ByteArray
207
+ ) {
208
+ Logger.verbose(TAG, "Using onCharacteristicChanged from API level 33.")
209
+ super.onCharacteristicChanged(gatt, characteristic, data)
210
+ val notifyKey = "notification|${characteristic.service.uuid}|${characteristic.uuid}"
211
+ val value = bytesToString(data)
212
+ callbackMap[notifyKey]?.invoke(CallbackResponse(true, value))
213
+ }
214
+
215
+ @TargetApi(Build.VERSION_CODES.S_V2)
169
216
  override fun onDescriptorRead(
170
217
  gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int
171
218
  ) {
219
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
220
+ // handled by new callback below
221
+ return
222
+ }
223
+ Logger.verbose(TAG, "Using deprecated onDescriptorRead.")
172
224
  super.onDescriptorRead(gatt, descriptor, status)
173
225
  val key =
174
226
  "readDescriptor|${descriptor.characteristic.service.uuid}|${descriptor.characteristic.uuid}|${descriptor.uuid}"
@@ -185,6 +237,22 @@ class Device(
185
237
  }
186
238
  }
187
239
 
240
+ @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
241
+ override fun onDescriptorRead(
242
+ gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int, data: ByteArray
243
+ ) {
244
+ Logger.verbose(TAG, "Using onDescriptorRead from API level 33.")
245
+ super.onDescriptorRead(gatt, descriptor, status, data)
246
+ val key =
247
+ "readDescriptor|${descriptor.characteristic.service.uuid}|${descriptor.characteristic.uuid}|${descriptor.uuid}"
248
+ if (status == BluetoothGatt.GATT_SUCCESS) {
249
+ val value = bytesToString(data)
250
+ resolve(key, value)
251
+ } else {
252
+ reject(key, "Reading descriptor failed.")
253
+ }
254
+ }
255
+
188
256
  override fun onDescriptorWrite(
189
257
  gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int
190
258
  ) {
@@ -256,7 +324,7 @@ class Device(
256
324
  return bluetoothGatt?.requestConnectionPriority(connectionPriority) ?: false
257
325
  }
258
326
 
259
- fun createBond(callback: (CallbackResponse) -> Unit) {
327
+ fun createBond(timeout: Long, callback: (CallbackResponse) -> Unit) {
260
328
  val key = "createBond"
261
329
  callbackMap[key] = callback
262
330
  try {
@@ -277,6 +345,7 @@ class Device(
277
345
  return
278
346
  }
279
347
  // otherwise, wait for bond state change
348
+ setTimeout(key, "Bonding timeout.", timeout)
280
349
  }
281
350
 
282
351
  private fun createBondStateReceiver() {
@@ -287,7 +356,14 @@ class Device(
287
356
  if (action == BluetoothDevice.ACTION_BOND_STATE_CHANGED) {
288
357
  val key = "createBond"
289
358
  val updatedDevice =
290
- intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
359
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
360
+ intent.getParcelableExtra(
361
+ BluetoothDevice.EXTRA_DEVICE,
362
+ BluetoothDevice::class.java
363
+ )
364
+ } else {
365
+ intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
366
+ }
291
367
  // BroadcastReceiver receives bond state updates from all devices, need to filter by device
292
368
  if (device.address == updatedDevice?.address) {
293
369
  val bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1)
@@ -415,12 +491,21 @@ class Device(
415
491
  return
416
492
  }
417
493
  val bytes = stringToBytes(value)
418
- characteristic.value = bytes
419
- characteristic.writeType = writeType
420
- val result = bluetoothGatt?.writeCharacteristic(characteristic)
421
- if (result != true) {
422
- reject(key, "Writing characteristic failed.")
423
- return
494
+
495
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
496
+ val statusCode = bluetoothGatt?.writeCharacteristic(characteristic, bytes, writeType)
497
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
498
+ reject(key, "Writing characteristic failed with status code $statusCode.")
499
+ return
500
+ }
501
+ } else {
502
+ characteristic.value = bytes
503
+ characteristic.writeType = writeType
504
+ val result = bluetoothGatt?.writeCharacteristic(characteristic)
505
+ if (result != true) {
506
+ reject(key, "Writing characteristic failed.")
507
+ return
508
+ }
424
509
  }
425
510
  setTimeout(key, "Write timeout.", timeout)
426
511
  }
@@ -457,20 +542,32 @@ class Device(
457
542
  return
458
543
  }
459
544
 
460
- if (enable) {
545
+ val value = if (enable) {
461
546
  if ((characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
462
- descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
547
+ BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
463
548
  } else if ((characteristic.properties and BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
464
- descriptor.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
549
+ BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
550
+ } else {
551
+ BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
465
552
  }
466
553
  } else {
467
- descriptor.value = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
554
+ BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
468
555
  }
469
556
 
470
- val resultDesc = bluetoothGatt?.writeDescriptor(descriptor)
471
- if (resultDesc != true) {
472
- reject(key, "Setting notification failed.")
473
- return
557
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
558
+ val statusCode = bluetoothGatt?.writeDescriptor(descriptor, value)
559
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
560
+ reject(key, "Setting notification failed with status code $statusCode.")
561
+ return
562
+ }
563
+ } else {
564
+ descriptor.value = value
565
+ val resultDesc = bluetoothGatt?.writeDescriptor(descriptor)
566
+ if (resultDesc != true) {
567
+ reject(key, "Setting notification failed.")
568
+ return
569
+ }
570
+
474
571
  }
475
572
  // wait for onDescriptorWrite
476
573
  }
@@ -525,11 +622,20 @@ class Device(
525
622
  return
526
623
  }
527
624
  val bytes = stringToBytes(value)
528
- descriptor.value = bytes
529
- val result = bluetoothGatt?.writeDescriptor(descriptor)
530
- if (result != true) {
531
- reject(key, "Writing characteristic failed.")
532
- return
625
+
626
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
627
+ val statusCode = bluetoothGatt?.writeDescriptor(descriptor, bytes)
628
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
629
+ reject(key, "Writing descriptor failed with status code $statusCode.")
630
+ return
631
+ }
632
+ } else {
633
+ descriptor.value = bytes
634
+ val result = bluetoothGatt?.writeDescriptor(descriptor)
635
+ if (result != true) {
636
+ reject(key, "Writing descriptor failed.")
637
+ return
638
+ }
533
639
  }
534
640
  setTimeout(key, "Write timeout.", timeout)
535
641
  }
@@ -1,5 +1,6 @@
1
1
  package com.capacitorjs.community.plugins.bluetoothle
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.app.AlertDialog
4
5
  import android.bluetooth.BluetoothAdapter
5
6
  import android.bluetooth.BluetoothDevice
@@ -27,6 +28,7 @@ class DisplayStrings(
27
28
  val noDeviceFound: String,
28
29
  )
29
30
 
31
+ @SuppressLint("MissingPermission")
30
32
  class DeviceScanner(
31
33
  private val context: Context,
32
34
  bluetoothAdapter: BluetoothAdapter,
package/dist/docs.json CHANGED
@@ -33,6 +33,16 @@
33
33
  "complexTypes": [],
34
34
  "slug": "isenabled"
35
35
  },
36
+ {
37
+ "name": "requestEnable",
38
+ "signature": "() => Promise<void>",
39
+ "parameters": [],
40
+ "returns": "Promise<void>",
41
+ "tags": [],
42
+ "docs": "Request enabling Bluetooth. Show a system activity that allows the user to turn on Bluetooth. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#ACTION_REQUEST_ENABLE\nOnly available on **Android**.",
43
+ "complexTypes": [],
44
+ "slug": "requestenable"
45
+ },
36
46
  {
37
47
  "name": "enable",
38
48
  "signature": "() => Promise<void>",
@@ -41,10 +51,10 @@
41
51
  "tags": [
42
52
  {
43
53
  "name": "deprecated",
44
- "text": "See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()"
54
+ "text": "Will fail on Android SDK >= 33. Use `requestEnable` instead. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()"
45
55
  }
46
56
  ],
47
- "docs": "Enable Bluetooth.\nOnly available on **Android**.\n*deprecated* See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()",
57
+ "docs": "Enable Bluetooth.\nOnly available on **Android**.\n**Deprecated** Will fail on Android SDK >= 33. Use `requestEnable` instead. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()",
48
58
  "complexTypes": [],
49
59
  "slug": "enable"
50
60
  },
@@ -56,10 +66,10 @@
56
66
  "tags": [
57
67
  {
58
68
  "name": "deprecated",
59
- "text": "See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()"
69
+ "text": "Will fail on Android SDK >= 33. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()"
60
70
  }
61
71
  ],
62
- "docs": "Disable Bluetooth.\nOnly available on **Android**.\n*deprecated* See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()",
72
+ "docs": "Disable Bluetooth.\nOnly available on **Android**.\n**Deprecated** Will fail on Android SDK >= 33. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()",
63
73
  "complexTypes": [],
64
74
  "slug": "disable"
65
75
  },
@@ -313,12 +323,17 @@
313
323
  },
314
324
  {
315
325
  "name": "createBond",
316
- "signature": "(deviceId: string) => Promise<void>",
326
+ "signature": "(deviceId: string, options?: TimeoutOptions | undefined) => Promise<void>",
317
327
  "parameters": [
318
328
  {
319
329
  "name": "deviceId",
320
330
  "docs": "The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan))",
321
331
  "type": "string"
332
+ },
333
+ {
334
+ "name": "options",
335
+ "docs": "Options for plugin call",
336
+ "type": "TimeoutOptions | undefined"
322
337
  }
323
338
  ],
324
339
  "returns": "Promise<void>",
@@ -326,10 +341,16 @@
326
341
  {
327
342
  "name": "param",
328
343
  "text": "deviceId The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan))"
344
+ },
345
+ {
346
+ "name": "param",
347
+ "text": "options Options for plugin call"
329
348
  }
330
349
  ],
331
350
  "docs": "Create a bond with a peripheral BLE device.\nOnly available on **Android**. On iOS bonding is handled by the OS.",
332
- "complexTypes": [],
351
+ "complexTypes": [
352
+ "TimeoutOptions"
353
+ ],
333
354
  "slug": "createbond"
334
355
  },
335
356
  {
@@ -12,18 +12,22 @@ export interface BleClientInterface {
12
12
  * Always returns `true` on **web**.
13
13
  */
14
14
  isEnabled(): Promise<boolean>;
15
+ /**
16
+ * Request enabling Bluetooth. Show a system activity that allows the user to turn on Bluetooth. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#ACTION_REQUEST_ENABLE
17
+ * Only available on **Android**.*/
18
+ requestEnable(): Promise<void>;
15
19
  /**
16
20
  * Enable Bluetooth.
17
21
  * Only available on **Android**.
18
- * *deprecated* See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
19
- * @deprecated See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
22
+ * **Deprecated** Will fail on Android SDK >= 33. Use `requestEnable` instead. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
23
+ * @deprecated Will fail on Android SDK >= 33. Use `requestEnable` instead. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#enable()
20
24
  */
21
25
  enable(): Promise<void>;
22
26
  /**
23
27
  * Disable Bluetooth.
24
28
  * Only available on **Android**.
25
- * *deprecated* See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
26
- * @deprecated See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
29
+ * **Deprecated** Will fail on Android SDK >= 33. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
30
+ * @deprecated Will fail on Android SDK >= 33. See https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
27
31
  */
28
32
  disable(): Promise<void>;
29
33
  /**
@@ -109,8 +113,9 @@ export interface BleClientInterface {
109
113
  * Create a bond with a peripheral BLE device.
110
114
  * Only available on **Android**. On iOS bonding is handled by the OS.
111
115
  * @param deviceId The ID of the device to use (obtained from [requestDevice](#requestDevice) or [requestLEScan](#requestLEScan))
116
+ * @param options Options for plugin call
112
117
  */
113
- createBond(deviceId: string): Promise<void>;
118
+ createBond(deviceId: string, options?: TimeoutOptions): Promise<void>;
114
119
  /**
115
120
  * Report whether a peripheral BLE device is bonded.
116
121
  * Only available on **Android**. On iOS bonding is handled by the OS.
@@ -226,6 +231,7 @@ declare class BleClientClass implements BleClientInterface {
226
231
  disableQueue(): void;
227
232
  initialize(options?: InitializeOptions): Promise<void>;
228
233
  isEnabled(): Promise<boolean>;
234
+ requestEnable(): Promise<void>;
229
235
  enable(): Promise<void>;
230
236
  disable(): Promise<void>;
231
237
  startEnabledNotifications(callback: (value: boolean) => void): Promise<void>;
@@ -241,7 +247,7 @@ declare class BleClientClass implements BleClientInterface {
241
247
  getDevices(deviceIds: string[]): Promise<BleDevice[]>;
242
248
  getConnectedDevices(services: string[]): Promise<BleDevice[]>;
243
249
  connect(deviceId: string, onDisconnect?: (deviceId: string) => void, options?: TimeoutOptions): Promise<void>;
244
- createBond(deviceId: string): Promise<void>;
250
+ createBond(deviceId: string, options?: TimeoutOptions): Promise<void>;
245
251
  isBonded(deviceId: string): Promise<boolean>;
246
252
  disconnect(deviceId: string): Promise<void>;
247
253
  getServices(deviceId: string): Promise<BleService[]>;
@@ -27,6 +27,11 @@ class BleClientClass {
27
27
  });
28
28
  return enabled;
29
29
  }
30
+ async requestEnable() {
31
+ await this.queue(async () => {
32
+ await BluetoothLe.requestEnable();
33
+ });
34
+ }
30
35
  async enable() {
31
36
  await this.queue(async () => {
32
37
  await BluetoothLe.enable();
@@ -148,9 +153,9 @@ class BleClientClass {
148
153
  await BluetoothLe.connect(Object.assign({ deviceId }, options));
149
154
  });
150
155
  }
151
- async createBond(deviceId) {
156
+ async createBond(deviceId, options) {
152
157
  await this.queue(async () => {
153
- await BluetoothLe.createBond({ deviceId });
158
+ await BluetoothLe.createBond(Object.assign({ deviceId }, options));
154
159
  });
155
160
  }
156
161
  async isBonded(deviceId) {