¿Cómo puedo leer el valor de todas las características de mi dispositivo BLE?
Estoy creando una aplicación con Android Studio que puede leer el valor de un dispositivo BLE. Este dispositivo, tiene 4 servicios. Los cuartos servicios tienen 3 características. Quiero leer todas las características de este cuarto servicio.
Este dispositivo puede enviar más información, por lo que quiero que la aplicación pueda almacenar toda la información que llega del dispositivo BLE.
Entonces este es mi código:
@TargetApi(21)
public class BLEActivity extends BaseActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
String mCurrentService;
TextView tvBLE;
ImageButton ibDownload;
BluetoothDevice currDevice;
private int id = 1000;
public SensorDataAdapter adapter;
final BLEActivity classe = this;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ble);
mHandler = new Handler();
//mSensors = db.getAllSensorTypes();
//BLUETOOTH LOW ENERGY NON SUPPORTATO
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
//VERIFICO SE IL BLUETOOTH DEL DISPOSITIVO E' ABILITATO
//OPPURE NO. SE NON è ABILITATO DEVO CHIEDERE ALL'UTENTE DI ATTIVARLO
// Ensures Bluetooth is available on the device and it is enabled. If not,
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
ibDownload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(currDevice!=null){
mGatt = currDevice.connectGatt(getBaseContext(), false, gattCallback);
scanLeDevice(false);// will stop after first device detection
}
}
});
}
private void scanLeDevice(final boolean enable) {
if (enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}, SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner.startScan(filters, settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("callbackType", String.valueOf(callbackType));
Log.i("result", result.toString());
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i("onLeScan", device.toString());
connectToDevice(device);
}
});
}
};
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
currDevice = device;
ibDownload.setEnabled(true);
ibDownload.setImageResource(R.drawable.download_ok);
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
Log.i("gattCallback", "STATE_CONNECTED");
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED");
break;
default:
Log.e("gattCallback", "STATE_OTHER");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
List<BluetoothGattService> services = gatt.getServices();
Log.i("onServicesDiscovered", services.toString());
;
for(BluetoothGattService srv : services){
// if(srv.getUuid().toString().equals(mSensors.get(1).getServUid())){
mCurrentService = srv.getUuid().toString();
//RECUPERO SOLO IL SERVIZIO CON UID 1130
if(mCurrentService.contains("1130")){
List<BluetoothGattCharacteristic> mListCars = srv.getCharacteristics();
//leggo le caratteristiche del servizio che cerco
for(BluetoothGattCharacteristic bc : mListCars){
//recupero solo le caratteristiche 1131, 1132
if(bc.getUuid().toString().contains("1131") ||
bc.getUuid().toString().contains("1132")){
//LEGGO LE 2 CARATTERISTICHE NECESSARIE
gatt.readCharacteristic(srv.getCharacteristic(bc.getUuid()));
}
}
}else{
Log.i("SERVIZIO NON CORRETTO", "SERVIZIO NON CORRETTO");
}
// }
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
Log.i("onCharacteristicRead", characteristic.toString());
SensorData mSenData = new SensorData();
mSenData.setValue(characteristic.getStringValue(0));
Log.i("LETTURA DATI ", mSenData.getValue());
mSenData.setIdType(++id);
mSenData.setCharacteristic(characteristic.getUuid().toString());
mSenData.setValueTimestamp(db.getDateTime());
db.insertSensorData(mSenData);
}
};
}
con este código, puedo leer una de las primeras características de mi servicio y solo un valor de la primera característica.
Quiero leer todos los valores de todas las características automáticamente de mi dispositivo BLE. ¿Cómo puedo cambiar mi código para hacer esto?