Flutter: широковещательный маяк с iOS на iOS не работает

В настоящее время я создаю приложение, которое превращает мое устройство в маяк, одновременно сканируя другие маяки. Так что я могу отслеживать маяки, с которыми контактировал.


Проблема

Текущий Я тестировал этот код в следующих сценариях:

  1. Android TO Android - Передача и сканирование - Работает хорошо
  2. С Android на IOS - широковещательная передача и сканирование в обоих направлениях - Работает хорошо
  3. IOS на IOS - не работает (когда я транслирую UUID с устройства IOS, я вижу UUID на устройстве Android, но не вижу UUID на любом устройстве IOS.)

  • Я установил этот фрагмент кода на 4 устройства (2 Android и 2 IOS). Теперь все 4 устройства транслируют разные UUID и одновременно слушают.
  • На устройствах Android я вижу 1 UUID другого устройства Android и 2 UUID устройств IOS.
  • В устройствах IOS я вижу 2 UUID Android, но не вижу UUID другого устройства IOS.

Это очень странно, и мне нужна помощь, чтобы решить эту проблему!


В настоящее время я реализовал 2 пакета для достижения этой функциональности:

(1) Для трансляции

beacon_broadcast: https://pub.dev/packages/beacon_broadcast версия: 0.2.1

(2) Для сканирования других маяков

flutter_blue: https://pub.dev/packages/flutter_blue версия: 0.6.3 + 1


Это немного о моем коде

(1) Для трансляции

String UUID = 'DYNAMIC_UUID_FOR_EACH_DEVICE';
static const MAJOR_ID = 1;
static const MINOR_ID = 30;
static const TRANSMISSION_POWER = -59;
static const IDENTIFIER = 'com.example.myDeviceRegion';
static const LAYOUT = 'm:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24';
static const MANUFACTURER_ID = 0x004c;

BeaconBroadcast beaconBroadcast = BeaconBroadcast();
beaconBroadcast
   .setUUID(UUID)
   .setMajorId(MAJOR_ID)
   .setMinorId(MINOR_ID)
   .setTransmissionPower(TRANSMISSION_POWER)
   .setIdentifier(IDENTIFIER)
   .setLayout(LAYOUT)
   .setManufacturerId(MANUFACTURER_ID);
   .start();

(2) Для сканирования

FlutterBlue flutterBlue = FlutterBlue.instance;
flutterBlue.startScan(timeout: Duration(seconds: 30));
flutterBlue.scanResults.listen((List<ScanResult> results) {
  print('scanningListen...');
  for (ScanResult result in results) {
      result.advertisementData.manufacturerData.forEach((item, hexcodeAsArray) => {
         print("calculated UUID String : " + calculateHexFromArray(v));
         _addToScanResult(calculateHexFromArray(v));
      });
  }
}
String calculateHexFromArray(decimalArray) {
  String uuid = '';
  decimalArray.forEach((i) => {uuid += i.toRadixString(16).padLeft(2, '0')});
  String uuid1 = uuid.substring(4, uuid.length - 12);
  return uuid1.toUpperCase();
}

person Darshit Hedpara    schedule 28.03.2020    source источник


Ответы (1)


К сожалению, вы не можете использовать FlutterBlue для обнаружения пакетов iBeacon на iOS.

Почему? FlutterBlue использует необработанное сканирование Bluetooth для обнаружения маяков, что под капотом означает использование собственных API-интерфейсов сканирования CoreBluetooth на iOS. Apple блокирует API CoreBluetooth от чтения необработанных байтов любой рекламы Bluetooth, декодируемой как реклама iBeacon. Хотя это может показаться безумным, скорее всего, это вызвано ошибочными соображениями безопасности со стороны Apple. Подробнее читайте в моем сообщении в блоге: CoreBluetooth Doesn Я не хочу видеть iBeacons

Два варианта исправить это:

  1. Переключитесь на использование формата AltBeacon. Просто измените LAYOUT = 'm:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25'; и MANUFACTURER_ID = 0x0118;

    Это будет работать, но имеет тот недостаток, что рекламу можно обнаружить только на iOS на переднем плане.

  2. Переключитесь на использование другой библиотеки обнаружения на iOS, которая использует CoreLocation (единственный API, позволяющий обнаруживать iBeacon на iOS) вместо CoreBluetooth. Это означает отказ от FlutterBlue в пользу FlutterBeacon или подобного.

person davidgyoung    schedule 28.03.2020
comment
Спасибо за быстрый ответ, я попробую вышеуказанные решения и дам вам знать. @davidgyoung - person Darshit Hedpara; 28.03.2020
comment
Привет @davidgyoung, я уже пробовал вариант 1, но теперь он не работает. Я попробовал вариант 2 в соответствии с вашим предложением и установил плагин flutter_becaon. IOS очень хорошо обнаруживает, только если я передаю один и тот же UUID. В моем случае UUID будет другим, и я хочу их получить. Не могли бы вы помочь мне с этим? - person Darshit Hedpara; 29.03.2020
comment
Привет, Дэвид, у меня тоже есть аналогичная проблема, почему на ios я не могу обнаружить, и я хотел бы сканировать только на основе диапазона, возможно ли это? - person newbie; 25.04.2020
comment
@newbie, задайте новый вопрос, и я буду рад ответить. - person davidgyoung; 25.04.2020
comment
@davidgyoung по запросу Я разместил вопрос здесь stackoverflow.com/questions/61442488/. Спасибо. - person newbie; 26.04.2020
comment
@davidgyoung Я использую предложенную вами библиотеку FlutterBeacon. Я также рекламирую iBeacon, как вы предложили stackoverflow.com/a/60892464/3455666. Все работает нормально, за исключением того, что маяк не работает в фоновом режиме для Android 8+. Было бы полезно, если бы вы могли проверить мой вопрос: stackoverflow.com/q/62232482/3455666 и предложить какое-то обходное решение. Спасибо. - person iAkshay; 07.06.2020