@@ -105,8 +105,12 @@ private static final class DiscoveredDevice {
105105 private Runnable connectTimeoutRunnable ;
106106 private PluginCall pendingConnectCall ;
107107 private String connectedDeviceId ;
108+
109+ // Cached per connection
108110 private BluetoothGattCharacteristic writeCharacteristic = null ;
109111 private boolean writeNoResponseSupported = false ;
112+ private int cachedWriteType = BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT ;
113+
110114 private final Queue <PluginCall > pendingStartNotificationCalls = new ConcurrentLinkedQueue <>();
111115 private volatile boolean servicesDiscovered = false ;
112116
@@ -328,32 +332,19 @@ public void disconnect(PluginCall call) {
328332 @ PluginMethod
329333 public void write (PluginCall call ) {
330334 if (!ensureConnected (call )) return ;
331-
332335 final BluetoothGatt gatt = bluetoothGatt ;
333336 if (gatt == null || !servicesDiscovered ) { call .reject ("Not connected" ); return ; }
334337
335338 final BluetoothGattCharacteristic target = writeCharacteristic ;
336339 if (target == null ) { call .reject ("Write characteristic not available" ); return ; }
337340
338- // Params and payload decode only
339341 final String value = call .getString ("value" , call .getString ("data" ));
340342 final String encoding = call .getString ("encoding" , "base64" );
341- final boolean withoutResponse = call .getBoolean ("withoutResponse" , false );
342-
343343 final byte [] payload ;
344- try {
345- payload = decodePayload (value , encoding );
346- } catch (IllegalArgumentException ex ) {
347- call .reject ("Failed to decode payload: " + ex .getMessage ());
348- return ;
349- }
350-
351- // Minimal branch based on cached capability (no property reads here)
352- final int writeType = (withoutResponse && writeNoResponseSupported )
353- ? BluetoothGattCharacteristic .WRITE_TYPE_NO_RESPONSE
354- : BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT ;
344+ try { payload = decodePayload (value , encoding ); }
345+ catch (IllegalArgumentException ex ) { call .reject ("Failed to decode payload: " + ex .getMessage ()); return ; }
355346
356- final boolean ok = submitWrite (gatt , target , payload , writeType );
347+ final boolean ok = submitWrite (gatt , target , payload , cachedWriteType );
357348 if (ok ) {
358349 JSObject result = new JSObject ();
359350 result .put ("bytesSent" , payload .length );
@@ -646,6 +637,7 @@ private void cleanupGatt() {
646637 bluetoothGatt = null ;
647638 writeCharacteristic = null ;
648639 writeNoResponseSupported = false ;
640+ cachedWriteType = BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT ;
649641 connectedDeviceId = null ;
650642 servicesDiscovered = false ;
651643 }
@@ -948,6 +940,7 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
948940 } else if (newState == BluetoothProfile .STATE_DISCONNECTED ) {
949941 connectionState .set (ConnectionState .DISCONNECTED );
950942 cleanupGatt ();
943+ // notifyConnectionState("disconnected", null);
951944 failConnect (status == BluetoothGatt .GATT_SUCCESS ? "Disconnected" : "Connect status: " + status );
952945 }
953946 }
@@ -959,33 +952,29 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
959952
960953 writeCharacteristic = null ;
961954 writeNoResponseSupported = false ;
955+ cachedWriteType = BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT ;
962956
963957 try {
964958 for (BluetoothGattService svc : gatt .getServices ()) {
965- BluetoothGattCharacteristic preferred = null ;
966- BluetoothGattCharacteristic fallback = null ;
967-
959+ BluetoothGattCharacteristic preferred = null , fallback = null ;
968960 for (BluetoothGattCharacteristic ch : svc .getCharacteristics ()) {
969- final int props = ch .getProperties ();
970- if ((props & BluetoothGattCharacteristic .PROPERTY_WRITE_NO_RESPONSE ) != 0 ) {
971- preferred = ch ; // best option
972- break ;
973- }
974- if (fallback == null && (props & BluetoothGattCharacteristic .PROPERTY_WRITE ) != 0 ) {
975- fallback = ch ;
976- }
961+ int props = ch .getProperties ();
962+ if ((props & BluetoothGattCharacteristic .PROPERTY_WRITE_NO_RESPONSE ) != 0 ) { preferred = ch ; break ; }
963+ if (fallback == null && (props & BluetoothGattCharacteristic .PROPERTY_WRITE ) != 0 ) fallback = ch ;
977964 }
978-
979- final BluetoothGattCharacteristic chosen = (preferred != null ) ? preferred : fallback ;
965+ BluetoothGattCharacteristic chosen = (preferred != null ) ? preferred : fallback ;
980966 if (chosen != null ) {
981967 writeCharacteristic = chosen ;
982968 writeNoResponseSupported =
983- (chosen .getProperties () & BluetoothGattCharacteristic .PROPERTY_WRITE_NO_RESPONSE ) != 0 ;
969+ (chosen .getProperties () & BluetoothGattCharacteristic .PROPERTY_WRITE_NO_RESPONSE ) != 0 ;
970+ cachedWriteType = writeNoResponseSupported
971+ ? BluetoothGattCharacteristic .WRITE_TYPE_NO_RESPONSE
972+ : BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT ;
984973 break ;
985974 }
986975 }
987976 } catch (Exception ignored ) {
988- // leave writeCharacteristic null; write() will report unavailable
977+ // leave writeCharacteristic null; write() will reject
989978 }
990979
991980 flushPendingStartNotificationCalls ();
0 commit comments