android之蓝牙通信(二)(蓝牙连接,数据传递)

上次写了android之蓝牙通信(一)(基础之检测蓝牙、开启蓝牙、扫描附近蓝牙设备)
,大致介绍了开启蓝牙,搜索附近蓝牙设备功能,下面接下来写下搜索到蓝牙设备后进行连接,传递数据的操作,连接蓝牙设备有两种,一种是单向,一种是双向。单向是它发数据,你接受就行;双向是它发数据,你接收,你也发数据,它接收,双向的最佳例子就是蓝牙聊天。单向跟双向的做法差不多,单向只需要做个接收就行,而双向比单向多一个发送功能,具体的差异上一篇说过,双向是即作为服务器也作为客户端,单向是只需要作为客户端就行。

由于项目是做连接蓝牙秤获取蓝牙秤的数据,所以就以单向为例了,双向原理类似,多一个accept()和作为service服务器,具体就不多说了。

废话不多说了,直接上代码,首先,连接设备(很多人写的时候都是直接进行连接,没有先进行配对而是直接连接操作,这种方式不稳定,未配对的直接进行连接不稳定,有时候会很久连不上,所以先进行配对判断,配对过了直接连接,未配对的先进行配对,配对成功后再进行连接):

//配对连接线程
    private class ClientThread extends Thread {
        @Override
        public void run() {
            if (bluetoothAdapter.isDiscovering()) {
                bluetoothAdapter.cancelDiscovery();
            }

            try {
                if (device.getBondState() == BluetoothDevice.BOND_NONE) {  //未配对,就先配对,再连接
                    Method m = BluetoothDevice.class.getMethod("createBond");
                    m.invoke(device);
                } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {  //已配对,直接连接
                    try {
                        MlogUtil.d(MlogUtil.MY_TEST, "开始连接");
                        socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                        socket.connect();  //进行socket连接
                        Message succeedMsg = new Message();
                        succeedMsg.what = 1;
                        handler.sendMessage(succeedMsg);  //连接成功,发送消息给UI线程,进行提示
                        clientThread = null;
                        readThread = new ReadThread();  //连接成功后开启读取数据的线程
                        readThread.start();
                    } catch (IOException e) {
                        MlogUtil.d(MlogUtil.MY_TEST, "连接异常");
                    }
                }
            } catch (Exception e) {
                MlogUtil.d(MlogUtil.MY_TEST, "配对异常");
            }
        }
    }
  连接设备和读取数据都需要新启线程在子线程中进行,因为过程比较耗时,如果不在子线程影响效率和阻塞UI。代码我就不做解释了,上面注释写的很清楚了。下面贴读取数据的操作:
//读写线程
    private class ReadThread extends Thread {
        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream mmInStream = null;   //建立输入流读取数据
            try {
                mmInStream = socket.getInputStream();  
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while (true) {  //无限循环读取数据
                try {
                    // Read from the InputStream
                    if ((bytes = mmInStream.read(buffer)) > 0) {
                        byte[] buf_data = new byte[bytes];
                        for (int i = 0; i < bytes; i++) {
                            buf_data[i] = buffer[i];
                        }
                        String s = new String(buf_data);
                        final String data = MyUtil.getResult(s);
                        if (!TextUtils.isEmpty(data)) {
                            getActivity().runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Intent intent = new Intent(MyUtil.BOLOOTH_SEND_DATA);
                                    intent.putExtra("data", data);
                                    getActivity().sendBroadcast(intent);  //获取到蓝牙数据,传递数据
                                }
                            });
                        }
                    }
                } catch (IOException e) {
                    handler.sendEmptyMessage(3);
                    try {
                        mmInStream.close();
                    } catch (IOException e1) {

                    }
                    break;  //异常的时候break跳出无限循环
                }
            }
        }
    }

上面是以流的形式读取数据。

还差一个,就是配对成功后进行连接,所以做个广播接收者,接收配对广播,成功后直接进行连接,广播接收者就不说了,自己脑补,比较简单。下面需要结束连接:

/* 停止客户端连接 */
    private void shutdownClient() {
        new Thread() {
            @Override
            public void run() {
                if (socket != null) {
                    try {
                        socket.close();
                        socket = null;
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        socket = null;
                    }
                }
                if (clientThread != null) {
                    clientThread.interrupt();
                    clientThread = null;
                }
                if (readThread != null) {
                    readThread.interrupt();
                    readThread = null;
                }
            }
        }.start();
    }

当连接失败时需要断开重连或者关闭当前页面时断开连接,执行下就可以了,还有些其他细节上的就不多说了,重点就是这几个操作,至于双向的还需要写个服务器和accept(),这个也不多说了,网上很多,也比较简单。

废话就不多说了,其实也不难,所以也不多做解释了,有什么问题也可以留言。

发布了33 篇原创文章 · 获赞 49 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/gsw333/article/details/53331731