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

У меня была эта проблема некоторое время, и я не мог понять это.

У меня есть приложение для Android, которое помещает все сопряженные устройства в список. Когда вы щелкаете один из элементов списка, он инициирует запрос на подключение к этому устройству Bluetooth.

Я могу получить список устройств с их адресами без проблем. Проблема в том, что когда я пытаюсь подключиться, я получаю IOException на socket.connect();

Сообщение об ошибке выглядит следующим образом: "Ошибка чтения соединения, возможно, сокет закрыт или истекло время ожидания, чтение ret: -1"

Вот мой код. ЛЮБЫЕ предложения будут оценены. Я довольно застрял на этом.

к вашему сведению: методы onEvent — это библиотека, которая упрощает обратные вызовы... эта часть работает. Когда пользователь щелкает элементы списка, этот метод вызывается "public void onEvent(EventMessage.DeviceSelected event)"

public class EcoDashActivity extends BaseActivity {

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


private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 100;
private ArrayList<BluetoothDevice> mDevicesList;
private BluetoothDeviceDialog mDialog;
private ProgressDialog progressBar;
private int progressBarStatus = 0;
private Handler progressBarHandler = new Handler();


@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    mDevicesList = new ArrayList<BluetoothDevice>();

    // Register the BroadcastReceiver
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);

    setupBluetooth();
}

private void setupBluetooth() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter == null) {
        // Device does not support Bluetooth
        Toast.makeText(this, "Device does not support Bluetooth", Toast.LENGTH_SHORT).show();
    }

    if (!mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    } else {
        searchForPairedDevices();
        mDialog = new BluetoothDeviceDialog(this, mDevicesList);
        mDialog.show(getFragmentManager(), "");
    }

}

private void searchForPairedDevices() {

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    // If there are paired devices
    if (pairedDevices.size() > 0) {
        // Loop through paired devices
        for (BluetoothDevice device : pairedDevices) {
            // Add the name and address to an array adapter to show in a ListView
            mDevices.add(device.getName() + "\n" + device.getAddress());
            mDevicesList.add(device);
        }
    }
}


private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // When discovery finds a device
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a ListView
            mDevicesList.add(device);
        }
    }
};


@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mReceiver);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
        if (resultCode == RESULT_OK) {
            Toast.makeText(this, "BT turned on!", Toast.LENGTH_SHORT).show();
            searchForPairedDevices();

            mDialog = new BluetoothDeviceDialog(this, mDevicesList);
            mDialog.show(getFragmentManager(), "");
        }
    }

    super.onActivityResult(requestCode, resultCode, data);
}


public void onEvent(EventMessage.DeviceSelected event) {

    mDialog.dismiss();

    BluetoothDevice device = event.getDevice();

    ConnectThread connectThread = new ConnectThread(device);
    connectThread.start();
}


public class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        BluetoothSocket tmp = null;
        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        setName("ConnectThread");
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            Log.d("kent", "trying to connect to device");
            mmSocket.connect();
            Log.d("kent", "Connected!");
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                Log.d("kent", "failed to connect");

                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        Log.d("kent", "Connected!");
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

Вот мой логкэт. Довольно короткий.

07-22 10:37:05.129: DEBUG/kent(17512): trying to connect to device
07-22 10:37:05.129: WARN/BluetoothAdapter(17512): getBluetoothService() called with no BluetoothManagerCallback
07-22 10:37:05.129: DEBUG/BluetoothSocket(17512): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[98]}
07-22 10:37:40.757: DEBUG/dalvikvm(17512): GC_CONCURRENT freed 6157K, 9% free 62793K/68972K, paused 7ms+7ms, total 72ms
07-22 10:38:06.975: DEBUG/kent(17512): failed to connect
07-22 10:38:06.975: DEBUG/kent(17512): read failed, socket might closed or timeout, read ret: -1

Эта последняя строка находится в разделе «Поймать» попытки/поймать... Я просто регистрирую сообщение об ошибке.

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


person Kent Andersen    schedule 20.07.2013    source источник
comment
Какая версия Андроида? Может быть проблема со стеком из-за того, что у Jelly bean совершенно другой стек bluetooth, сначала разорвите пару и попробуйте выполнить сопряжение, а затем повторите попытку.   -  person Vrashabh Irde    schedule 22.07.2013
comment
@Slartibartfast В настоящее время я работаю над 4.2.2 Nexus 4. Я обновлю вопрос с помощью logcat.   -  person Kent Andersen    schedule 22.07.2013
comment
Проверьте мой ответ, это должно помочь   -  person Vrashabh Irde    schedule 22.07.2013
comment
Я посмотрю на это. Вероятно, пройдет несколько часов, прежде чем я смогу проверить это.   -  person Kent Andersen    schedule 22.07.2013


Ответы (2)


Стек bluetooth jelly bean заметно отличается от других версий.

Это может помочь: http://wiresareobsolete.com/wordpress/2010/11/android-bluetooth-rfcomm/

Суть: UUID — это значение, которое должно указывать на опубликованную службу на вашем встроенном устройстве, а не просто генерируется случайным образом. Соединение RFCOMM SPP, к которому вы хотите получить доступ, имеет определенный UUID, который он публикует для идентификации этой службы, и при создании сокета он должен соответствовать тому же UUID.

Если вы нацелены на устройство версии 4.0.3 и выше, используйте fetchUuidsWithSdp() и getUuids(), чтобы найти все опубликованные службы и связанные с ними значения UUID. Для обратной совместимости прочитайте статью

person Vrashabh Irde    schedule 22.07.2013
comment
GetUUIDs() возвращает список идентификаторов. Как узнать, какой из них следует использовать? - person Kent Andersen; 22.07.2013
comment
Я просто пробовал каждый UUID, который он возвращал, и у меня была такая же проблема. - person Kent Andersen; 22.07.2013
comment
Знаете ли вы полный пример кода, который я могу скопировать/вставить в новое приложение, чтобы просто протестировать его? - person Kent Andersen; 22.07.2013
comment
Я вижу две ошибки, связанные с вашей проблемой на Android. Узнайте, есть ли какая-либо помощь или обходной путь здесь: code.google.com/p/android/issues/detail?id=41415 и code.google.com/p/android/issues/detail?id=41110 - person Vrashabh Irde; 23.07.2013
comment
Я только что попробовал это на устройстве Note 2, и код отлично сработал. Блютуз подключился сразу. Думаю, это просто ошибка в Android 4.2.2 или, может быть, в Nexus 4. Я наградил вас бонусными баллами :) Спасибо. - person Kent Andersen; 26.07.2013
comment
Я считаю, что всем, кто читает это, стоит отметить, что мой код подключается к адаптеру Bluetooth, подключенному к моей машине. Я использую его для чтения OBD2. Мне не удалось подключить приложение к одному адаптеру, но недавно я купил другой, и код работал отлично. Значит, либо проблема в адаптере, либо в Android есть баг, не позволяющий общаться с некоторыми устройствами. - person Kent Andersen; 02.10.2013

Я получил такое же сообщение об ошибке после второго подключения к сокету. Я просто проверил, подключен ли уже сокет.

if(!mmSocket.isConnected())
            mmSocket.connect();

Я тестировал на Android 4.4.2 (Moto G).

person marnaish    schedule 02.07.2014