项目的一个功能,蓝牙多连接。应用同时连接多个设备,等待接收数据,处理后显示图表。
在这之前我没有搞过蓝牙方面的东西,只能从基础开始边看边干。
最开始不知道,看的是传统蓝牙的连接与传输,几天过后,发现与低功耗蓝牙不一样啊,又针对低功耗蓝牙开始找资料。
低功耗蓝牙支持的api最低是18。
基本思路:低功耗蓝牙连接分两种,一种是作为周边设备,一种是作为中心设备。因为需求是多连接,那我们就按照创建一个中心设备的做法来处理。
下面先记录一下,一个低功耗蓝牙的连接:
注:因为程序与硬件是一套设备,所以我不需要扫瞄附近的设备,然后选择连接,直接拿地址进行连接。
蓝牙需要的权限:
接下来在activity中,不管周边设备还是中心设备,我们都需要拿到:BluetoothManager和BluetoohAdapter:
//获取BluetoothManager
BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
//获取BluetoothAdapter
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
//如果蓝牙没有打开 打开蓝牙
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
然后就是通过上面拿到的adapter得到BluetoothDevice对象:
BluetoothDevice bluetoothDeviceOne = mBluetoothAdapter.getRemoteDevice("D8:B0:4C:BC:C0:83");
2.假如你需要多连接,那么这里就要获得多个BluetoothDevice对象,通过不同的地址。
然后就是BluetoothGatt对象:
private BluetoothGatt mBluetoothGattOne;
//如果Gatt在运行,将其关闭
if (mBluetoothGattOne != null) {
mBluetoothGattOne.close();
mBluetoothGattOne = null;
}
//连接蓝牙设备并获取Gatt对象
mBluetoothGattOne = bluetoothDeviceOne.connectGatt(MainActivity.this, true, bluetoothGattCallbackOne);
/**
* 第一个设备 蓝牙返回数据函数
*/
private BluetoothGattCallback bluetoothGattCallbackOne = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
setText("设备一连接成功");
//搜索Service
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
setText("设备一连接断开");
}
}
super.onConnectionStateChange(gatt, status, newState);
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//根据UUID获取Service中的Characteristic,并传入Gatt中
BluetoothGattService bluetoothGattService = gatt.getService(UUID_SERVICE);
BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID_NOTIFY);
boolean isConnect = gatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
if (isConnect){
}else {
Log.i("geanwen", "onServicesDiscovered: 设备一连接notify失败");
}
super.onServicesDiscovered(gatt, status);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {//数据改变
super.onCharacteristicChanged(gatt, characteristic);
String data = new String(characteristic.getValue());
Log.i("geanwen", "onCharacteristicChanged: " + data);
}
};
2.上面onConectionStateChange方法就是连接状态改变时回调的方法,在其中判断连接是否成功。
3.上面onServicesDiscovered方法就是在onConectionStateChange连接成功之后,发现该蓝牙的服务。
在这里你可以设置你需要的服务,每个蓝牙连接中会有不同的服务,设置你需要的即可。
4.上面我设置了接收数据的服务,其中传入的几个常量就是我们低功耗蓝牙的服务的固定码,下面贴个例子:
//蓝牙设备的Service的UUID
public final static UUID UUID_SERVICE = UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131");
//蓝牙设备的notify的UUID
public final static UUID UUID_NOTIFY = UUID.fromString("0003cdd1-0000-1000-8000-00805f9b0131");
因为我这个需求是不能先搜索,在连接,然后选择对应服务的,所以我将这些这些操作都省略,即我提前拿到了这几个服务的码。
5.上面回调方法onCharacteristicChanged方法就是来数据了,接收的方法。
连接一个低功耗蓝牙并接收数据上面就介绍完了,下面说下连接两个或者多个。
到这里是后期来修改的,原来简单的通过上面的连接一个,多次创建对应的对象来实现多连接。
那样第一个代码量有点大,重复工作做的多。性能还不是很好。
下面我在github找到一个框架,大神封装的模块,clone到本地看他的代码,学习一番,
下面贴出地址:
点击打开链接
具体使用,他的文档中记录的很详细了
学习思路之后自己也封装一下。
实现多连接过程中遇到了几个问题,这里记录下。
当你的业务需求需要连接多个设备的时候,
需要考验你的手机/平板的设备了,(价钱高一些性能好一些)
我试用的华为6.0的平板,同时连接三个是相对稳定一些,一次搜索并连接三个,第四个设备需要重新搜索才能成功。
小米的7.0系统的平板,连接四个很快的。
部分手机/平板是国内厂商定制的,不能搜索到蓝牙设备或者不能连接设备,可能的原因是硬件设备没有对这些厂商进行兼容。