BLE с Android 5.0: как заставить устройство действовать как центральный и сервер?

Я использую два устройства Android 5.0 для связи через Bluetooth с низким энергопотреблением, и я не хочу:

  • Устройство 1 в качестве центрального и серверного.

  • Устройство 2 в качестве периферийного устройства и клиента.


Это поведение, которое я хотел бы достичь:

1) Устройство 2 запускает рекламу (роль периферии).

2) Устройство 1 начинает сканирование (центральная роль) и получает рекламное устройство (объект BluetoothDevice) с помощью метода onScanResult ScanCallback.

3) Теперь я хочу, чтобы рекламное устройство (Устройство 2) было уведомлено о том, что оно было отсканировано, и могло получить BluetoothDevice, связанное с Устройством 1.

4) Устройство 1 имеет экземпляр BluetoothGattServer. Устройство 2 теперь будет вызывать connectGatt(Context context, boolean autoConnect, обратный вызов BluetoothGattCallback) на устройстве 1, чтобы получить экземпляр BluetoothGatt.

5) В конце концов, Устройство 1 — это Сервер, а Устройство 2 — Клиент.


До сих пор я обнаружил, что на шаге 2, когда устройство 1 удерживает BluetoothDevice для устройства 2, оно может подключаться только как клиент, как на шаге 4, используя connectGatt.

Я мог бы использовать BluetoothGattServer, определенный в устройстве 1, и вызвать: gattServer.connect(устройство BluetoothDevice, логическое автоподключение) с устройством Устройство 2.

Но как Устройство 2 будет уведомлено о том, что оно было подключено?

И как мне получить экземпляр BluetoothGatt на Устройстве 2, если я не могу вызвать connectGatt(Context, boolean, BluetoothGattCallback) на BluetoothDevice< /эм>?

Заранее спасибо за вашу помощь !

Некоторая документация:

BluetoothGattServer

устройство Bluetooth


person Thomas W    schedule 24.05.2015    source источник
comment
Привет, Томас, ты нашел решение своей проблемы?   -  person Hollerweger    schedule 29.01.2016
comment
Привет Холлервегер, к сожалению, я так и не нашел решения. Это было для проекта в университете, в итоге я продемонстрировал свою работу с двумя телефонами и объяснил, почему он не может работать с этим конкретным микроконтроллером. Я закончил с тех пор и не уделял этому больше своего времени. Однако, возможно, стоит проверить, изменилось ли что-нибудь в Android 6. Пожалуйста, дайте мне знать, если вы что-то выясните! ;)   -  person Thomas W    schedule 30.01.2016


Ответы (2)


1) Устройство 2 запускает рекламу (роль периферии).

Периферийная роль будет рекламироваться, обязательно добавьте CONNECTABLE

     AdvertiseSettings.Builder settingBuilder = new AdvertiseSettings.Builder();
     settingBuilder.setConnectable(true);

И запустить рекламу соответственно.

2) Устройство 1 начинает сканирование (центральная роль) и получает рекламное устройство (объект BluetoothDevice) с помощью метода onScanResult ScanCallback.

Отлично, теперь вызовите connectGatt на этом устройстве (периферийном устройстве), убедитесь, что вы останавливаете рекламу после получения необходимого устройства, иначе вы в конечном итоге отправите несколько команд подключения.

3) Теперь я хочу, чтобы рекламное устройство (Устройство 2) было уведомлено о том, что оно было отсканировано, и могло получить BluetoothDevice, связанное с Устройством 1.

Когда вы вызываете connectGatt из центральной/клиентской роли, ваше периферийное устройство получит уведомление в своем BluetoothGattServerCallback'onConnectionStateChange.

здесь вы узнаете, что соединение установлено. хотя вам необходимо зарегистрировать gatt Service с характеристиками на периферийной стороне.

4) Устройство 1 имеет экземпляр BluetoothGattServer. Устройство 2 теперь будет вызывать connectGatt(Context context, boolean autoConnect, обратный вызов BluetoothGattCallback) на устройстве 1, чтобы получить экземпляр BluetoothGatt.

Неверно. Устройство 1 инициирует подключение, как я указал в пункте 3. Будет вызван метод onConnectionStateChange обоих устройств, чтобы узнать, что подключение установлено.

5) В конце концов, Устройство 1 — это Сервер, а Устройство 2 — Клиент.

Неверно, Устройство 2 — периферийное (серверное), устройство 1 — мониторное (клиентское)

person AAnkit    schedule 27.05.2015
comment
Я уже реализовал это решение, и мое приложение отлично работает с обеих сторон. Проблема в том, что это не соответствует тому поведению, которого я пытаюсь добиться. Что я пытаюсь сделать с устройством 2, так это эмулировать определенный микроконтроллер, который НЕ может сканировать устройства, а может только рекламировать. (Поэтому Устройство 2 должно быть периферийным GAP, а Устройство 1 должно быть центральным GAP). Однако мой телефон (устройство 1) отправляет данные на микроконтроллер (устройство 2), что делает устройство 1 сервером Gatt, а устройство 2 — клиентом Gatt. - person Thomas W; 27.05.2015
comment
Вышеприведенное соответствует определениям, приведенным в разделе Роли и обязанности здесь: BLE Android Как вы думаете, какую пользу может принести следующий метод? BluetoothGattServer.connect (устройство BluetoothDevice, логическое значение autoConnect) - person Thomas W; 27.05.2015
comment
BluetoothGattServer.connect можно использовать для подключения, если autoConnection имеет значение true, а роль сервера/монитора видит событие разъединения. - person AAnkit; 27.05.2015

Вы должны немного повернуть его. Сканер подключается к рекламодателю. Dev1 сканирует dev2 adv и сканирует ответ. тогда dev1 должен подключиться. Dev2 получит обратный вызов при подключении. Нет обратного вызова, когда кто-то слышит вашу рекламу или запрашивает ответ на сканирование на Android. Вместо этого отметьте 0x14 «Список 16-битных UUID для запроса услуг» от btsig, если вы хотите объявить запрос на подключение к вам серверов с определенной службой. Немного необычно видеть, как это используется.

person henrik    schedule 25.05.2015
comment
Вы имеете в виду, что dev1 должен открыть BluetoothGattServer, а затем вызвать gattServer.connect(device2,boolean)? Соединение работает во время отладки dev1, когда я это делаю. Проблема в том, что единственный способ получить экземпляр BluetoothGatt в dev2 и реализовать обратный вызов — через BluetoothDevice.connectGatt(contect,boolean,callback). И я не могу сделать это в dev2, не зная, кто такой dev1. - person Thomas W; 26.05.2015