«Обнаружение службы не удалось» из Android Bluetooth Небезопасный Rfcomm - PullRequest
13 голосов
/ 15 декабря 2011

Кто-нибудь знает, как создать небезопасное соединение RFCOMM между двумя устройствами Android на уровне API 2.3.3 при использовании произвольно объявленного имени службы? (не случайное или не меняющееся имя службы, просто имя службы, котороеЯ определяю себя)

Подробности

Я пытаюсь создать небезопасное соединение Rfcomm между двумя устройствами Android: Droid X2 и Asus Transformer.Я предполагаю, что оба эти устройства имеют функциональность на уровне Android 2.3.3, чтобы фактически получить возможность использовать небезопасный Rfcomm.

Когда я пытаюсь создать соединение Bluetooth, как описано здесь используя теперь общедоступные createInsecureRfcommSocketToServiceRecord () и listenUsingInsecureRfcommWithServiceRecord (SERVICE, UUID), я получаю сообщение:

java.io.IOException: Service discovery failed
at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:377)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:201)
at com.s4d.bluenomad.DeviceConnections$ClientThread.run(DeviceConnections.java:406)

Я нашел связанный вопрос , где кто-то, создавший нормальное соединение, получалэта ошибка и используется отражение для вызова частного метода.Однако я понятия не имею, какой приватный метод теперь будет соответствовать инициации «небезопасного» соединения.Я попытался использовать решение, предложенное в этом связанном вопросе, но Android попросил меня соединить устройства, и это именно то, чего мне нужно избегать.Мне действительно нужен небезопасный подход.

Я даже попробовал комбинацию официальных и взломанных решений, обозначенных здесь

Соответствующие фрагменты кода

Создание ServerThread для прослушивания соединений

Log.i(TAG, "Constructing a ServerThread");
// Use a temporary object that is later assigned to serverSocket,
// because serverSocket is final
BluetoothServerSocket tmp = null;
try {
    // MY_UUID is the app's UUID string, also used by the client code
    tmp = btAdapter.listenUsingInsecureRfcommWithServiceRecord(SERVICE_NAME, SERVICE_UUID);
    Log.i(TAG,"Started listening on insecure RFCOMM channel for service requests for: " + SERVICE_NAME);
} catch (IOException e) { }
serverSocket = tmp;

ServerThread Прослушивание соединений

BluetoothSocket socket;
while(true)
{
    try
    {
        socket = serverSocket.accept();
    }
    catch( IOException e)
    {
        break;
    }

    if( socket != null )
    {
        Log.i(TAG, "Received new socket connection requesting service: " + SERVICE_NAME);
    }
    else
    {
        Log.i(TAG, "Socket connection attempted, but socket received is NULL.");
    }
}

Создание ClientThread для инициации соединений

Log.i(TAG, "Constructing a ClientThread");
BluetoothSocket tmp = null;
try {
    // MY_UUID is the app's UUID string, also used by the server code
    tmp = device.createInsecureRfcommSocketToServiceRecord(SERVICE_UUID);
    Log.i(TAG,"Created client socket on insecure RFCOMM channel for service requests for: " + SERVICE_NAME);
} 
catch (IOException e) 
{ 
    Log.i(TAG, "Failed to createInsecureRfcommSocket() against MAC: " + device.getAddress());
}
clientSocket = tmp;

ClientThread Подключение к серверу

try
{
    clientSocket.connect();
}
catch( final IOException e)
{
    DeviceConnections.this.runOnUiThread(new Runnable()
    {

        @Override
        public void run() 
        {
            console.append("Client unable to connect to service.");
            Log.i(TAG, "Client socket unable to connect() to: " + clientSocket.getRemoteDevice().getAddress());
            e.printStackTrace();
        }

    });

}

Я получаю вывод журнала "Клиентский сокет не может подключиться () к: [MY_MAC_ADDRESS]", затем яполучить трассировку стека для исключения «Обнаружение службы не удалось».

Ответы [ 5 ]

15 голосов
/ 06 января 2012

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

clientSocket.connect()

Мне нужно было позвонить

btAdapter.cancelDiscovery()

Я видел это в документации, но это было указано как проблема «производительности» - в моем случае кажется, что это на самом деле «функциональная» проблема. После того, как я добавил вызов отмены обнаружения, соединение с сокетом сработало немедленно.

5 голосов
/ 15 декабря 2011

Несколько вещей для проверки

  • с использованием одного и того же уникального UUID как на клиенте, так и на сервере.
  • Иметь разрешение BLUETOOTH
  • Попробуйте использовать стандартный известный SPP UUID 00001101-0000-1000-8000-00805F9B34FB

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

3 голосов
/ 28 декабря 2011

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

2-е устройство не вызывало метод listenUsingInsecureRfcommWithServiceRecord, прежде чем пытаться вызвать«createInsecureRfcommSocketToServiceRecord» с 1-го устройства.

Убедитесь, что этот код был выполнен на 2-м устройстве (например, onResume () или при нажатии кнопки / optionItem), прежде чем пытаться подключиться с 1-го устройства.

 if ((mChatService != null) &&  (mBluetoothAdapter.isEnabled())) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
            }
        }
0 голосов
/ 07 ноября 2013

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

У меня возникла та же проблема. В моем конкретном случае ошибка произошла, когда хотя бы одному из устройств BluetoothAdapter.getScanMode() было присвоено значение BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE (т. Е. Устройство можно обнаружить и подключить с удаленных устройств Bluetooth) .

Это любопытно, потому что устройство должно быть подключаемым, но это не так.

Если устройство getScanMode() ==SCAN_MODE_CONNECTABLE, то ошибки не возникает.

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

Включение связи по Bluetooth только для сопряженных устройств исключает необходимость обнаружения и последующего исключения «Ошибка обнаружения службы».

Опять же, это мой конкретный случай на моем конкретном устройстве. Это не может быть общим правилом, но надеюсь, что это поможет любому, кто получает ту же ошибку.

0 голосов
/ 25 февраля 2013

Вам следует изменить 8ce255c0-200a-11e0-ac64-0800200c9a66 на любой другой UUID, и вы можете использовать имя своей службы, поскольку 8ce255c0-200a-11e0-ac64-0800200c9a66 используется для предопределенной службы BluetoothChatInsecure

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