9

Próbuję włączyć powiadomienia dla więcej niż jednej charakterystyki BLE za pomocą Xamarin/Androida, ale wydaje się, że nie można tego zrobić. Wygląda na to, że aplikacja przestaje otrzymywać jakiekolwiek zdarzenia BLE, jeśli spróbuję włączyć więcej niż jedną naraz.Jak włączyć wielokrotne powiadomienia BLE na Xamarin/Android?

Czy ktoś może potwierdzić, czy jest to możliwe za pomocą Tamarin/Android. Mamy natywną aplikację na iOS, która działa dobrze z włączonymi wieloma powiadomieniami. Podstawowe kroki, których używamy, są następujące:

  1. skanowania dla urządzenia
  2. połączyć się z urządzeniem
  3. Odkrywanie usługi
  4. Dla każdej odkrytej iteracyjne usług poprzez charakterystykę i włączyć te, które są wymagane
  5. Process każde asynchroniczne zdarzenie zwrotne w wywołaniu zwrotnym BLE

Za każdym razem, gdy próbujemy włączyć powiadomienia na więcej niż jedna cecha nie otrzymujemy już żadnych zdarzeń.

Nie znalazłem również przykładów, w których włączono więcej niż jedną cechę.

Mam nadzieję, że po prostu przegapiłem coś fundamentalnego na temat korzystania z interfejsów API Xamarin/Android.

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"); 
     } 
    } 
} 

Może ktoś wyjaśnić, co się następujące wiersze są dla

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

Wreszcie znalazłem coś, co działa: http: // stackoverflow. com/questions/17910322/android-ble-api-gatt-notification-not-received http://stackoverflow.com/questions/21278993/android-ble-how-to-read-multiple-characteristics –

Odpowiedz

2

Obok swojej znalazł rozwiązanie: Należy pamiętać, że nie można słuchać nieograniczonej liczby charakterystyk. Maksymalna jest ograniczona na stałe w źródle Androida do BTA_GATTC_NOTIF_REG_MAX.

więc aplikacja nie powinna opierać się na więcej niż maksymalna liczba powiadomień o minimalnej obsługiwanej wersji Androida.

0

Istnieje wiele opcji ponownego availble ale kiedyś poniżej logiki wprowadzić na tej charakterystyce i to naprawdę działa spróbuj go:

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; 
      } 
Powiązane problemy