【问题标题】:How to enable multiple BLE characteristic notifications on Xamarin/Android?如何在 Xamarin/Android 上启用多个 BLE 特征通知?
【发布时间】:2016-04-11 03:42:52
【问题描述】:

我正在尝试使用 Xamarin/Android 为多个 BLE 特性启用通知,但似乎无法这样做。如果我尝试一次启用多个事件,该应用似乎停止接收任何 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);

【问题讨论】:

标签: xamarin notifications xamarin.android bluetooth-lowenergy characteristics


【解决方案1】:

除了您找到的解决方案:请注意,您不能听无限数量的特征。最大值限制在 android 源代码中硬编码为 BTA_GATTC_NOTIF_REG_MAX

因此,您的应用所依赖的通知特性的数量不应超过您支持的最低 Android 版本的最大数量。

【讨论】:

    【解决方案2】:

    有很多可用的选项,但我习惯于用下面的逻辑来实现这个特性,它会真正起作用,请尝试一下:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多