产品需求:1、app通过蓝牙连接到板子设备
2、以发报文的形式与板子设备通讯
3、当设备接受到正确的报文指令后,会将检测的数据返回
4、将返回的数据解析设置到界面显示即可
板子介绍:
准备工作:
1:、与嵌入式工程师交互(将驱动这里指串口,装在电脑上)
2、将对应线路接好
3、报文的协议文档等可先看看了解一下(这里用的是MODBUS RTU协议)
其实也就差不多这些准备(有问题可以直接问相关嵌入式人员),废话少说,下面就直接进行主题吧。。。
第一步:首先我们可以整理一下思路:
1、实现搜索功能,针对蓝牙周围设备的发现
2、对目标 设备进行连接
3、开发期间是多与串口交互(可以先实现app将数据传递串口,协议先不做考虑)
4、在实现串口向app的数据的传递(协议先不做考虑)
5、实现对数据的解析(根据协议去实现解析即可),在将数据显示即可
以上为整体的实现步骤,开发的时候在具体到细节!
第二步:防止一头雾水,我们先来简单复习一下BlueTooth相关的api
1:BuletoothAdapter
这个类的对象代表了本地的蓝牙适配器,相当于蓝牙工作流程图中的手机里的蓝牙适配器,也就是说比如这个应用程序是运行在手机上,那么手机上的蓝牙适配器就是本地蓝牙适配器。
cancelDiscovery() 根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索
disable() 关闭蓝牙
enable() 打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:
Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler,reCode); 同startActivity(enabler);
getAddress() 获取本地蓝牙地址
getDefaultAdapter() 获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter
getName() 获取本地蓝牙名称
getRemoteDevice(String address) 根据蓝牙地址获取远程蓝牙设备
getState() 获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)
isDiscovering() 判断当前是否正在查找设备,是返回true
isEnabled() 判断蓝牙是否打开,已打开返回true,否则,返回false
listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步
startDiscovery() 开始搜索,这是搜索的第一步
2:BuletoothDevice
这个类的对象代表了远程的蓝牙设备,相当于蓝牙工作流程图中的计算机里的蓝牙适配器,也就是说比如这个应用程序是运行在手机上,那么BuletoothDevice代表了你要连接的远程的那个设备上面的蓝牙适配器。
createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket 这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket
3.BluetoothSocket,跟BluetoothServerSocket相对,是客户端一共5个方法,不出意外,都会用到
close(), 关闭
connect() 连接
getInptuStream() 获取输入流
getOutputStream() 获取输出流
getRemoteDevice() 获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备
第三步:实现功能
3.1:开启蓝牙,判断手机是否支持蓝牙
3.3:判断是否启用蓝牙对话框 3.4:开始进行蓝牙设备的搜索 - 注意一点:这里不要在onCreate里面去进行搜索,会出现没有响应
3.5:当设备搜索到的时候,代码会回调LeScanCallback接口 3.6:搜索到设备的时候开始进行连接 - 代码里面进行服务的开启,里面进行读写的操作的封装
3.7:当连接成功之后,会走BluetoothGatttCallBack接口,这里主要实现读写的操作 3.8:连接成功时候,我们可以获取板子中的服务 - 以及相关 的服务的UUID(重要 - 后面图片实例介绍) 3.9:获取到服务之后开始去解析服务 - 目的是为了将其中的uuid得到,因为后期的读写操作需要进行的使用 Characteristic -
注意:这里你就可以和相关的嵌入式工程师交互,使用哪些服务以及使用哪些UUID即可
4.2:这里的读写就要注意了(要根据项目的开发协议而定),一会儿实例!
4.3:针对读的操作在加深一下理解:请看
BluetoothGattService batteryService=mBluetoothGatt.getService(UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb")); if(batteryService!=null){
BluetoothGattCharacteristic batteryCharacteristic=batteryService.getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")); if(batteryCharacteristic!=null){
mBluetoothGatt.readCharacteristic(batteryCharacteristic); } } }//如果读取电量(或者读取其他值)成功之后 ,会来到 回调: @Override public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); //读取到值,根据UUID来判断读到的是什么值 if (characteristic.getUuid().toString() .equals("00002a19-0000-1000-8000-00805f9b34fb")) {// 获取到电量 int battery = characteristic.getValue()[0]; } } void sendSetting(){ BluetoothGattService sendService=mBluetoothGatt.getService(UUID.fromString("00001805-0000-1000-8000-00805f9b34fb")); if(sendService!=null){
BluetoothGattCharacteristic sendCharacteristic=sendService.getCharacteristic(UUID.fromString("00002a08-0000-1000-8000-00805f9b34fb")); if(sendCharacteristic!=null){ sendCharacteristic.setValue(new byte[] { 0x01,0x20,0x03 });//随便举个数据 mBluetoothGatt.writeCharacteristic(sendCharacteristic);//写命令到设备, } } } //如果下发配置成功之后,会来到回调: @Override public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); if (status == BluetoothGatt.GATT_SUCCESS) {//write成功(发送值成功),可以根据 characteristic.getValue()来判断是哪个值发送成功了,比如 连接上设备之后你有一大串命令需要下发,你调用多次写命令,
这样你需要判断是不是所有命令都成功了,因为android不太稳定,有必要来check命令是否成功,否则你会发现你明明调用 写命令,但是设备那边不响应 } } 第四步:主要的相关的代码如上,具体的实现就没有直接展示了。敬请原谅!谢谢!
本人也是第一次操作蓝牙这一块,期间看了很多的博客,很有帮助,推荐给大家(链接),也可以自己去查资料。
点击打开链接
点击打开链接
串口:使用的demo,app和蓝牙交互与串口交互:(有需要可以找我接收)