Как подключить устройство Android к устройству iOS через BLE (Bluetooth Low Energy)
Я пытаюсь создать приложение, использующее новый Bluetooth Low Energy API для Android. Для этого я начал с образца BLE, приходящего с уровнем API уровня 18.
Поскольку я читал, что Android не может выступать в качестве периферии, я помещаю телефон Android в центральный режим, просматривая устройства BLE вокруг него. Для этой цели я провел несколько испытаний с помощью Nordic Platform, имитирующей датчик сердца. Все работает идеально!
После этого я пытаюсь выбрать iPhone (iOS 7 beta 4) и поместить его в Peripheral way и имитировать датчик сердечного ритма как предыдущее тестирование. Приложение Android может видеть устройство и подключаться к нему. Но после того, как соединение активировано, два устройства отключаются друг от друга через 3-4 секунды. В дополнение к этому, когда я вызываю DiscoverServices() на стороне Android, никакой обратный вызов не срабатывает! В некоторых случаях устройство Android получает событие "Подключено", даже если чип IOS Bluetooth выключен. Это очень странно. Чтобы доказать это, я поместил Nordic Board в центральном режиме, и я правильно смог подключиться к устройству iOS без проблем.
Что это может быть? Есть некоторые ограничения на Android или iOS, которые не позволяют подключаться с Android до iOS или наоборот?
Спасибо.
EDIT: после некоторого жесткого тестирования я поднял вопрос на странице AOSP. Это можно проверить здесь
Ответы
Ответ 1
Добавление сводки для справки:
Что это может быть? Есть некоторые ограничения на Android или iOS, которые не позволяют подключаться с Android до iOS или наоборот?
При подключении к серверу GATT, который рекламируется как устройство с двойной связью (BLE и BR/EDR), вызывая connectGatt (...), флаг TRANSPORT_AUTO, который добавляется внутри страны, делает Android по умолчанию режимом BR/EDR (ссылка).
Возможны следующие обходные пути:
- Периферийная сторона: прекратите рекламировать возможности BR/EDR, настроив
соответствующие флаги (ссылка)
- Центральная сторона: задайте параметр транспорта для
TRANSPORT_LE, вызвав скрытую версию connectGatt(), используя
отражение
Пример:
public void connectToGatt(BluetoothDevice device) {
...
Method m = device.getClass().getDeclaredMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);
int transport = device.getClass().getDeclaredField("TRANSPORT_LE").getInt(null); // LE = 2, BREDR = 1, AUTO = 0
BluetoothGatt mGatt = (BluetoothGatt) m.invoke(device, this, false, gattCallback, transport);
...
}
Редактировать 4/2016
Как отметил Arbel Israel, Google представил перегруженную версию connectGatt (...), который позволяет указать транспорт в Android M.
Ответ 2
Я написал простой рабочий пример, довольно простой и включил его в open source на Github: https://github.com/GitGarage. Пока он протестирован только с Android Nexus 9 и iPhone 5, но я полагаю, что он также будет работать с Nexus 6 и различными типами iPhone. Пока что он настроен явно для связи между одним Android и одним iPhone, но я полагаю, что он способен делать гораздо больше.
Ответ 3
Возможно, немного задержка, но, возможно, ваша боль может быть немного облегчена;)
Мы много экспериментировали с кросс-платформенными соединениями BLE (iOS ↔ Android) и узнали, что по-прежнему существует много несовместимостей и проблем с подключением. Помимо нестабильности Android, вы также должны учитывать, что на сегодняшний день не так много Android-устройств фактически поддерживают режим периферийных устройств BLE.
Поэтому, если ваш прецедент связан с функцией, и вам нужен только базовый обмен данными, я бы предложил посмотреть на Frameworks и библиотеки, которые могут обеспечить взаимодействие между платформами для вас, без необходимости создавать его с нуля.
Например: http://p2pkit.io или google рядом
Отказ от ответственности: я работаю на Uepaa, разрабатывая p2pkit.io для Android и iOS.