BluetoothSocket#connect блокирует поток и выдает IOException через некоторое время

Первый подход к созданию сокета:

try {
    socket = device.createRfcommSocketToServiceRecord(BSERVICE_UUID)
} catch(e: Exception) {
    e.printStackTrace()
}

Второй подход к созданию сокета:

try {
    socket = device.createInsecureRfcommSocketToServiceRecord(BSERVICE_UUID)
} catch(e: Exception) {
    e.printStackTrace()
}

Третий подход к созданию сокета:

try {
    socket = createRfcommSocket(device)
} catch(e: Exception) {
    e.printStackTrace()
}

С createRfcommSocket(device), определенным как:

private fun createRfcommSocket(device: BluetoothDevice): BluetoothSocket? {
    val method = device::class.java.getMethod("createRfcommSocket", Int::class.javaPrimitiveType)
    return method.invoke(device, 1) as BluetoothSocket?
}

Любое из них выполняется до того, как я действительно вызову BluetoothSocket#connect() для непустой ссылки. Поток замораживается на некоторое время, а затем выбрасывается исключение:

java.io.IOException: read failed, socket might closed or timeout, read ret: -1
W/System.err:     at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:581)
W/System.err:     at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:558)
W/System.err:     at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:374)

Все данные по этому вопросу:

Устройство, о котором здесь идет речь, обнаруживается с помощью метода BluetoothAdapter#startDiscovery() с зарегистрированными соответствующими широковещательными приемниками. Процесс выглядит так: кешируем устройства локально, затем, после получения ACTION_DISCOVERY_FINISHED Intent — начинаем вызывать BluetoothDevice#fetchUuidsWithSdp(). Потенциальная причина вышеуказанной проблемы заключается в том, что в намерении ACTION_UUID я получаю нуль в качестве объекта массива UUID, извлеченного с помощью ключа BluetoothDevice.EXTRA_UUID из намерения.

Протестировано на Samsung Galaxy Tab S с API уровня 19. Без рута. С BLE работает нормально с тем же устройством.

Ни один UUID не работает: ни стандартный "00001101-0000-1000-8000-00805F9B34FB", ни любой из потенциально возможных, которые имеются в виду в документации устройства.

Самое интересное в этом то, что решение на основе отражения дало ту же проблему.

UPD: нашел еще кое-что из логов. Через несколько секунд после вызова функции подключения я получаю следующее:

D/BluetoothSocket: SecProductFeature_BLUETOOTH.SEC_PRODUCT_FEATURE_BLUETOOTH_IT_POLICY_FEATURE = true
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback

Первая строка не дает результатов в гугле, может в этом и причина моей проблемы?


person Игорь Комаров    schedule 27.08.2017    source источник


Ответы (1)


Закрытое устройство не поддерживает Bluetooth Classic и позволяет взаимодействие, построенное только поверх BLE.

person Игорь Комаров    schedule 28.08.2017