Как реализовать JobScheduler для сканирования маяков Bluetooth в фоновом режиме? - PullRequest
0 голосов
/ 01 апреля 2019

Я пишу приложение, которое сканирует маяки Bluetooth, когда оно находится на переднем плане и на заднем плане. У меня есть часть переднего плана, но я не знаю, что делать с фоновой частью, особенно в Android 8.0 и выше, где система не позволяет приложению работать дольше, чем 15 минут в фоновом режиме.

Приложение должно сканировать маяки и получать их MAC-адреса и UUID. Кроме того, он должен получить ответ на сканирование, потому что там есть некоторая информация, которую мне нужно декодировать и сохранить. Я использовал руководство здесь для осуществления сканирования переднего плана с использованием BluetoothLeScanner. Что касается фона, я попытался изменить режим сканирования на LOW_POWER, но ОС убивает приложение примерно через 15 минут. Обратите внимание, что мне не нужна служба переднего плана с постоянным уведомлением, и я в порядке, когда сканирование выполняется только с интервалом ~ 15 минут.

Многие предлагали библиотеку маяков Android, но я не смог найти требуемый beaconLayout для типа используемых маяков, Kontakt Beacon Pro BP16-3, и поэтому библиотека маяков не обнаруживает их.

Информация, которую мне нужно получить от маяков, включает уникальный идентификатор и процент заряда батареи. См. [Здесь] (https://support.kontakt.io/hc/en-gb/articles/206294004-How-to-check-the-battery-level-on-your-beacons) для получения подробной информации о том, где они находятся в ответе на сканирование.

Буду признателен за любую помощь в написании кода для поиска маяков в фоновом режиме, который будет работать на любой версии Android от 6.0 и выше, или помощь в использовании библиотеки маяков с маяком, о котором я упоминал выше.

РЕДАКТИРОВАТЬ: уникальный идентификатор и Bluetooth из ответа на сканирование

Когда я использую BLEScanner для сканирования маяков, я могу использовать ScanResult :: getScanRecord (), чтобы получить объект scanRecord. Затем я использую метод getServiceData () для получения байтового массива, первые 4 байта которого представляют уникальный идентификатор в ASCII, следующие два байта - это версия прошивки в ASCII, и, наконец, последний байт - это процент заряда батареи в шестнадцатеричном формате. Я даже подтвердил уровень заряда батареи в официальном приложении Kontakt, и я уверен, что он правильный.

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

[2, 1, 6, 26, -1, 76, 0, 2, 21, -9, -126, 109, -90, 79, -94, 78, -104, -128, 36, -68, 91, 113, -32, -119, 62, -91, 68, 124, 56, -77, 8, 9, 75, 111, 110, 116, 97, 107, 116, 2, 10, -12, 10, 22, 13, -48, 68, 106, 69, 77, 52, 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0].

Кажется, что байты из индекса 46-49 указывают уникальный идентификатор в ASCII, в данном случае "DjEM". Кроме того, байт в индексе 52 - это процент батареи в десятичном формате; В данном случае это 68.

Кажется, что с помощью сканера BLE я могу сэкономить много головной боли с точки зрения анализа уникального идентификатора и батареи. Однако было бы гораздо сложнее надежно реализовать фоновое сканирование. Следовательно, есть ли способ объединить лучшее из двух и получить библиотеку бекона для анализа уникального идентификатора и процента заряда батареи?

EDIT2: сообщение библиотеки маяков, когда не распознается мой маяк

Библиотека маяков по-прежнему не может обнаружить мой маяк, хотя я использую схемы маяков iBeacon и EddyStone. Это печатает ниже в logcat:

 processing pdu type 16: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 16
This is not a matching Beacon advertisement. (Was expecting 02 15.  The bytes I see are: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000
Ignoring pdu type 01

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 03 апреля 2019

Согласно связанным документам Kontakt.io, уровень заряда батареи также доступен в ответе сканирования. (Примечание: ответ на сканирование не всегда доступен при обнаружении пакета маяка, но он часто доступен - он предоставляется ОС Android и объединяется с данными сканирования при получении ответа на сканирование .) В массиве необработанных результатов сканирования Android ответ на сканирование просто добавляется в конец данных обычного сканирования.

При использовании библиотеки маяков Android также доступен ответ на сканирование, операционная система Android берет ответ на сканирование и сохраняет его в поле имени BluetoothDevice #. (См. здесь ). Библиотека маяков Android, когда она анализирует маяк, копирует это поле в поле имени маяка #. Так что эта информация будет доступна вам в виде строки, если вы сможете проанализировать маяк, и устройство обнаружит ответ на сканирование.

Два препятствия здесь:

  1. Ваш маяк Kontakt.io, похоже, не рекламирует ничего, что на самом деле является рекламой маяка. Возможно, вам потребуется настроить его для рекламы формата iBeacon или, возможно, формата Eddystone-UID. Как только вы сделаете это и настроите библиотеку Android Beacon с этим макетом, она обнаружит ее. Обратите внимание, что показанные байты: processing pdu type 16: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 16 This is not a matching Beacon advertisement. не соответствуют iBeacon или Eddystone. Похоже, это какая-то проприетарная реклама 16-битной службы GATT (тип AD 0x16). Он имеет 16-разрядный служебный UUID 0x0102, который ничем не соответствует в списке Bluetooth SIG стандартных или пользовательских 16-разрядных UUID. Ваше предположение так же хорошо, как мое, что это!

  2. Имя BluetoothDevice # или Beacon # будет строкой. Вам нужно будет преобразовать это в байты, а затем проанализировать уровень заряда батареи, как Kontakt.io описывает в своем документе ответа сканирования.

1 голос
/ 01 апреля 2019

Вы не можете прочитать уровень заряда батареи вашего маяка Kontakt.io, просто сканируя рекламные объявления. Вы должны подключиться к нему с помощью встроенной службы GATT (подробнее об этом ниже.)

Для общего сканирования в фоновом и переднем плане вы, безусловно, можете использовать библиотеку Android Beacon. Вы, вероятно, хотите использовать макет iBeacon:

        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

Но, хотя вышеперечисленное обнаружит ваши маяки, оно не сообщит вам уровень заряда батареи. Это потому, что Kontakt не рекламирует уровень заряда батареи. Чтобы получить его, необходимо отдельно подключиться к сервису GATT с Service UUID = 0x1805, а затем прочитать значение признака с Characteristic UUID = 0x2a19. Это вернет значение в диапазоне 0-100, указывающее уровень заряда батареи в процентах.

Подробную информацию о том, как к этому можно получить, можно найти в разделе «Другие сканеры BLE» Kontakt.io здесь .

ОК, так что это не говорит о том, как написать код для чтения этого значения. Для этого вам необходимо изучить основы программирования Bluetooth LE GATT, что требует некоторого изучения. Хорошее место для начала - здесь. Вам нужно запрограммировать несколько шагов:

  1. Сканирование устройства (библиотека маяков Android выполняет эту часть за вас, используя API-интерфейсы ранжирования, предоставляя вам MAC-адрес устройства в String macAddress = beacon.getBluetoothAddress();)
  2. Подключение к устройству. Если вы использовали библиотеку для обнаружения, вы можете получить ссылку на устройство и подключиться к нему с помощью bluetoothAdapter.getRemoteDevice(macAddress).connectGatt(...)
  3. Откройте для себя услуги
  4. Найдите uuid службы 0x1805 в списке служб из вышеприведенного шага.
  5. Ознакомьтесь с характеристиками обнаруженного сервиса сверху
  6. Найдите список характеристик 0x2a19 uuid в списке признаков из вышеприведенного шага.
  7. Считать значение обнаруженной выше характеристики.

Все вышеперечисленное может быть помещено в запланированное задание для запуска каждые 15 минут с использованием сохраненной копии строк MAC-адреса Bluetooth ближайших маяков.

Это не просто супер, я знаю. Я хотел бы дать вам несколько строк кода, чтобы просто получить этот уровень заряда батареи, но, к сожалению, это не работает таким образом. Добро пожаловать в мир программирования Bluetooth LE GATT!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...