@capacitor-community/bluetooth-le 7.2.0 → 8.0.0-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.
Files changed (55) hide show
  1. package/CapacitorCommunityBluetoothLe.podspec +17 -17
  2. package/LICENSE +21 -21
  3. package/Package.swift +28 -0
  4. package/README.md +68 -161
  5. package/android/build.gradle +71 -68
  6. package/android/src/main/AndroidManifest.xml +22 -22
  7. package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/BluetoothLe.kt +1094 -1070
  8. package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/Conversion.kt +51 -51
  9. package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/Device.kt +771 -767
  10. package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/DeviceList.kt +28 -28
  11. package/android/src/main/java/com/capacitorjs/community/plugins/bluetoothle/DeviceScanner.kt +189 -189
  12. package/dist/docs.json +906 -849
  13. package/dist/esm/bleClient.d.ts +278 -278
  14. package/dist/esm/bleClient.js +361 -347
  15. package/dist/esm/bleClient.js.map +1 -1
  16. package/dist/esm/config.d.ts +53 -53
  17. package/dist/esm/config.js +2 -2
  18. package/dist/esm/conversion.d.ts +56 -34
  19. package/dist/esm/conversion.js +134 -84
  20. package/dist/esm/conversion.js.map +1 -1
  21. package/dist/esm/definitions.d.ts +352 -313
  22. package/dist/esm/definitions.js +42 -42
  23. package/dist/esm/definitions.js.map +1 -1
  24. package/dist/esm/index.d.ts +5 -5
  25. package/dist/esm/index.js +5 -5
  26. package/dist/esm/plugin.d.ts +2 -2
  27. package/dist/esm/plugin.js +4 -4
  28. package/dist/esm/queue.d.ts +3 -3
  29. package/dist/esm/queue.js +17 -17
  30. package/dist/esm/queue.js.map +1 -1
  31. package/dist/esm/timeout.d.ts +1 -1
  32. package/dist/esm/timeout.js +9 -9
  33. package/dist/esm/validators.d.ts +1 -1
  34. package/dist/esm/validators.js +11 -11
  35. package/dist/esm/validators.js.map +1 -1
  36. package/dist/esm/web.d.ts +57 -56
  37. package/dist/esm/web.js +403 -340
  38. package/dist/esm/web.js.map +1 -1
  39. package/dist/plugin.cjs.js +967 -837
  40. package/dist/plugin.cjs.js.map +1 -1
  41. package/dist/plugin.js +967 -837
  42. package/dist/plugin.js.map +1 -1
  43. package/ios/{Plugin → Sources/BluetoothLe}/Conversion.swift +83 -83
  44. package/ios/{Plugin → Sources/BluetoothLe}/Device.swift +423 -423
  45. package/ios/Sources/BluetoothLe/DeviceListView.swift +121 -0
  46. package/ios/{Plugin → Sources/BluetoothLe}/DeviceManager.swift +503 -401
  47. package/ios/{Plugin → Sources/BluetoothLe}/Logging.swift +8 -8
  48. package/ios/{Plugin → Sources/BluetoothLe}/Plugin.swift +775 -682
  49. package/ios/{Plugin → Sources/BluetoothLe}/ThreadSafeDictionary.swift +15 -13
  50. package/ios/Tests/BluetoothLeTests/ConversionTests.swift +55 -0
  51. package/ios/Tests/BluetoothLeTests/PluginTests.swift +27 -0
  52. package/package.json +115 -101
  53. package/ios/Plugin/Info.plist +0 -24
  54. package/ios/Plugin/Plugin.h +0 -10
  55. package/ios/Plugin/Plugin.m +0 -41
@@ -1,28 +1,28 @@
1
- package com.capacitorjs.community.plugins.bluetoothle
2
-
3
- import android.bluetooth.BluetoothDevice
4
-
5
- class DeviceList {
6
- private val devices: ArrayList<BluetoothDevice> = ArrayList()
7
-
8
- fun addDevice(device: BluetoothDevice): Boolean {
9
- // contains compares devices by their address
10
- if (!devices.contains(device)) {
11
- devices.add(device)
12
- return true
13
- }
14
- return false
15
- }
16
-
17
- fun getDevice(index: Int): BluetoothDevice {
18
- return devices[index]
19
- }
20
-
21
- fun getCount(): Int {
22
- return devices.size
23
- }
24
-
25
- fun clear() {
26
- devices.clear()
27
- }
28
- }
1
+ package com.capacitorjs.community.plugins.bluetoothle
2
+
3
+ import android.bluetooth.BluetoothDevice
4
+
5
+ class DeviceList {
6
+ private val devices: ArrayList<BluetoothDevice> = ArrayList()
7
+
8
+ fun addDevice(device: BluetoothDevice): Boolean {
9
+ // contains compares devices by their address
10
+ if (!devices.contains(device)) {
11
+ devices.add(device)
12
+ return true
13
+ }
14
+ return false
15
+ }
16
+
17
+ fun getDevice(index: Int): BluetoothDevice {
18
+ return devices[index]
19
+ }
20
+
21
+ fun getCount(): Int {
22
+ return devices.size
23
+ }
24
+
25
+ fun clear() {
26
+ devices.clear()
27
+ }
28
+ }
@@ -1,190 +1,190 @@
1
- package com.capacitorjs.community.plugins.bluetoothle
2
-
3
- import android.annotation.SuppressLint
4
- import android.app.AlertDialog
5
- import android.bluetooth.BluetoothAdapter
6
- import android.bluetooth.BluetoothDevice
7
- import android.bluetooth.le.ScanCallback
8
- import android.bluetooth.le.ScanFilter
9
- import android.bluetooth.le.ScanResult
10
- import android.bluetooth.le.ScanSettings
11
- import android.content.Context
12
- import android.os.Handler
13
- import android.os.Looper
14
- import android.widget.ArrayAdapter
15
- import com.getcapacitor.Logger
16
-
17
-
18
- class ScanResponse(
19
- val success: Boolean,
20
- val message: String?,
21
- val device: BluetoothDevice?,
22
- )
23
-
24
- class DisplayStrings(
25
- val scanning: String,
26
- val cancel: String,
27
- val availableDevices: String,
28
- val noDeviceFound: String,
29
- )
30
-
31
- @SuppressLint("MissingPermission")
32
- class DeviceScanner(
33
- private val context: Context,
34
- bluetoothAdapter: BluetoothAdapter,
35
- private val scanDuration: Long?,
36
- private val displayStrings: DisplayStrings,
37
- private val showDialog: Boolean,
38
- ) {
39
- companion object {
40
- private val TAG = DeviceScanner::class.java.simpleName
41
- }
42
-
43
- private var isScanning = false
44
- private val bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
45
- private var savedCallback: ((ScanResponse) -> Unit)? = null
46
- private var scanResultCallback: ((ScanResult) -> Unit)? = null
47
- private var adapter: ArrayAdapter<String>? = null
48
- private val deviceList = DeviceList()
49
- private var deviceStrings: ArrayList<String> = ArrayList()
50
- private var dialog: AlertDialog? = null
51
- private var dialogHandler: Handler? = null
52
- private var stopScanHandler: Handler? = null
53
- private var allowDuplicates: Boolean = false
54
- private var namePrefix: String = ""
55
-
56
- private val scanCallback: ScanCallback = object : ScanCallback() {
57
- override fun onScanResult(callbackType: Int, result: ScanResult) {
58
- super.onScanResult(callbackType, result)
59
- if (namePrefix.isNotEmpty()) {
60
- if (result.device.name == null || !result.device.name.startsWith(namePrefix)) {
61
- return
62
- }
63
- }
64
- val isNew = deviceList.addDevice(result.device)
65
- if (showDialog) {
66
- if (isNew) {
67
- dialogHandler?.post {
68
- deviceStrings.add("[${result.device.address}] ${result.device.name ?: "Unknown"}")
69
- adapter?.notifyDataSetChanged()
70
- }
71
- }
72
- } else {
73
- if (allowDuplicates || isNew) {
74
- scanResultCallback?.invoke(result)
75
- }
76
- }
77
- }
78
- }
79
-
80
- fun startScanning(
81
- scanFilters: List<ScanFilter>,
82
- scanSettings: ScanSettings,
83
- allowDuplicates: Boolean,
84
- namePrefix: String,
85
- callback: (ScanResponse) -> Unit,
86
- scanResultCallback: ((ScanResult) -> Unit)?
87
- ) {
88
- this.savedCallback = callback
89
- this.scanResultCallback = scanResultCallback
90
- this.allowDuplicates = allowDuplicates
91
- this.namePrefix = namePrefix
92
-
93
- deviceStrings.clear()
94
- deviceList.clear()
95
- if (!isScanning) {
96
- setTimeoutForStopScanning()
97
- Logger.debug(TAG, "Start scanning.")
98
- isScanning = true
99
- bluetoothLeScanner?.startScan(scanFilters, scanSettings, scanCallback)
100
- if (showDialog) {
101
- dialogHandler = Handler(Looper.getMainLooper())
102
- showDeviceList()
103
- } else {
104
- savedCallback?.invoke(
105
- ScanResponse(
106
- true, "Started scanning.", null
107
- )
108
- )
109
- savedCallback = null
110
- }
111
- } else {
112
- stopScanning()
113
- savedCallback?.invoke(
114
- ScanResponse(
115
- false, "Already scanning. Stopping now.", null
116
- )
117
- )
118
- savedCallback = null
119
- }
120
- }
121
-
122
- fun stopScanning() {
123
- stopScanHandler?.removeCallbacksAndMessages(null)
124
- stopScanHandler = null
125
- if (showDialog) {
126
- dialogHandler?.post {
127
- if (deviceList.getCount() == 0) {
128
- dialog?.setTitle(displayStrings.noDeviceFound)
129
- } else {
130
- dialog?.setTitle(displayStrings.availableDevices)
131
- }
132
- }
133
- }
134
- Logger.debug(TAG, "Stop scanning.")
135
- isScanning = false
136
- bluetoothLeScanner?.stopScan(scanCallback)
137
- }
138
-
139
- private fun showDeviceList() {
140
- dialogHandler?.post {
141
- val builder = AlertDialog.Builder(context)
142
- builder.setTitle(displayStrings.scanning)
143
- builder.setCancelable(true)
144
- adapter = ArrayAdapter(
145
- context, android.R.layout.simple_selectable_list_item, deviceStrings
146
- )
147
- builder.setAdapter(adapter) { dialog, index ->
148
- stopScanning()
149
- dialog.dismiss()
150
- val device = deviceList.getDevice(index)
151
- savedCallback?.invoke(ScanResponse(true, device.address, device))
152
- savedCallback = null
153
- }
154
- builder.setNegativeButton(displayStrings.cancel) { dialog, _ ->
155
- stopScanning()
156
- dialog.cancel()
157
- savedCallback?.invoke(
158
- ScanResponse(
159
- false, "requestDevice cancelled.", null
160
- )
161
- )
162
- savedCallback = null
163
- }
164
- builder.setOnCancelListener { dialog ->
165
- stopScanning()
166
- dialog.cancel()
167
- savedCallback?.invoke(
168
- ScanResponse(
169
- false, "requestDevice cancelled.", null
170
- )
171
- )
172
- savedCallback = null
173
- }
174
- dialog = builder.create()
175
- dialog?.show()
176
- }
177
- }
178
-
179
- private fun setTimeoutForStopScanning() {
180
- if (scanDuration != null) {
181
- stopScanHandler = Handler(Looper.getMainLooper())
182
- stopScanHandler?.postDelayed(
183
- {
184
- stopScanning()
185
- }, scanDuration
186
- )
187
- }
188
- }
189
-
1
+ package com.capacitorjs.community.plugins.bluetoothle
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.app.AlertDialog
5
+ import android.bluetooth.BluetoothAdapter
6
+ import android.bluetooth.BluetoothDevice
7
+ import android.bluetooth.le.ScanCallback
8
+ import android.bluetooth.le.ScanFilter
9
+ import android.bluetooth.le.ScanResult
10
+ import android.bluetooth.le.ScanSettings
11
+ import android.content.Context
12
+ import android.os.Handler
13
+ import android.os.Looper
14
+ import android.widget.ArrayAdapter
15
+ import com.getcapacitor.Logger
16
+
17
+
18
+ class ScanResponse(
19
+ val success: Boolean,
20
+ val message: String?,
21
+ val device: BluetoothDevice?,
22
+ )
23
+
24
+ class DisplayStrings(
25
+ val scanning: String,
26
+ val cancel: String,
27
+ val availableDevices: String,
28
+ val noDeviceFound: String,
29
+ )
30
+
31
+ @SuppressLint("MissingPermission")
32
+ class DeviceScanner(
33
+ private val context: Context,
34
+ bluetoothAdapter: BluetoothAdapter,
35
+ private val scanDuration: Long?,
36
+ private val displayStrings: DisplayStrings,
37
+ private val showDialog: Boolean,
38
+ ) {
39
+ companion object {
40
+ private val TAG = DeviceScanner::class.java.simpleName
41
+ }
42
+
43
+ private var isScanning = false
44
+ private val bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
45
+ private var savedCallback: ((ScanResponse) -> Unit)? = null
46
+ private var scanResultCallback: ((ScanResult) -> Unit)? = null
47
+ private var adapter: ArrayAdapter<String>? = null
48
+ private val deviceList = DeviceList()
49
+ private var deviceStrings: ArrayList<String> = ArrayList()
50
+ private var dialog: AlertDialog? = null
51
+ private var dialogHandler: Handler? = null
52
+ private var stopScanHandler: Handler? = null
53
+ private var allowDuplicates: Boolean = false
54
+ private var namePrefix: String = ""
55
+
56
+ private val scanCallback: ScanCallback = object : ScanCallback() {
57
+ override fun onScanResult(callbackType: Int, result: ScanResult) {
58
+ super.onScanResult(callbackType, result)
59
+ if (namePrefix.isNotEmpty()) {
60
+ if (result.device.name == null || !result.device.name.startsWith(namePrefix)) {
61
+ return
62
+ }
63
+ }
64
+ val isNew = deviceList.addDevice(result.device)
65
+ if (showDialog) {
66
+ if (isNew) {
67
+ dialogHandler?.post {
68
+ deviceStrings.add("[${result.device.address}] ${result.device.name ?: "Unknown"}")
69
+ adapter?.notifyDataSetChanged()
70
+ }
71
+ }
72
+ } else {
73
+ if (allowDuplicates || isNew) {
74
+ scanResultCallback?.invoke(result)
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ fun startScanning(
81
+ scanFilters: List<ScanFilter>,
82
+ scanSettings: ScanSettings,
83
+ allowDuplicates: Boolean,
84
+ namePrefix: String,
85
+ callback: (ScanResponse) -> Unit,
86
+ scanResultCallback: ((ScanResult) -> Unit)?
87
+ ) {
88
+ this.savedCallback = callback
89
+ this.scanResultCallback = scanResultCallback
90
+ this.allowDuplicates = allowDuplicates
91
+ this.namePrefix = namePrefix
92
+
93
+ deviceStrings.clear()
94
+ deviceList.clear()
95
+ if (!isScanning) {
96
+ setTimeoutForStopScanning()
97
+ Logger.debug(TAG, "Start scanning.")
98
+ isScanning = true
99
+ bluetoothLeScanner?.startScan(scanFilters, scanSettings, scanCallback)
100
+ if (showDialog) {
101
+ dialogHandler = Handler(Looper.getMainLooper())
102
+ showDeviceList()
103
+ } else {
104
+ savedCallback?.invoke(
105
+ ScanResponse(
106
+ true, "Started scanning.", null
107
+ )
108
+ )
109
+ savedCallback = null
110
+ }
111
+ } else {
112
+ stopScanning()
113
+ savedCallback?.invoke(
114
+ ScanResponse(
115
+ false, "Already scanning. Stopping now.", null
116
+ )
117
+ )
118
+ savedCallback = null
119
+ }
120
+ }
121
+
122
+ fun stopScanning() {
123
+ stopScanHandler?.removeCallbacksAndMessages(null)
124
+ stopScanHandler = null
125
+ if (showDialog) {
126
+ dialogHandler?.post {
127
+ if (deviceList.getCount() == 0) {
128
+ dialog?.setTitle(displayStrings.noDeviceFound)
129
+ } else {
130
+ dialog?.setTitle(displayStrings.availableDevices)
131
+ }
132
+ }
133
+ }
134
+ Logger.debug(TAG, "Stop scanning.")
135
+ isScanning = false
136
+ bluetoothLeScanner?.stopScan(scanCallback)
137
+ }
138
+
139
+ private fun showDeviceList() {
140
+ dialogHandler?.post {
141
+ val builder = AlertDialog.Builder(context)
142
+ builder.setTitle(displayStrings.scanning)
143
+ builder.setCancelable(true)
144
+ adapter = ArrayAdapter(
145
+ context, android.R.layout.simple_selectable_list_item, deviceStrings
146
+ )
147
+ builder.setAdapter(adapter) { dialog, index ->
148
+ stopScanning()
149
+ dialog.dismiss()
150
+ val device = deviceList.getDevice(index)
151
+ savedCallback?.invoke(ScanResponse(true, device.address, device))
152
+ savedCallback = null
153
+ }
154
+ builder.setNegativeButton(displayStrings.cancel) { dialog, _ ->
155
+ stopScanning()
156
+ dialog.cancel()
157
+ savedCallback?.invoke(
158
+ ScanResponse(
159
+ false, "requestDevice cancelled.", null
160
+ )
161
+ )
162
+ savedCallback = null
163
+ }
164
+ builder.setOnCancelListener { dialog ->
165
+ stopScanning()
166
+ dialog.cancel()
167
+ savedCallback?.invoke(
168
+ ScanResponse(
169
+ false, "requestDevice cancelled.", null
170
+ )
171
+ )
172
+ savedCallback = null
173
+ }
174
+ dialog = builder.create()
175
+ dialog?.show()
176
+ }
177
+ }
178
+
179
+ private fun setTimeoutForStopScanning() {
180
+ if (scanDuration != null) {
181
+ stopScanHandler = Handler(Looper.getMainLooper())
182
+ stopScanHandler?.postDelayed(
183
+ {
184
+ stopScanning()
185
+ }, scanDuration
186
+ )
187
+ }
188
+ }
189
+
190
190
  }