From d6c2576f919032d6d6099e692fdb51ee9a339ce5 Mon Sep 17 00:00:00 2001 From: Tobias Neumann Date: Wed, 1 Nov 2023 18:40:01 +0000 Subject: [PATCH 1/3] isConnectable --- src/android/BLECentralPlugin.java | 23 ++++++++++++++++------- src/android/Peripheral.java | 22 +++++++++++++++++++++- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/android/BLECentralPlugin.java b/src/android/BLECentralPlugin.java index 0d820c64..08953858 100644 --- a/src/android/BLECentralPlugin.java +++ b/src/android/BLECentralPlugin.java @@ -617,13 +617,13 @@ private void onBluetoothStateChange(Intent intent) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); sendBluetoothStateChange(state); if (state == BluetoothAdapter.STATE_OFF) { - // #894 When Bluetooth is physically turned off the whole process might die, so the normal + // #894 When Bluetooth is physically turned off the whole process might die, so the normal // onConnectionStateChange callbacks won't be invoked - + BluetoothManager bluetoothManager = (BluetoothManager) cordova.getActivity().getSystemService(Context.BLUETOOTH_SERVICE); for(Peripheral peripheral : peripherals.values()) { if (!peripheral.isConnected()) continue; - + int connectedState = bluetoothManager.getConnectionState(peripheral.getDevice(), BluetoothProfile.GATT); if (connectedState == BluetoothProfile.STATE_DISCONNECTED) { peripheral.peripheralDisconnected("Bluetooth Disabled"); @@ -1140,7 +1140,12 @@ public void onScanResult(int callbackType, ScanResult result) { if (!alreadyReported) { - Peripheral peripheral = new Peripheral(device, result.getRssi(), result.getScanRecord().getBytes()); + Peripheral peripheral = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + peripheral = new Peripheral(device, result.getRssi(), result.getScanRecord().getBytes(),result.isConnectable()); + }else{ + peripheral = new Peripheral(device, result.getRssi(), result.getScanRecord().getBytes()); + } peripherals.put(device.getAddress(), peripheral); if (discoverCallback != null) { @@ -1152,7 +1157,11 @@ public void onScanResult(int callbackType, ScanResult result) { } else { Peripheral peripheral = peripherals.get(address); if (peripheral != null) { - peripheral.update(result.getRssi(), result.getScanRecord().getBytes()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + peripheral.update(result.getRssi(), result.getScanRecord().getBytes(),result.isConnectable()); + }else{ + peripheral.update(result.getRssi(), result.getScanRecord().getBytes()); + } if (reportDuplicates && discoverCallback != null) { PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, peripheral.asJSONObject()); pluginResult.setKeepCallback(true); @@ -1279,7 +1288,7 @@ private void stopScan() { LOG.d(TAG, "Stopping Scan"); try { final BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); - if (bluetoothLeScanner != null) + if (bluetoothLeScanner != null) bluetoothLeScanner.stopScan(leScanCallback); } catch (Exception e) { LOG.e(TAG, "Exception stopping scan", e); @@ -1468,7 +1477,7 @@ public void onReceive(Context context, Intent intent) { if (ACTION_BOND_STATE_CHANGED.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Peripheral peripheral = peripherals.get(device.getAddress()); - + if (peripheral != null) { int bondState = intent.getIntExtra(EXTRA_BOND_STATE, BluetoothDevice.ERROR); int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1); diff --git a/src/android/Peripheral.java b/src/android/Peripheral.java index 9b7b15a9..46acf821 100644 --- a/src/android/Peripheral.java +++ b/src/android/Peripheral.java @@ -53,6 +53,7 @@ public class Peripheral extends BluetoothGattCallback { private BluetoothDevice device; private byte[] advertisingData; + private boolean isConnectable = true; private int advertisingRSSI; private boolean autoconnect = false; private boolean connected = false; @@ -83,6 +84,13 @@ public Peripheral(BluetoothDevice device) { } + public Peripheral(BluetoothDevice device, int advertisingRSSI, byte[] scanRecord, boolean isConnectable) { + this.device = device; + this.advertisingRSSI = advertisingRSSI; + this.advertisingData = scanRecord; + this.isConnectable = isConnectable; + } + public Peripheral(BluetoothDevice device, int advertisingRSSI, byte[] scanRecord) { this.device = device; @@ -280,6 +288,10 @@ public JSONObject asJSONObject() { if (advertisingRSSI != FAKE_PERIPHERAL_RSSI) { json.put("rssi", advertisingRSSI); } + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + json.put("connectable", this.isConnectable); + } } catch (JSONException e) { // this shouldn't happen e.printStackTrace(); } @@ -515,11 +527,19 @@ public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { } // Update rssi and scanRecord. + public void update(int rssi, byte[] scanRecord, boolean isConnectable) { + this.advertisingRSSI = rssi; + this.advertisingData = scanRecord; + this.isConnectable = isConnectable; + } + + public void update(int rssi, byte[] scanRecord) { this.advertisingRSSI = rssi; this.advertisingData = scanRecord; } + public void updateRssi(int rssi) { advertisingRSSI = rssi; } @@ -1024,7 +1044,7 @@ public void bond(CallbackContext callbackContext, BluetoothAdapter bluetoothAdap } } } - + @RequiresPermission("android.permission.BLUETOOTH_CONNECT") public void unbond(CallbackContext callbackContext) { final int bondState = device.getBondState(); From b5f57b4b4709b7d24c9261612442deee731f1d2f Mon Sep 17 00:00:00 2001 From: Tobias Neumann Date: Thu, 2 Nov 2023 08:54:14 +0100 Subject: [PATCH 2/3] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ac9dcb37..149beb99 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ Function `scan` scans for BLE devices. The success callback is called each time "id": "BD922605-1B07-4D55-8D09-B66653E51BBA", "rssi": -79, "advertising": /* ArrayBuffer or map */ + "connectable":"true" /*Only on Android >= API Level 26*/ } Advertising information format varies depending on your platform. See [Advertising Data](#advertising-data) for more information. From 9b171f0bdaf3c04232459a2740638e1f27a3d0cf Mon Sep 17 00:00:00 2001 From: Tobias Neumann Date: Thu, 2 Nov 2023 08:58:05 +0100 Subject: [PATCH 3/3] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 149beb99..37cd9fe7 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,6 @@ Function `scan` scans for BLE devices. The success callback is called each time "id": "BD922605-1B07-4D55-8D09-B66653E51BBA", "rssi": -79, "advertising": /* ArrayBuffer or map */ - "connectable":"true" /*Only on Android >= API Level 26*/ } Advertising information format varies depending on your platform. See [Advertising Data](#advertising-data) for more information. @@ -1309,6 +1308,7 @@ the [ble-central-advertisements](https://github.com/jospete/ble-central-advertis "id": "00:1A:7D:DA:71:13", "advertising": ArrayBuffer, "rssi": -37 + "connectable":"true" /*Only on Android >= API Level 26*/ } Convert the advertising info to a Uint8Array for processing. `var adData = new Uint8Array(peripheral.advertising)`. You application is responsible for parsing all the information out of the advertising ArrayBuffer using the [GAP type constants](https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile). For example to get the service data from the advertising info, I [parse the advertising info into a map](https://github.com/don/ITP-BluetoothLE/blob/887511c375b1ab2fbef3afe210d6a6b7db44cee9/phonegap/thermometer_v2/www/js/index.js#L18-L39) and then get the service data to retrieve a [characteristic value that is being broadcast](https://github.com/don/ITP-BluetoothLE/blob/887511c375b1ab2fbef3afe210d6a6b7db44cee9/phonegap/thermometer_v2/www/js/index.js#L93-L103).