Мое приложение подключается к модулям Bluetooth SPP, выполняя и обрабатывая подключения в значительной степени, как описано в документации Android Bluetooth .То есть в моем потоке соединения я использовал для создания соединения просто:
socket = device.createRfcommSocketToServiceRecord(MY_UUID)
, где UUID - это «хорошо известный» UPID SPP, 00001101-0000-1000-8000-00805F9B34FB.
Устройства Bluetooth, к которым я подключаюсь, - это маленькие адаптеры Bluetooth / последовательный порт.У меня есть три, которые я использовал для теста.Два из них - это последовательные печатные платы от Bluetooth до TTL уровня Linvor, которые на данный момент находятся на всех eBay и являются идентичными;и третий - полностью закрытый адаптер неизвестного производителя.
За время разработки этого приложения я регулярно тестировал на различных устройствах от Android версии 2.2.1 (мой старый Archos 101) до устройства Archos Honeycomb.Устройство, которое я тестировал в основном, это мой Desire HD, который в настоящее время имеет версию Android 2.3.5.В течение года или около того я работал над этим, я могу с уверенностью сказать, что у меня никогда не было проблем со связью.
Вчера во время тестирования моего Desire HD (2.3.5) я обнаружил, что приложение больше не будет подключаться к моей печатной плате Linvor Bluetooth, с которой я работал в основном в последнее время.После получения сокета, используя приведенную выше строку кода, при попытке socket.connect()
я бы немедленно получил IOException
из Unable to start discovery
.
Следующее, что я сделал, это переключился на другой запасной модуль Linvor и попытался выполнить сопряжение и подключение.Приложение подключено просто отлично.Затем я также поменял свой третий упакованный адаптер Bluetooth, и приложение, подключенное к нему, тоже прекрасно.Возвращаясь к моему первому модулю Linvor, приложение по-прежнему отказывается подключаться.Я гарантирую, что отсоединяю «неисправное» устройство Linvor на своем Desire HD, выключаю Bluetooth, выключаю телефон, вынимаю и снова вставляю аккумулятор, включаю, повторно подключаю и т. Д., А затем повторяю попытку.Приложение по-прежнему отказывается подключаться к этому первому модулю Linvor, но нормально подключается ко второму модулю Linvor и другому адаптеру.
Затем я беру свой Archos 101 (2.2.1) и запускаю несколько более старую сборку моего приложения, которая все еще установлена на нем.Archos 101 немедленно подключается к «неисправному» модулю Linvor.
В этот момент я начинаю задаваться вопросом, может ли какое-либо устройство - т.е. мой Desire HD или, возможно, более вероятно, модуль Linvor - иметь какую-либо поврежденную запись в своей таблице флэш-памяти для сопряженных устройств.Другими словами, что-то в этом первом модуле Linvor, что означает, что он больше не принимает соединение (хотя и принимает сопряжение) с моего Desire HD, и все же он все равно будет принимать соединения от других устройств;и в то же время мой Desire HD может с радостью подключаться к другим устройствам, как это всегда делалось, включая другой запасной модуль Linvor.
После нескольких часов царапин и отчаяния я решил попробовать метод отражения , как описано в ответе Майкла .Об этом я много слышал, и у меня сложилось впечатление, что это применимо к Android 2.2 и ниже.Тем не менее, в течение всего года, когда я работал с Bluetooth SPP с моих различных устройств Android, у меня никогда не было необходимости использовать его, так как .createRfcommSocketToServiceRecord()
всегда работал для меня.Поэтому я использую код, приведенный в ответе Майкла на этот вопрос, для создания моего socket
, и, к моему изумлению, мой Desire HD подключается к «неисправному» модулю Linvor.
Итак, напомним, что ситуация выглядит следующим образом:
В течение прошлого года я смог регулярно использовать .createRfcommSocketToServiceRecord()
на своих устройствах 2.2.1 и 2.3.5 дляподключите к моим трем адаптерам Bluetooth SPP.
Затем, в один конкретный день, без каких-либо изменений в программном обеспечении на телефонах или моих адаптерах Bluetooth, первый из адаптеров внезапно требует метода отражения для работы соединения; два других адаптера (один из них того же типа, что и первый) продолжают нормально подключаться к моему приложению, используя .createRfcommSocketToServiceRecord()
. Обратите внимание, что в мой код Bluetooth не было внесено абсолютно никаких изменений непосредственно перед этим внезапным изменением поведения.
Что на земле здесь происходит?
Может кто-нибудь посоветовать мне, на каком уровне версии Android требуется «взлом» отражения , а не ? У меня сложилось впечатление, что это больше не нужно, скажем, на 2.3.5 (мой Desire HD). Это правильно?
Является ли / была природа ошибки с .createRfcommSocketToServiceRecord()
такой, что соединения обычно работают, но иногда не работают в зависимости от фазы луны?
Вот вывод Logcat, когда происходит сбой соединения с этим конкретным модулем Linvor при использовании .createRfcommSocketToServiceRecord()
:
<code>
01-29 10:22:00.004: D/View(8165): onTouchEvent: viewFlags: 0x18005001
01-29 10:22:00.014: D/View(8165): onTouchEvent: isFocusable: true, isFocusableInTouchMode: false, isFocused: false; focusTaken: false
01-29 10:22:00.034: D/WindowManagerImpl(8165): finishRemoveViewLocked, mViews<a href="/3079722/problemy-s-podklycheniem-po-bluetooth-android">2</a>: com.android.internal.policy.impl.PhoneWindow$DecorView@406215d8
01-29 10:22:00.074: I/BLZ20_WRAPPER(8165): blz20_wrp_socket: fam 31, type 1, prot BTPROTO_RFCOMM
01-29 10:22:00.084: D/BLZ20_WRAPPER(8165): blz20_init: initializing...
01-29 10:22:00.084: D/BTL_IFC_WRP(8165): wsactive_init: init active list
01-29 10:22:00.084: I/BTL_IFC(8165): main_client_thread: Client main thread starting
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_init: success
01-29 10:22:00.194: I/BTL_IFC(8165): BTL_IFC_RegisterSubSystem: Register subsystem [BTS]
01-29 10:22:00.194: I/BTL_IFC(8165): btl_ifc_ctrl_connect: Connect control channel for subsystem [BTS]
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_create: CTRL
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_alloc_new_sock: wrp_alloc_new_sock sub 1
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_create: 66
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: wrp_sock_connect brcm.bt.btlif:9000 (66)
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: BTLIF_MAKE_LOCAL_SERVER_NAME return name: brcm.bt.btlif.9000
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: wrp_sock_connect ret:0 server name:brcm.bt.btlif.9000
01-29 10:22:00.194: I/BTL_IFC_WRP(8165): wrp_sock_connect: Connected. (66)
01-29 10:22:00.194: I/BTL_IFC(8165): send_ctrl_msg: [BTL_IFC CTRL] send BTLIF_REGISTER_SUBSYS_REQ (BTS) 0 pbytes (hdl 66)
01-29 10:22:00.194: D/BTL_IFC(8165): BTL_IFC_RegisterSubSystem: add new ctrl fd to active set
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_wsock_create: BTS
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_alloc_new_sock: wrp_alloc_new_sock sub 16
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_wsock_create: 67
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): btsk_alloc_add: success
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): btsk_dump_list: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_socket: return 67
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: configure rfcomm lm mode 0x26, (master:0, auth 1, enc 1)
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: success
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: configure rfcomm sndbuf len 71680 bytes
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: success
01-29 10:22:00.194: D/BLZ20_ASOCKWRP(8165): asocket_init
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 67, cmd 3
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 67, cmd 4
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: transparant fcntl
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 69, cmd 3
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: wsock not found, pass through transparantly
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 69, cmd 4
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: wsock not found, pass through transparantly
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_set_asocket: success (67,68,69)
01-29 10:22:00.214: I/BluetoothIF(8165): BEGIN mConnectThread
01-29 10:22:00.234: E/BluetoothIF(8165): TP: IOException error: java.io.IOException: Unable to start Service Discovery
01-29 10:22:00.234: E/BluetoothIF(8165): Unable to start Service Discovery
01-29 10:22:00.234: E/BluetoothIF(8165): Unable to start Service Discovery
01-29 10:22:00.234: D/BluetoothSocket(8165): close(): android.bluetooth.BluetoothSocket@405c8f78
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_abort [67,68,69]
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: s 67, how 2
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: shutdown socket
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_write: wrote 1 bytes out of 1 on fd 69
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_destroy
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_abort [67,68,69]
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: s 67, how 2
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: shutdown socket
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_write: wrote 1 bytes out of 1 on fd 69
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 69
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_close: std close (69)
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 68
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): blz20_wrp_close: std close (68)
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 67
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): blz20_wrp_close: fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): __close_prot_rfcomm: fd 67
01-29 10:22:00.244: I/BTL_IFC(8165): send_ctrl_msg: [BTL_IFC CTRL] send BTLIF_BTS_RFC_CLOSE (BTS) 8 pbytes (hdl 66)
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: wrp_close_s_only [67] (67:-1) []
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: data socket closed
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wsactive_del: delete wsock 67 from active list [ad40f904]
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: wsock fully closed, return to pool
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): btsk_free: success
В настоящее время лучший способ действий, который я вижу, состоит в том, чтобы спроектировать мой код так, чтобы в случае немедленного сбоя метода .createRfcommSocketToServiceRecord()
с исключением «неспособно начать обнаружение» затем использовался метод выбора, который до сегодняшнего дня Я никогда не нуждался в использовании.
Дополнительная информация: Мое приложение предназначено для уровня API 8. Подозревая, что ошибка подключения RFCOMM влияет на Android 2.2 и ниже, я попытался перейти на уровень API 10, просто чтобы посмотреть, повлияет ли это на поведение .createRfcommSocketToServiceRecord()
, но проблема сохранялась: попытки подключиться к одному модулю Linvor привели к немедленному исключению IOException, как описано выше.
Спасибо - Трев