获取到设备后就可以开始处理蓝牙设备之间的连接。

在上一篇教程中我们将搜索到的蓝牙设备展示在列表中,现在我们为列表项增加上点击事件。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (bTAdatper.isDiscovering()) {
                    bTAdatper.cancelDiscovery();
                }
                BluetoothDevice device = (BluetoothDevice) adapter.getItem(position);
                //连接设备
                connectDevice(device);
            }
        });

当我们点击了列表项后,如果蓝牙设备当前处于搜索状态,则取消搜索。获取到列表项相对应的蓝牙设备后调用连接方法。

/**
     * 连接蓝牙设备
     */
    private void connectDevice(BluetoothDevice device) {

        text_state.setText(getResources().getString(R.string.connecting));

        try {
            //创建Socket
            BluetoothSocket socket = device.createRfcommSocketToServiceRecord(BT_UUID);
            //启动连接线程
            connectThread = new ConnectThread(socket, true);
            connectThread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

可以看到,在connectDevice()方法中,首先用一个TextView提示连接状态,然后用我们选择的设备调用createRfcommSocketToServiceRecord(UUID uuid)获取BluetoothSocket。最后开启一个线程去处理BluetoothSocket。

这里需要注意的是传入的UUID。UUID是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符。我们在连接蓝牙设备的时候,必须确保两个设备的UUID是相同的。通常UUID是16字节128位长的数字,通常以36字节的字符串表示,示例如下:

3F2504E0-4F89-11D3-9A0C-0305E82C3301。

//如果是自动连接 则调用连接方法
                if (activeConnect) {
                    socket.connect();
                }
                text_state.post(new Runnable() {
                    @Override
                    public void run() {
                        text_state.setText(getResources().getString(R.string.connect_success));
                    }
                });

在创建线程的时候我们会传入布尔变量activeConnect做标识,区分是自动连接还是被动连接。当是自动连接状态,则调用BluetoothSocket的connect()进行连接。

而被动连接的做法主要是开启一个监听线程,监听是否有设备连接到我们的设备上,具体代码如下:
listenerThread = new ListenerThread();
        listenerThread.start();
在onCreate()方法中开启监听线程
private BluetoothServerSocket serverSocket;
        private BluetoothSocket socket;

        @Override
        public void run() {
            try {
                serverSocket = bTAdatper.listenUsingRfcommWithServiceRecord(
                        NAME, BT_UUID);
                while (true) {
                    //线程阻塞,等待别的设备连接
                    socket = serverSocket.accept();
                    text_state.post(new Runnable() {
                        @Override
                        public void run() {
                            text_state.setText(getResources().getString(R.string.connecting));
                        }
                    });
                    connectThread = new ConnectThread(socket, false);
                    connectThread.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

监听线程中的代码很简单,首先是获取BluetoothServerSocket,这里需要用到UUID必须确保和自动连接所用到的UUID是相同的,而对于NAME就没什么要求。接着我们就调用accept()方法。这个方法会阻塞住当前的线程,直到有设备连接上来。当有设备连接上来,则可以获取到对应的BluetoothSocket。到这里被动连接就成功了。接着我们只要把获取到的BluetoothSocket交由连接线程ConnectThread去处理就行了。