9

我想使用Xamarin/Android啓用多個BLE特性的通知,但似乎無法這樣做。如果我嘗試一次啓用多個BLE事件,該應用程序似乎不會再收到任何BLE事件。如何在Xamarin/Android上啓用多個BLE特徵通知?

任何人都可以確認這是否可能使用Tamarin/Android。我們有一個原生iOS應用程序,可以在啓用多個通知的情況下正常工作是我們使用的基本步驟如下:

  1. 掃描設備
  2. 連接到設備
  3. 發現服務
  4. 對於通過特性每個發現的服務迭代並啓用所需
  5. 過程中的那些BLE回調中的每個異步回調事件

任何時候我們嘗試啓用多於我們不再收到任何事件的一個特徵。

我也一直無法找到任何啓​​用多個特徵的例子。

我希望我錯過了關於在這裏使用Xamarin/Android API的一些基本知識。

public override void OnServicesDiscovered (BluetoothGatt gatt, GattStatus status) 
{ 
    base.OnServicesDiscovered (gatt, status); 
    foreach (BluetoothGattService service in gatt.Services) { 
     string uuid = service.Uuid.ToString().ToUpper(); 
     if (uuid.Equals (BLEServices.HRService.ToUpper())) { 
      _Adap.LogMessage ("HRService discovered"); 
      foreach(BluetoothGattCharacteristic characteristic in service.Characteristics) { 
       string c_uuid = characteristic.Uuid.ToString().ToUpper(); 
       _Adap.LogMessage (" HRCharacteristic: " + c_uuid); 

       if (c_uuid.Equals(_Adap.useCharacteristic.ToUpper())) { 
        _Adap.LogMessage (" enabling HRCharacteristic"); 
        gatt.SetCharacteristicNotification(characteristic, true); 
        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read); 
        characteristic.AddDescriptor (descriptor); 
        descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray()); 
        gatt.WriteDescriptor (descriptor); 
        _Adap.StartTimer(); 
       } 
      } 

     } else if (uuid.Equals (BLEServices.BatteryService.ToUpper())) { 
      _Adap.LogMessage ("BatteryService discovered"); 
      foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) { 
       string c_uuid = characteristic.Uuid.ToString().ToUpper(); 
       _Adap.LogMessage (" BatteryService: " + c_uuid); 

       if (c_uuid.Equals (_Adap.useCharacteristic.ToUpper())) { 
        _Adap.LogMessage (" reading batteryCharacteristic"); 
        // This may only be reported when the battery level changes so get the level first by doing a read 
        gatt.ReadCharacteristic (characteristic); 

        //gatt.SetCharacteristicNotification (characteristic, true); 
        //BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read); 
        //characteristic.AddDescriptor (descriptor); 
        //descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray()); 
        //gatt.WriteDescriptor (descriptor); 
       } 
      } 
     } else if (uuid.Equals (BLEServices.DeviceInfoService.ToUpper())) { 
      _Adap.LogMessage ("DeviceInfoService discovered"); 
      foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) { 
       string c_uuid = characteristic.Uuid.ToString().ToUpper(); 
       _Adap.LogMessage (" DeviceInfoService: " + c_uuid); 
       if (c_uuid.Equals (BLEServices.kModelNumberCharacteristicUuidString.ToUpper())) { 
        //gatt.ReadCharacteristic (characteristic); 
       } 
      } 
     } else if (uuid.Equals (BLEServices.kHxM2CustomServiceUuidString.ToUpper())) { 
      _Adap.LogMessage ("HxM2CustomService discovered"); 
      foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) { 
       string c_uuid = characteristic.Uuid.ToString().ToUpper(); 
       _Adap.LogMessage (" HxM2CustomCharacteristic: " + c_uuid); 

       if (c_uuid.Equals (_Adap.useCharacteristic.ToUpper())) { 
        _Adap.LogMessage (" enabling HxM2 characteristic: "+_Adap.useCharacteristic); 
        gatt.SetCharacteristicNotification (characteristic, true); 
        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read); 
        characteristic.AddDescriptor (descriptor); 
        descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray()); 
        gatt.WriteDescriptor (descriptor); 
        // Start a timer to make sure that we can recover if we never receive any data from the device 
        _Adap.StartTimer(); 
       } 

      } 
     } else { 
      _Adap.LogMessage ("Unknown Service "+uuid+" discovered"); 
     } 
    } 
} 

誰能解釋一下下面的線是

BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read); 
characteristic.AddDescriptor (descriptor); 
descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray()); 
gatt.WriteDescriptor (descriptor); 
+1

最後,我發現一些作品:HTTP://計算器。 com/questions/17910322/android-ble-api-gatt-notification-not-received http://stackoverflow.com/questions/21278993/android-ble-how-to-read-multiple-characteristics –

回答

2

除了您找到解決方案:要知道,你可以不聽無限數量的特點。 Android源代碼中的最大值被硬編碼爲BTA_GATTC_NOTIF_REG_MAX

所以你的應用不應依賴於比更最小支持的android版本的通知特徵的最大數量。

0

有選擇重新availble的數量,但我用下面的邏輯來實現這一特性,它會真的工作,請嘗試:

public ConnectThread(BluetoothDevice device, BluetoothDeviceConnector deviceConnector) 
      { 
       _mmDevice = device; 
       BluetoothSocket tmp = null; 
       _deviceConnector = deviceConnector; 

       Log.Info(Tag, "calling device.createRfcommSocket with channel 1 ..."); 
       try 
       { 
        //tmp = device.CreateRfcommSocketToServiceRecord(UUID.FromString("00001101-0000-1000-8000-00805F9B34FB")); 
        //tmp = device.CreateRfcommSocketToServiceRecord(device.GetUuids()[0].Uuid); 
        deviceConnector.BluetoothAdapter.CancelDiscovery(); 

        var createRfcommSocket = JNIEnv.GetMethodID(device.Class.Handle, "createInsecureRfcommSocket", "(I)Landroid/bluetooth/BluetoothSocket;"); 
        var socket = JNIEnv.CallObjectMethod(device.Handle, createRfcommSocket, new JValue(1)); 
        tmp = GetObject<BluetoothSocket>(socket, JniHandleOwnership.TransferLocalRef); 

        var uuidList = device.GetUuids(); 
        if (uuidList != null) 
        { 
         foreach (var uuid in uuidList) 
         { 
          try 
          { 
           tmp = device.CreateInsecureRfcommSocketToServiceRecord(uuid.Uuid); 
           tmp.Connect(); 
           if (tmp.IsConnected) 
            break; 
          } 
          catch (Exception) 
          { 
           // ignored 
          } 
         } 
        } 

        Log.Info(Tag, "setting socket to result of createRfcommSocket"); 
       } 
       catch (Exception e) 
       { 
        Log.Error(Tag, e.Message, e); 
       } 
       _mmSocket = tmp; 
      }