先说我的应用场景,android手机跟一块带有蓝牙模块的板子通信。为了节省成本那块板子的蓝牙模块是2.0的,而现在大多数手机带的蓝牙都是4.0 以上的。所以我的应用应该是蓝牙4.0以上与蓝牙2.0的通信。
在此说明一下蓝牙4.0 与2.0 之间通信是ok的,蓝牙的开放性、兼容性都很强的,只是传输速率是按2.0的。还有蓝牙传输的是字节流,每包最大能发20个字节,所以在定传输协议的时候一定要考虑进去,我们的协议定义我会在下面详细说明下。
参考项目地址:点我吧,亲测可用
项目结构
主要类说明:
MyApplication:打开蓝牙
BleRotocoUtils:是我们自己定义的协议类
BlueToothManager:蓝牙管理类(主要是:初始化,搜索设备,设备连接,发送数据,接收数据,关闭等功能)
MyBlueTooth2: 蓝牙2.0管理类(上述参考项目里有源码)
MyBlueTooth4:蓝牙4.0管理类(上述参考项目里有源码)
BluetoothConnectActivityReceiver: 监听蓝牙配对的消息(两个设备连接时,如果没有配对,系统会弹出一个配对弹框,密码默认1234,只有配对成功才能连接通信)
蓝牙通信协议定义:
命令码:(以启停功能为例,其他功能道理一样,按自己需求定就ok)
异或校验:(一个字节)
/**
* datas 需要校验的字符数组
**/
public static byte getXor(byte[] datas){
bytetemp=datas[0];
for(int i =1; i < datas.length;i++){
temp ^=datas[i];
}
return temp;
}
代码奉上,请笑纳。注:i是从1开始的 因为协议定的是 起始码 不参与校验!!!
介绍完帧定义格式,接下来 就是按协议codding了
/**
* 发送“启动指令”:
**/
public static byte[] device2Start(){
byte[] date = new byte[5];
date[0] = (byte)0xFF; //起始码
date[1] = (byte)0x04; //长度
date[2] = (byte)0x02; // 命令
date[3] = (byte)0x01; //命令字
date[4] = getXor(date); //异或校验
return date;
}
返回的是字节数组 ,直接调用 sendMessage(btye[] msg) 就可以发动命令了。
接收数据同理:接收的也是字节数组,获取到数据格式也是协议上的这个格式,直接按数组下标取值就行。
项目过程中还有一点需要注意:
蓝牙使用权限问题:
android 6.0 以下的手机只需要以下两个权限即可
android6.0 以上的手机 用蓝牙权限的话,需要打开定位权限。定位权限是启动权限
启动权限需要每次打开应用请求用户打开。
我的开发工具是Androidstudio,安装了permissiondispatcher插件,使用很方便。
另外,我还添加了下面这个权限
required 为 true时,应用只能在支持BLE的adroid设备是安装运行。
required 为 false时,android设备均能安装,这时需要代码运行时判断设备支持BLE。
至此结束,祝各位顺利....