Ошибка обнаружения службы при использовании Bluetooth на Android - PullRequest
49 голосов
/ 03 августа 2010

В настоящее время я работаю над приложением Android, которое подключается к инструменту через Bluetooth, и мне нужно писать строковые команды и получать ответы на них. В настоящее время у меня есть подключение / чтение / запись для TCP / IP через Wi-Fi, и теперь я пытаюсь реализовать Bluetooth. Но я сталкиваюсь с некоторыми препятствиями. Я искал в Интернете, пытаясь найти примеры чего-то подобного, и мне не повезло. Я использовал пример ресурса разработчика Android: Bluetooth-чат в качестве основного ориентира.

Кажется, мой текущий код работает .. Затем он генерирует исключение Service Discovery Failed в точке соединения. Я использую класс DeviceListActivity для обнаружения и выбора устройства, к которому я хочу подключиться. Он возвращает anActivityResult, а затем мой класс Bluetooth ожидает его обработки и затем подключается к нему. Код ниже практически идентичен приложению Bluetooth Chat.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(!m_BluetoothAdapter.isEnabled())
    {
        m_BluetoothAdapter.enable();
    }
    switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
            // When DeviceListActivity returns with a device to connect
            if (resultCode == Activity.RESULT_OK) {
                // Get the device MAC address
                String address = data.getExtras()
                                     .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                // Get the BLuetoothDevice object
                BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
                connect(device);
            }
            break;

        case REQUEST_ENABLE_BT:
            // When the request to enable Bluetooth returns
            if (resultCode == Activity.RESULT_OK) {
                // Bluetooth is now enabled, so set up a chat session
            }
            else {
                // User did not enable Bluetooth or an error occured

                Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
                finish();
            }
    }
}

Это моя функция подключения:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

private void connect(BluetoothDevice device) {
    m_Device = device;
    BluetoothSocket tmp = null;

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    }
    catch (IOException e) {

    }
    m_Socket = tmp;

    m_BluetoothAdapter.cancelDiscovery();

    try {
        // This is a blocking call and will only return on a
        // successful connection or an exception
        m_Socket.connect();
    }
    catch (IOException e) {
        try {
            m_Socket.close();
        }
        catch (IOException e2) {
        }
        return;
    }
}

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

Вы можете подключить / найти устройство в любое время вручную на телефоне ... Для этого требуется пароль, но я не думаю, что это проблема, с которой я столкнулся.

Ответы [ 5 ]

93 голосов
/ 03 августа 2010

Через три дня я понял это благодаря некоторым очень полезным сообщениям.

Мне пришлось заменить:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

на:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
         tmp = (BluetoothSocket) m.invoke(device, 1);

ивуаля это работает!

13 голосов
/ 13 мая 2013

Начиная с API 15, вы можете использовать следующий метод:

Попробуйте заменить ваш UUID на возвращаемое значение getUuids () метода BluetoothDevice класса.У меня получилось что-то вроде этого:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);

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

Еще один интересный новый метод (поддерживается начиная с API 14): BluetoothHealth.getConnectionState .Не пробовал, но выглядит многообещающе ...

2 голосов
/ 03 марта 2012

Это было предлагаемое изменение от анонимного пользователя , пытающегося ответить на принятый ответ.

Одна большая разница между кодом до и после - UUIDВы проходитеЯ нашел свой ответ здесь: http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)

Мне пришлось заменить:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

на:

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);

и вуаля это работает!Оригинальный код для однорангового приложения для Android.Нет смысла использовать приложение UUID при подключении к простому последовательному устройству Bluetooth.Вот почему открытие не удается.

1 голос
/ 15 сентября 2017

Это очень старый вопрос, но я обнаружил, что использование createInsecureRfcommSocketToServiceRecord() вместо createRfcommSocketToServiceRecord() вместе с getUuids(), упомянутым ранее, помогает мне

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
1 голос
/ 10 июня 2015

Итак, как уже упоминалось выше, смысл в том, что вам нужно использовать UUID, которого ожидает сервер.

Если вы подключаетесь к устройству Bluetooth, например, к гарнитуре или мыши, вам нужночтобы проверить, какие UUID прослушивает устройство.Вы можете видеть UUID как это.

UUID[] uuids = bluetoothDevice.getUuids();

И если вы хотите узнать, что означают эти UUID, см. this .

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