Contenido
Parte # 2 (conectar / desconectar), estás aquí.
En el artículo anterior, analizamos el escaneo de dispositivos en detalle. Este artículo trata sobre cómo conectar , desconectar y descubrir servicios .
Conectarse al dispositivo
, , 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
. AndroidSCAN_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()
, BluetoothdiscoverServices()
.discoverServices()
, (bonding);
BOND_BONDED
, Android-8 ,discoverServices()
. 7 . Service Changed Characteristic, BluetoothdiscoverServices()
. 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 ).
: .
/ , – , .
¿No puede esperar a trabajar con BLE? Prueba mi biblioteca Blessed para Android . Toma todos los enfoques de esta serie de artículos y facilita el trabajo con BLE en su aplicación.