简体   繁体   English

如何读取我的BLE设备的所有特性值?

[英]How can read all characteristic's value of my BLE device?

I'm building an app with Android Studio that can read the value from a device BLE. 我正在使用Android Studio构建可从设备BLE读取值的应用程序。 This device, have 4 services. 该设备有4个服务。 The fourth services have 3 characteristic. 第四项服务具有3个特征。 I want to read the all characteristic of this fourth service. 我想阅读第四项服务的所有特征。

This device, can send more information, so I want that the application can storage the all information that arrive from device BLE. 该设备可以发送更多信息,因此我希望该应用程序可以存储从设备BLE到达的所有信息。

So this is my code: 这是我的代码:

@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);


        }




    };
}

with this code, I can read one the first characteristic of my service and only one value of the first characteristic. 使用此代码,我可以读取我的服务的第一个特征,而只能读取第一个特征的一个值。

I want to read all value of all characteristic automatically of my BLE device. 我想自动读取我的BLE设备的所有特性的所有值。 How can I change my code to do this ? 如何更改我的代码以执行此操作?

You can achive multiple reads with the following code: First create a List 您可以使用以下代码实现多次读取:首先创建一个列表

private int ReadQueueIndex;
private List<BluetoothGattCharacteristic> ReadQueue;

In onServicesDiscovered add characteristics in ReadQueue: onServicesDiscoveredonServicesDiscovered添加特征:

ReadQueue = new ArrayList<>();
ReadQueue.add(characteristicsList.get(2));        
ReadQueue.add(characteristicsList.get(1));            
ReadQueue.add(characteristicsList.get(0));
ReadQueueIndex = 2;
ReadCharacteristics(ReadQueueIndex);

Create ReadCharacteristics method 创建ReadCharacteristics方法

private void ReadCharacteristics(int index){
   bluetoothGatt.readCharacteristic(ReadQueue.get(index));
}

Then in your onCharacteristicRead callback: 然后在您的onCharacteristicRead回调中:

String value =  Arrays.toString(characteristic.getValue());
if(characteristic.getUuid().equals(characteristicsList.get(0).getUuid())){
  Log.i("Characteristic 0:", value);
} else if(characteristic.getUuid().equals(characteristicsList.get(1).getUuid())){
  Log.i("Characteristic 1:", value);
} else if(characteristic.getUuid().equals(characteristicsList.get(2).getUuid())){
  Log.i("Characteristic 2:", value);
}
ReadQueue.remove(ReadQueue.get(ReadQueueIndex));
if (ReadQueue.size() >= 0) {
    ReadQueueIndex--;
    if (ReadQueueIndex == -1) {
       Log.i("Read Queue: ", "Complete");
    }
    else {
       ReadCharacteristics(ReadQueueIndex);
    }
 }

Hope its helpful. 希望对您有所帮助。

First store your read characteristics, and ghatt objects. 首先存储您的读取特征和ghatt对象。 and if you want to read a value from characteristic call this method: 如果要从特征读取值,请调用此方法:

private fun readDataFromCharacteristic(ghatt: BluetoothGhatt? , characteristic:BluetoothGhattCharacteristic) {
        Log.d(TAG, " readDataFromCharacteristic")
        ghatt?.readCharacteristic(characteristic)
    }

if you call readCharacteristic(characteristic) on ghatt , below method will give result 如果您在ghatt上调用readCharacteristic(characteristic),则以下方法将给出结果

override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {}

You should not read whole list of characteristics in onServicesDiscovered method, because ble device could havent a time to performs all requests from android client. 您不应该在onServicesDiscovered方法中阅读特征的完整列表,因为ble设备可能没有时间执行来自android客户端的所有请求。

I offer you: 我为您提供:

  1. Keep all characteristics in onServicesDiscovered 将所有特征保留在onServicesDiscovered中
  2. By turns try reading characteristics in onCharacteristicRead method (at first you read first characteristic, after characteristic has been read, try reading second characteristic and ... ) 依次尝试使用onCharacteristicRead方法读取特征(首先读取第一个特征,读取特征后,尝试读取第二个特征,然后...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM