目录
效果展示
●客户端
●服务端
相关文章
Android蓝牙(一):设备的扫描
本篇文章是接着上面的文章写的,没看上面文章的同学可以点击进行查看
通信原理
整个通信的过程其实就是使用的Socket,基本跟Java的Socket通信一样
实现步骤
1.添加开启服务逻辑
我们用的是BluetoothAdapter的listenUsingRfcommWithServiceRecord方法,它的参数如下:
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.客户端连接逻辑
配对成功之后我们就可以进行连接通信了,这里我们用的是BluetoothDevice的createRfcommSocketToServiceRecord方法,参数如下:
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
网友评论