Android Bluetooth Low Energy (BLE) - cooking correctly, part # 2 (connecting / disconnecting)

Part 2
Part 2

Content

Part # 1 (scanning).





Part # 2 (connecting / disconnecting), you are here.









In the  previous article,  we looked at device scanning in detail. This article is about  connectingdisconnecting,  and  discovering services  .





Connect to device

, ,  connectGatt()



. – BluetoothGatt



,  GATT , . ,  connectGatt()



. Android , Android-6 :





BluetoothGatt connectGatt(Context context, boolean autoConnect,
        BluetoothGattCallback callback)
BluetoothGatt connectGatt(Context context, boolean autoConnect,
        BluetoothGattCallback callback, int transport)
      
      



–  transport = TRANSPORT_AUTO



. BLE . TRANSPORT_AUTO



  BLE Bluetooth . , Android . , .  connectGatt()



  transport = TRANSPORT_LE



:





BluetoothGatt gatt = device.connectGatt(context, false, 
    bluetoothGattCallback, TRANSPORT_LE);
      
      



– context



 . –  autoconnect



, (false



) (true



). (false



) Android 30 ( ),  status_code = 133



. . Android  GATT_ERROR



. , . ,  autoconnect = false



Android ( - , ). –  BluetoothGattCallback



 (callback) . , . .





Autoconnect = true

 autoconnect = true



, Android , . : Bluetooth – . , , . , .  BluetoothDevice



   connectGatt



  autoconnect = true



.





BluetoothDevice device = 
bluetoothAdapter.getRemoteDevice("12:34:56:AA:BB:CC");

BluetoothGatt gatt = 
device.connectGatt(context, true, bluetoothGattCallback, TRANSPORT_LE);
      
      



, , Bluetooth (bonding).   , Bluetooth . / Bluetooth ( Airplane ) – ,  autoconnect = true



, .





Autoconnect (bonded) !





, , , .  BluetoothDevice



,  getType



, – TYPE_UNKNOWN



, . , - ( ) .





Android-6 , (autoconnect = false



). , Polidea   . , .





:





  • Android (. - Android-8 ).





  • ;





:





  • , +  autoconnect = false



    . Android  SCAN_MODE_LOW_POWER



    , .





 connectGatt()



, Bluetooth  onConnectionStateChange



, .





– . ( ):





public void onConnectionStateChange(final BluetoothGatt gatt, 
                                    final int status, 
                                    final int newState) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        gatt.discoverServices();
    } else {
        gatt.close();
    }
}
      
      



 newState



   status



. . , , –  discoverServices()



. -  close()



, Android Bluetooth. BLE Android, !





 connectGatt()



, Bluetooth (client interface: clientIf



).





LogCat:





D/BluetoothGatt: connect() - device: B0:49:5F:01:20:XX, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() β€” UUID=0e47c0cf-ef13–4afb-9f54–8cf3e9e808d5
D/BluetoothGatt: onClientRegistered() β€” status=0 clientIf=6
      
      



,  6



   connectGatt()



. () Android 30 ( GATT_MAX_APPS



  ), – Android . , Android 5 6 , , Android . ,  close()



,  connectGatt()



.  close()



, Bluetooth , .





D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() β€” mClientIf=6
      
      



 close()



  ! .





(newState)

 newState



  4 :





  • STATE_CONNECTED







  • STATE_DISCONNECTED







  • STATE_CONNECTING







  • STATE_DISCONNECTING







.  STATE_CONNECTING



STATE_DISCONNECTING



  , . , , , , (. - , ),  close()



  .





(status)

,  status



  , . , , .  GATT_SUCCESS



  , . , - .  GATT_SUCCESS



, Β«- Β»  status



  . ,  BluetoothGatt



  ,  . 133 (GATT_ERROR



). , – Β« - Β». ,  GATT_ERROR



 .





,  newState



  status



,  onConnectionStateChange



:





public void onConnectionStateChange(final BluetoothGatt gatt, 
                                    final int status, 
                                    final int newState) {
if(status == GATT_SUCCESS) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        //  ,    
        gatt.discoverServices();
    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
        //    ( )
        gatt.close();
    } else {
        //     ,    
    }
} else {
   //  ... ,  !
   ...
   gatt.close();
} 
      
      



, . , .





bonding (bondState)

,  onConnectionStateChange



 β€“  bondState



, (bonding) . :





int bondstate = device.getBondState();
      
      



bonding  BOND_NONE



BOND_BONDING



 or BOND_BONDED



. , .





  • BOND_NONE



    , ,  discoverServices()



    ;





  • BOND_BONDING



    , ,  discoverServices()



    , Bluetooth  discoverServices()



    discoverServices()



    , (bonding);





  • BOND_BONDED



    , Android-8 ,  discoverServices()



      . 7 .  Service Changed Characteristic, Bluetooth  discoverServices()



      . 1000-1500 , . ,  Service Changed Characteristic  .





 bondState



   status



  newState



:





if (status == GATT_SUCCESS) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        int bondstate = device.getBondState();
        //  bondState
        if(bondstate == BOND_NONE || bondstate == BOND_BONDED) {
            //   ,  discoverServices  
            int delayWhenBonded = 0;
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
                delayWhenBonded = 1000;
            }
            final int delay = bondstate == BOND_BONDED ? delayWhenBonded : 0;
            discoverServicesRunnable = new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, String.format(Locale.ENGLISH, "discovering services of '%s' with delay of %d ms", getName(), delay));
                    boolean result = gatt.discoverServices();
                    if (!result) {
                        Log.e(TAG, "discoverServices failed to start");
                    }
                    discoverServicesRunnable = null;
                }
            };
            bleHandler.postDelayed(discoverServicesRunnable, delay);
        } else if (bondstate == BOND_BONDING) {
            // Bonding  ,   
            Log.i(TAG, "waiting for bonding to complete");
        }
....
      
      



, . , «», .





  • . , . - 19 (GATT_CONN_TERMINATE_PEER_USER



    );





  • . - 8 (GATT_CONN_TIMEOUT



    );





  • , . - 133 (GATT_ERROR



    ) , ;





  • Bluetooth . - 133 (GATT_ERROR



    );





  •  bonding



      discoverServices



    . .





-  close()



   BluetoothGatt



, . , , , - . UI , - .   .





133 (connecting)

- 133 , . , :





  • ,  close()



      . ,  status=133



    ;





  •  TRANSPORT_LE



       connectGatt()



    ;





  • . Bluetooth . (. : / Bluetooth, Airplane - );





  • advertising .  connectGatt()



      autoconnect = false



      30 ,  status=133



    ;





  • / . ;





133,   ! Android , . 133 ,  close()



  , ! , Android  close()



  . - , – !





(disconnect)

:





  •  disconnect()



    ;





  •  onConnectionStateChange



    ;





  •  close()



    ;





  • gatt ;





 disconnect()



  Bluetooth .  onConnectionStateChange



  Β«disconnectedΒ».





 close()



    BluetoothGattCallback



  Bluetooth .





,  BluetoothGatt



  .





«»

, , :





  •  disconnect()







  •   close()







-. , Β«disconnectedΒ». ,  disconnect()



  ( ),  close()



  ! , Android , .





 disconnect()



,  close()



. , ,  disconnect()



  (  autoconnect = true



). ,  close()



, .





 connectGatt()



,  disconnect()



. ,  onConnectionStateChange



  !  disconnect()



   close()



 (. : 50-100).





:





D/BluetoothGatt: cancelOpen() β€” device: CF:A9:BA:D9:62:9E
      
      



, ,  autoconnect = false



.  autoconnect = true



. , – , .





. :  autoconnect = false



  !





(discovering services)

,  discoverServices()



. Bluetooth    . , , .  onServicesDiscovered.





, :





//    ?   - 
if (status == GATT_INTERNAL_ERROR) {
    Log.e(TAG, "Service discovery failed");
    disconnect();
    return;
}
      
      



(  GATT_INTERNAL_ERROR



  129), , - ( ). .





, :





final List<BluetoothGattService> services = gatt.getServices();
Log.i(TAG, String.format(Locale.ENGLISH,"discovered %d services for '%s'", services.size(), getName()));
//     ( )
...
      
      



.

Bluetooth , . , – . Bluetooth. . , , . : , , , . Java:





private boolean clearServicesCache() {
    boolean result = false;
    try {
        Method refreshMethod = bluetoothGatt.getClass().getMethod("refresh");
        if(refreshMethod != null) {
            result = (boolean) refreshMethod.invoke(bluetoothGatt);
        }
    } catch (Exception e) {
        Log.e(TAG, "ERROR: Could not invoke refresh method");
    }
    return result;
}
      
      



, !





/

, , .





  • 133 , ;





  • ,  onConnectionStateChange



    . , Bluetooth. , . – – ;





  • . , Huawei P8 Lite . (. : !);





  • / . , , . (. : 50-100 ).





: .

/ , – , .





Can't wait to work with BLE? Try  my Blessed for Android library . It takes all the approaches in this article series and makes it easy to work with BLE in your application.












All Articles