Android Bluetooth IOException: в соединении отказано

Ладно, вот в чем дело. У меня есть два телефона Galaxy Nexus, оба с включенным bluetooth.

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

Из http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm следующего стандарта UUID доступны для устройств Galaxy Nexus.

  • 0x1116 — ПДД
  • 0x112f — PBAP (профиль доступа к телефонной книге)
  • 0x111f — HFP (свободные руки)
  • 0x1105 — OPP (профиль отправки объекта)
  • 0x1112 — HSP (профиль гарнитуры)
  • 0x110c — АВРКП
  • 0x110a - A2DP

Я пытаюсь подключиться через профиль OPP (UUID 00001105-0000-1000-8000-00805F9B34FB) и проталкивать объекты (файлы) между устройствами. Я просмотрел всю документацию Android API о том, как обнаружить, соединить/связать (потоковое и т. д.) и управлять всеми соединениями Bluetooth. Мне удалось успешно подключиться и поговорить с устаревшим устройством платы через профиль SPP (0x1101).

Однако, когда я пытаюсь использовать socket.connect() между двумя телефонами Galaxy Nexus, появляется диалоговое окно сопряжения, и я нажимаю кнопку Pair на обоих устройствах. После этого я сразу получаю Connection Refused IOException. Обратите внимание, что после того, как сопряжение произошло один раз, меня больше никогда не спрашивают, что имеет смысл, поскольку безопасная ссылка кэшируется.

Если я не могу подключиться к этим стандартным профилям, используя эти стандартные UUID, почему они открыты? Как я могу подключиться из своего приложения к любому из этих профилей и взаимодействовать с ними? Это потому, что моему приложению как-то не доверяют? Странно то, что даже функционал Share на Android тоже вообще не работает. Это что-то полностью сломанное на Android?

Пожалуйста, не давайте мне намеков на использование «хорошо известного UUID SPP one 0x1101», как говорится в документации. Это не то, чего я хочу. У меня довольно хорошее понимание того, как это работает, и я ищу реальное решение или объяснение проблемы.

Я видел типичное решение «отражение», но я не понимаю, почему это все еще проблема на Android? Почему люди используют отражение, чтобы заставить это работать? Можем ли мы зарегистрировать ошибку на Android, чтобы исправить это?

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

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

ОБНОВЛЕНИЕ

Итак, по какой-то причине заработал объектный толчок в системе Android. Я на самом деле пытался подключиться через свое приложение, и оно не работало. Затем я зашел в приложение «Контакты» и попытался поделиться контактом, который волшебным образом сработал. Затем я вернулся к своему приложению, и теперь оно работает... вау. Это очень странно, и этому должно быть объяснение.


person dnkoutso    schedule 18.09.2012    source источник
comment
вы настроили правильные разрешения? developer.android.com/guide/topics/connectivity/   -  person Lars    schedule 19.09.2012
comment
@Lars Конечно, он сделал. dnkoutso: Как именно вы открываете сокет? Не могли бы вы попробовать выполнить повторное сопряжение, то есть разорвать соединение, а затем снова выполнить сопряжение. Кстати, это 2 уровня?   -  person nullpotent    schedule 19.09.2012
comment
@iccthedral, что ты имеешь в виду под 2 уровнями? Я часто захожу в настоящее приложение «Настройки» на обоих устройствах и удаляю сопряжение. Как только я снова вызываю socket.connect(), он предлагает мне диалоговое окно сопряжения и заполненный номер ключа доступа. К сожалению, сразу после того, как я получаю исключение Connection Refused IOException.   -  person dnkoutso    schedule 19.09.2012
comment
Спасибо за обновление! Я обнаружил, что с двумя моими приложениями для обмена Bluetooth первое сопряжение всегда сложно. Я рад узнать, что это не только я. Также, пожалуйста, примите или проголосуйте, если найдете ответы полезными :)   -  person pjco    schedule 19.09.2012


Ответы (2)


Я столкнулся с этой же проблемой и сумел найти решение, которое сработало для меня.

В моем случае я использовал три разных тестовых устройства (Nexus 5, Galaxy S4, Note 2), и по какой-то причине Note 2 не подключался к моему модулю Bluetooth, а два других подключались.

Причина, которую я обнаружил, заключается в том, что драйверы Bluetooth различаются, и для создания соединения между разными устройствами необходимы несколько разные методы подключения.

Три метода, которые я использую, называются «Безопасный», «Небезопасный» и «Метод отражения»/«hax».

            switch(connType)
            {
            case Secure:
                tmpSocket = device.createRfcommSocketToServiceRecord(_uuid);
                break;

            case Insecure:
                tmpSocket = device.createInsecureRfcommSocketToServiceRecord(_uuid);
                break;

            case Hax:
                Method createSocket = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                tmpSocket = (BluetoothSocket)createSocket.invoke(device, Integer.valueOf(1));   
                break;
            } 

В моем случае безопасный режим работал как на Nexus 5, так и на Galaxy S4, но не на Note 2.

После некоторого тестирования я обнаружил, что Note 2 работает только в «небезопасном» режиме, поэтому, чтобы удовлетворить его, я в основном пытаюсь подключиться и при необходимости переключаться между различными режимами. При попытке другого режима подключения я просто предлагаю «повторить попытку подключения». Итак, если соединение не работает с использованием безопасного, я попытаюсь использовать небезопасное, а затем использовать метод отражения.

Я не сталкивался со случаем, когда один из этих трех методов не работал.

person benallansmith    schedule 18.03.2014

Пробовали ли вы использовать нестандартный профиль? то есть пользовательский UUID только для вашего приложения. Это также поможет вам узнать, что (скорее всего) вы подключаетесь только к своему собственному приложению, а не к какому-либо другому приложению, зарегистрированному с тем же профилем.

По моему опыту, при первой попытке сопряжения по Bluetooth возникает много ошибок. Однако использование пользовательского UUID несколько помогает.

Метод отражения (я думаю) изначально был попыткой исправить ошибку с конкретным устройством, однако я думаю, что некоторые люди успешно использовали его и в других местах. Устройство называлось Spica или что-то подобное.

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

В основном напишите код, который планирует неудачу с первой попытки, но затем код пытается снова подключиться через 5 секунд, если произошел сбой.

Это несовершенные решения, но реализация Bluetooth на Android тоже несовершенна (ИМХО). надеюсь, это поможет

ИЗМЕНИТЬ

На основе обновления вопроса и комментариев:

Я согласен, что-то определенно глючит. Я думаю, что часть проблемы заключается в том, что драйверы BT различаются, и у каждого есть свой стек BT со своими особенностями. Я также нашел вопрос, который использует как метод отражения, так и пользовательский UUID, И другие стандартные методы. Это кажется мне экстремальным, но оно охватывает большую часть земли. К сожалению, как разработчики приложений, мы не можем контролировать низкоуровневый стек/код/драйверы.

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

Я рад узнать, что это не только я.

person pjco    schedule 19.09.2012
comment
Мне удалось установить соединение с моим собственным UUID. Я просто не понимаю, как эти общедоступные СТАНДАРТНЫЕ UUID Bluetooth не работают. Они также не работают в обычной системе Sharing на Android, что также является намеком на то, что в коде Android что-то не так. - person dnkoutso; 19.09.2012
comment
Я согласен, что-то определенно глючит. Я думаю, что часть проблемы заключается в том, что драйверы BT различаются, и у каждого есть свой стек BT со своими особенностями. Я также нашел вопрос, который использует как метод отражения, так и пользовательский, И другие стандартные методы. Это кажется мне экстремальным, но оно охватывает большую часть земли. К сожалению, как разработчики приложений, мы не можем контролировать низкоуровневый стек/код/драйверы. - person pjco; 19.09.2012