11

Xamarin/Android を使用して複数の BLE 特性の通知を有効にしようとしていますが、そうできないようです。一度に複数の 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);
4

2 に答える 2

4

見つけた解決策のほかに: 無制限の数の特性を聞くことはできないことに注意してください。最大値は、Android ソースにハードコードされて に制限されていBTA_GATTC_NOTIF_REG_MAXます。

したがって、アプリは、サポートされている Android の最小バージョンの通知特性の最大数を超えて依存するべきではありません。

于 2016-05-01T22:16:21.357 に答える
0

利用可能なオプションは多数ありますが、私はこの特性のために実装するロジックを以下に使用していましたが、実際に機能するので試してみてください:

 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;
            } 
于 2016-06-08T12:57:58.030 に答える