Per quanto ne so, di avviare una procedura di abbinamento a BLE ci sono due modi:
1) via api 19 e fino si può iniziare l'accoppiamento chiamando il mBluetoothDevice.createBond()
. Non è necessario essere connessi con il dispositivo BLE remoto per avviare il processo di accoppiamento.
2) Quando si tenta di eseguire un'operazione Gatt, prendiamo per esempio il metodo
mBluetoothGatt.readCharacteristic(characteristic)
Se il dispositivo remoto BLE deve essere legato a fare qualsiasi comunicazione poi quando il callback
onCharacteristicRead( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
viene chiamato il suo valore status
parametro sarà pari a uno o GATT_INSUFFICIENT_AUTHENTICATION
GATT_INSUFFICIENT_ENCRYPTION
, e non è uguale a GATT_SUCCESS
. Se ciò accade, la procedura di accoppiamento inizierà automaticamente.
Ecco un esempio per sapere quando non riesce una volta che il onCharacteristicRead
callback viene chiamato
@Override
public void onCharacteristicRead(
BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status)
{
if(BluetoothGatt.GATT_SUCCESS == status)
{
// characteristic was read successful
}
else if(BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION == status ||
BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION == status)
{
/*
* failed to complete the operation because of encryption issues,
* this means we need to bond with the device
*/
/*
* registering Bluetooth BroadcastReceiver to be notified
* for any bonding messages
*/
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mActivity.registerReceiver(mReceiver, filter);
}
else
{
// operation failed for some other reason
}
}
Altre persone che citano che questa operazione si avvia la procedura di abbinamento automatico: Android Bluetooth Low Energy Pairing
e questo è come il ricevitore può essere implementato
private final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
{
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
switch(state){
case BluetoothDevice.BOND_BONDING:
// Bonding...
break;
case BluetoothDevice.BOND_BONDED:
// Bonded...
mActivity.unregisterReceiver(mReceiver);
break;
case BluetoothDevice.BOND_NONE:
// Not bonded...
break;
}
}
}
};
Questa risposta è stata di grande aiuto per me! Stavo riscontrando problemi con Android 6.0 e versioni successive che facevano notifiche di abbinamento che l'utente non avrebbe nemmeno visto (il vecchio Android ha fatto delle belle finestre di dialogo, che volevo per tutti i casi). Una cosa che ho fatto in modo diverso rispetto a te era chiamare semplicemente createBond() dal get-go (cioè prima ancora di connetterti al dispositivo), se il dispositivo.getBondState() == BluetoothDevice.BOND_NONE. Questo perché non stavo ottenendo "GATT_INSUFFICIENT_AUTHENTICATION" durante la lettura della caratteristica; il sistema operativo l'avrebbe trattenuto mentre inviava una notifica per accoppiare il dispositivo. – cclogg
Cosa succede se il mio ** onCharacteristicRead() ** non viene mai chiamato? –
@IgorGanapolsky Se sei sicuro al 100% che stai chiamando questo metodo mBluetoothGatt.readCharacteristic (caratteristica), verrà richiamato il callback a meno che non ci sia un problema con il dispositivo remoto che sia collegato al codice o che la connessione sia andata persa (se questo è nel caso dovessi ricevere una richiamata diversa, ma al momento non ricordo il nome). Se qualcuno conosce diversi, faccelo sapere. – Kiki