Android BLE неожиданно и неоднократно подключается к периферийным устройствам

Я разрабатываю Android-приложение, которое взаимодействует с устройством BLE и недавно наткнулось на какое-то странное поведение: когда приложение отключается от устройства, через несколько секунд создается другое соединение.

Я уже более подробно описываю проблему и сосредоточен на профилях Bluetooth MAP и PBAP; они появляются в журналах вокруг точки выпуска. Я не уверен, однако, если это первопричина, и я не нашел обходного пути.

Приложение поддерживает API 23-25. На сегодняшний день я столкнулся с проблемой только в телефонах с SIM-картами, которые снова указывают на PBAP, поскольку многие телефоны, похоже, поддерживают этот профиль только с SIM-картой. Я еще не смог воспроизвести API 23, но пока эти тестовые телефоны не имеют SIM-карт.

Устройство BLE не имеет ничего общего с автомобильным приложением и не имеет возможности иметь дело с контактами или сообщениями. Я не намеренно включил это в приложение. Кроме того, между моим приложением и устройством нет спаривания/склеивания, и устройство не поддерживает спаривание/склеивание.

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

Единственное, что, по-видимому, разрешает проблему в краткосрочной перспективе - это цикл Bluetooth на телефоне или принудительное прекращение процесса обмена Bluetooth. Я не верю, что реконнекторы возвращаются сами по себе, но обычно они появляются снова, когда пользователь подключается - отключается от устройства через мое приложение.

Я не очень хорошо знаком с PBAP/MAP, поэтому не знаю, как они активируются или, если возможно, как их отключить. Я не уверен, являются ли они виновниками, но они появляются в журналах в момент повторного подключения.

Ниже приведены операторы журнала вокруг точки разъединения и последующего повторного подключения. Имя интерфейса здесь "Foo04" с MAC = B0: B4: 48: E8: FA: 04.

03-31 14:27:44.305 D/RxBle#Radio(14105):  STARTED RxBleRadioOperationDisconnect(186827491)
03-31 14:27:44.319 D/BluetoothManager(14105): getConnectionState()
03-31 14:27:44.320 D/BluetoothManager(14105): getConnectedDevices
03-31 14:27:44.332 D/BluetoothGatt(14105): cancelOpen() - device: B0:B4:48:E8:FA:04
03-31 14:27:44.334 D/BtGatt.GattService(13168): clientDisconnect() - address=B0:B4:48:E8:FA:04, connId=5
03-31 14:27:44.339 E/bt_btif (13168): bta_gattc_mark_bg_conn unable to find the bg connection mask for: b0:b4:48:e8:fa:04
03-31 14:27:44.340 D/BtGatt.GattService(13168): onDisconnected() - clientIf=5, connId=5, address=B0:B4:48:E8:FA:04
03-31 14:27:44.341 D/BluetoothGatt(14105): onClientConnectionState() - status=0 clientIf=5 device=B0:B4:48:E8:FA:04
03-31 14:27:44.342 D/RxBle#BluetoothGatt(14105): onConnectionStateChange newState=0 status=0
03-31 14:27:44.345 D/RxBle#Radio(14105): FINISHED RxBleRadioOperationDisconnect(186827491)
03-31 14:27:44.352 D/BluetoothGatt(14105): close()
03-31 14:27:44.352 D/BluetoothGatt(14105): unregisterApp() - mClientIf=5
03-31 14:27:44.354 D/BtGatt.GattService(13168): unregisterClient() - clientIf=5
03-31 14:27:45.376 W/bt_l2cap(13168): l2cble_process_conn_update_evt: Error status: 22
03-31 14:27:45.377 W/bt_btif (13168): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
03-31 14:27:45.377 W/bt_btif (13168): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
03-31 14:27:45.377 I/bt_btm_sec(13168): btm_sec_disconnected clearing pending flag handle:13 reason:22
03-31 14:27:45.381 E/BluetoothRemoteDevices(13168): state12newState1
03-31 14:27:45.393 D/BluetoothMapService(13168): onReceive
03-31 14:27:45.393 D/BluetoothMapService(13168): onReceive: android.bluetooth.device.action.ACL_DISCONNECTED
03-31 14:27:45.402 D/BluetoothPbapReceiver(13168): PbapReceiver onReceive action = 
03-31 14:27:45.404 D/BluetoothPbapReceiver(13168): Calling start service with action = null
03-31 14:27:45.405 I/TrustAgent.Tracker(15208): [BluetoothConnectionTracker] Bluetooth disconnect broadast for Foo04 B0:B4:48:E8:FA:04
03-31 14:27:46.407 W/bt_smp  (13168): smp_br_connect_callback is called on unexpected transport 2
03-31 14:27:46.408 W/bt_btif (13168): bta_dm_acl_change info: 0x0
03-31 14:27:46.408 I/bt_bta_dm(13168): bta_dm_gatt_disc_result service_id_uuid_len=2 
03-31 14:27:46.408 I/bt_bta_dm(13168): bta_dm_gatt_disc_result service_id_uuid_len=2 
03-31 14:27:46.408 D/bt_btif_dm(13168): remote version info [b0:b4:48:e8:fa:04]: 0, 0, 0
03-31 14:27:46.408 I/bt_bta_dm(13168): bta_dm_gatt_disc_result service_id_uuid_len=2 
03-31 14:27:46.408 I/bt_bta_dm(13168): bta_dm_gatt_disc_result service_id_uuid_len=16 
03-31 14:27:46.408 I/bt_bta_dm(13168): bta_dm_gatt_disc_result service_id_uuid_len=2 
03-31 14:27:46.412 E/BluetoothRemoteDevices(13168): state12newState0
03-31 14:27:46.457 I/TrustAgent.Tracker(15208): [BluetoothConnectionTracker] Bluetooth connect broadast for Foo04 B0:B4:48:E8:FA:04
03-31 14:27:47.317 I/WCNSS_FILTER(13194): ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver ioctl()
03-31 14:27:48.421 I/WCNSS_FILTER(13194): ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver ioctl()
03-31 14:27:48.483 W/bt_btif (13168): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
03-31 14:27:48.483 W/bt_btif (13168): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
03-31 14:27:48.483 I/bt_btm_sec(13168): btm_sec_disconnected clearing pending flag handle:14 reason:22
03-31 14:27:48.488 E/BluetoothRemoteDevices(13168): state12newState1
03-31 14:27:48.506 D/BluetoothMapService(13168): onReceive
03-31 14:27:48.506 D/BluetoothMapService(13168): onReceive: android.bluetooth.device.action.ACL_DISCONNECTED
03-31 14:27:48.524 D/BluetoothPbapReceiver(13168): PbapReceiver onReceive action = android.bluetooth.device.action.ACL_DISCONNECTED
03-31 14:27:48.527 D/BluetoothPbapReceiver(13168): Calling start service with action = null
03-31 14:27:48.530 I/TrustAgent.Tracker(15208): [BluetoothConnectionTracker] Bluetooth disconnect broadast for Foo04 B0:B4:48:E8:FA:04
03-31 14:27:49.430 I/WCNSS_FILTER(13194): ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver ioctl()

Дальнейшее исследование

Я отправил связанный с ним вопрос в Android BLE ACL_DISCONNECTED, который иногда задерживался.

Одна общая черта среди устройств, где я видел проблему, - это наличие SIM-карты, но другой - API 24 или 25. Я еще не смог воспроизвести устройство API 23 или, независимо от того, версии, без физически установленной SIM-карты.

После еще большего изучения, я меньше подозреваю SIM-карту и больше версии API. Существует несколько выдающихся (или недавно исправленных) ошибок, связанных с поведением, некоторые из которых указывают на версии API > 23; однако впоследствии я смог воспроизвести API 23.

Я чувствую, что это мало связано с профилями PBAP/MAP. Скорее, их существование в журналах указывает на то, что эти профили активируются при любом отключении BLE. Не проявляя повторного соединения, я смог увидеть аналогичную активацию PBAP/MAP при запуске с TI SensorTag: эти профили снова зарегистрировали любое отключение (не связанное с моим приложением).

Список уязвимых устройств

Я смог воспроизвести эту проблему в различной степени на следующих устройствах:

  • Samsung S6 - API 23
  • Samsung S7 - API 23
  • Samsung S7 Edge - API 24
  • Sony Xperia Z5 Compact - API 24
  • Motorola Droid Turbo 2 - API 24
  • Nexus 5x - API 25
  • Google Pixel - API 25

Ответ 1

После большого расследования я смог определить основную причину моей проблемы: Spotify.

Наличие Spotify, установленного на устройстве Android, было достаточно, чтобы продемонстрировать это отклоняющееся поведение; пользователю не нужно было входить в приложение Spotify или когда-либо запускать его. Удаление или принудительная остановка приложения во всех случаях устранила проблему.

Похоже, что Spotify имеет службу, которая регистрирует отсоединения от любого bluetooth-периферии. Когда система уведомляет Spotify, служба немедленно подключается к только что отключенному периферийному устройству --- я не стал описывать связь с Spotify. Через ~ 5 секунд соединение отключается; однако, поскольку Spotify уведомляется о событиях отключения Bluetooth, служба снова пытается подключиться к периферии. Это фактически бесконечный цикл, который можно прервать только силовым остановкой Spotify или циклическим bluetooth на устройстве Android.

Чтобы исследовать, я разработал простое приложение, которое уведомляется и сообщает о событиях подключения Bluetooth и отключении (ACL_CONNECTED, ACL_DISCONNECTED). Я использовал сканер BLE на своем устройстве Android и подключился/отключился с помощью различных периферийных устройств bluetooth. В моем тестовом приложении будет показано мое первоначальное взаимодействие с периферийным устройством, за которым следует бесконечный поток соединения, а затем отключите события. Опять же, это будет продолжаться до тех пор, пока Spotify не будет остановлен силой.

Ниже приведен пример регистрации...

04-10 19:56:24.109  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:56:32.057  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
04-10 19:56:34.197  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:56:40.396  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
04-10 19:56:43.857  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:56:49.962  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
04-10 19:56:51.130  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:57:17.348  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
04-10 19:57:17.927  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:57:37.621  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
04-10 19:57:38.157  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_CONNECTED
04-10 19:57:44.364  D/BluetoothConnectionMoni: onReceive: deviceName=System05 deviceAddr=B0:B4:48:E8:D7:03 action=ACL_DISCONNECTED
...

Было сложно определить, что Spotify была основной причиной.

Моим первым признаком явился поиск опций разработчика → Выполнение сервисов и запись Spotify, регулярно появляющихся, коррелированных с периферийным подключением/отключением.

В конце концов, дело сводилось к процессу устранения: после того, как началось аберрантное поведение, я выборочно просмотрел список установленных приложений, принудительно остановившихся, которые, вероятно, интересовались bluetooth, в конечном итоге увидели, что проблема прекратилась немедленно, когда я остановил Spotify.

Я представил подробный отчет об ошибках Spotify несколько недель назад, но мне еще нужно услышать от них ответ.

Ответ 2

Я также просто наткнулся на эту проблему, разрабатывая приложение Bluetooth BLE. Мое Android-устройство - это Sony (http://www.gsmarena.com/sony_xperia_x_performance-7949.php) с API 24. Он был повышен с API 23. От Android 6 → 7.

У него нет SIM-карты, поэтому я не думаю, что SIM-карта имеет значение. Но у него есть слот для SIM-карты, поэтому, возможно, это то, что вы имеете в виду.

Он снабжен чипом BLE версии 4.2 - не уверен, что это относится к вашей проблеме. Я постараюсь сегодня поработать над этим вопросом.

Ответ 3

Это кажется фиксированным, начиная с Spotify 8.4.19.792, выпущенного 2017-09-14.