美文网首页简化开发
Android蓝牙(二):设备的连接和通信

Android蓝牙(二):设备的连接和通信

作者: itfitness | 来源:发表于2021-12-16 16:21 被阅读0次

目录

效果展示

●客户端



●服务端


相关文章

Android蓝牙(一):设备的扫描
本篇文章是接着上面的文章写的,没看上面文章的同学可以点击进行查看

通信原理

整个通信的过程其实就是使用的Socket,基本跟Java的Socket通信一样

实现步骤

1.添加开启服务逻辑

我们用的是BluetoothAdapterlistenUsingRfcommWithServiceRecord方法,它的参数如下:
name:String类型,这个可以随便起个名。
uuid:UUID类型,这个可以通过这个网站(https://1024tools.com/uuid)生成一个,要注意客户端和服务端的UUID要一致才能连接。
具体代码如下,我们在开启服务之后会通过一个死循环的线程(这里可以做成参数控制线程)去监听连接的设备,当有设备连接的时候就发送当前设备的名字给连接的客户端设备

private val TAG = "BluetoothDemo"
private val MUUID = "46e38342-aff4-4da7-9568-f5e3f7d6d2a6" //用于连接的UUID
private var bluetoothServerSocket:BluetoothServerSocket? = null //服务端Socket
/**
     * 开启连接服务
     */
    private fun openService() {
        bluetoothAdapter?.let {
            if(!it.isEnabled){
                ToastUtils.showShort("请先开启蓝牙")
            }else{
                bluetoothServerSocket = it.listenUsingRfcommWithServiceRecord(TAG, UUID.fromString(MUUID))
                Thread {
                    while (true){
                        bluetoothServerSocket?.let { serverSocket->
                            val socket = serverSocket.accept()
                            val device = socket.remoteDevice
                            if(socket.isConnected){
                                device?.let {
                                    LogUtils.eTag("状态","${device.bondState}")
                                    ToastUtils.showShort("设备:${device.name} 已连接${device.bondState}")
                                }
                            }
                            sendData2Client(socket)
                        }
                    }
                }.start()
            }
        }
    }

    /**
     * 发送消息给客户端
     */
    private fun sendData2Client(socket: BluetoothSocket?) {
        socket?.let {
            val os = socket.outputStream
            try {
                val msg = "你好我是${bluetoothAdapter?.name}"
                os.write(msg.toByteArray())
                os.flush()
                os.close()
                socket.close()
            }catch (e:Exception){
                LogUtils.eTag("出错",e.message)
            }finally {
                os.close()
                socket.close()
            }
        }
    }
2.客户端配对逻辑

这里我们在之前的设备列表中加入一个按钮



我们通过判断列表中每个设备的状态来调整按钮的显示信息

deviceAdapter = object :BaseQuickAdapter<BluetoothDevice,BaseViewHolder>(R.layout.item_bluetooth,deviceList){
            override fun convert(holder: BaseViewHolder, item: BluetoothDevice) {
                val tvDeviceName = holder.getView<TextView>(R.id.tv_deviceName)
                val btConnect = holder.getView<Button>(R.id.bt_connect)
                tvDeviceName.text = item.name
                btConnect.visibility = View.VISIBLE
                when(item.bondState){
                    //未配对
                    BluetoothDevice.BOND_NONE->{
                        btConnect.text = "配对"
                    }
                    //已配对
                    BluetoothDevice.BOND_BONDED->{
                        btConnect.text = "连接"
                    }
                }
                btConnect.setOnClickListener {
                    when (item.bondState) {
                        //未配对 进行配对
                        BluetoothDevice.BOND_NONE -> {
                            item.createBond()
                        }
                        //已配对 进行连接
                        BluetoothDevice.BOND_BONDED -> {
                            connectDevice(item)
                        }
                    }
                }
            }
        }

假如我们没有配对的话,列表的设备会显示配对按钮,然后点击后会进行配对,如下所示


2.客户端连接逻辑

配对成功之后我们就可以进行连接通信了,这里我们用的是BluetoothDevicecreateRfcommSocketToServiceRecord方法,参数如下:
uuid:UUID类型,需要与服务端的UUID一致
连接设备后我们会读取服务端发的信息,具体如下:

 /**
     * 连接设备
     */
    private fun connectDevice(device: BluetoothDevice) {
        bluetoothClientSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(MUUID))
        bluetoothClientSocket?.let {
            Thread{
                try {
                    it.connect()
                    if(it.isConnected){
                        ToastUtils.showShort("已连接")
                        readServerData(it)
                    }else{
                        ToastUtils.showShort("未连接")
                    }
                }catch (e:Exception){}
            }.start()
        }
    }

    /**
     * 读取服务端的数据
     */
    private fun readServerData(socket: BluetoothSocket) {
        val ins = socket.inputStream
        try {
            val buffer = ByteArray(60)
            val size = ins.read(buffer)
            if(size > 0){
                val msg = String(buffer,0,size)
                LogUtils.eTag("消息",msg)
                ToastUtils.showShort(msg)
            }
            ins.close()
            socket.close()
        }catch (e:Exception){
            LogUtils.eTag("出错",e.message)
        }finally {
            ins.close()
            socket.close()
        }
    }

案例源码

本篇文章的代码为了区分清楚,与文章开头相关文章的代码分开了,地址如下:
https://gitee.com/itfitness/bluetooth-connect-device-demo

相关文章

网友评论

    本文标题:Android蓝牙(二):设备的连接和通信

    本文链接:https://www.haomeiwen.com/subject/clsvfrtx.html