让我们先来简单了解下什么是ble蓝牙
安卓4.3为BLE的核心功能提供平台支持和API(也就是说只有api大于等于18的设备才能用ble蓝牙) ,App可以利用它来发现设备、查询服务和读写特性。相比传统的蓝牙,BLE更显著的特点是低功耗。
这一优点使Android App可以与具有低功耗要求的BLE设备通信。- -
是不是有点看不懂,哈哈哈,没关系。我最开始也是一脸懵逼的,这ble蓝牙是什么鬼,在网上看了那么多 感觉就是五花八门的翻译官方的那份文档 太坑了,没关系下面让我来为大家具体介绍:
这里盗用了两位大神的两张图,谢谢了~~
第一张图,使用低功耗蓝牙可以包括多个Profile,一个Profile中有多个Service,一个Service中有多个Characteristic,一个Characteristic中包括一个value和多个Descriptor。
第二张图 Android中进行蓝牙开发需要使用到的类的执行过程是:
1、使用BluetoothAdapter.startLeScan来扫描低功耗蓝牙设备
2、在扫描到设备的回调函数中会得到BluetoothDevice对象,并使用BluetoothAdapter.stopLeScan停止扫描
3、使用BluetoothDevice.connectGatt来获取到BluetoothGatt对象
4、执行BluetoothGatt.discoverServices,这个方法是异步操作,在回调函数onServicesDiscovered中得到status,通过判断status是否等于BluetoothGatt.GATT_SUCCESS来判断查找Service是否成功
5、如果成功了,则通过BluetoothGatt.getService来获取BluetoothGattService
6、接着通过BluetoothGattService.getCharacteristic获取BluetoothGattCharacteristic
7、然后通过BluetoothGattCharacteristic.getDescriptor获取BluetoothGattDescriptor
1 首先如果我们要使用ble蓝牙需要在manifest 声明需要用到的权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2 检查设备是否开启蓝牙,如果没有则开启对话框启动蓝牙
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
}
大家不用慌,bluetoothAdapter 在下一步我们会获取的,这里只是为了让大家更清楚逻辑我把他写在了前面.
3 初始化蓝牙适配器
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
4 扫描周围蓝牙设备
bluetoothAdapter.startLeScan(mScanCallback);
注意 mScanCallBack,是我们扫描结果的回调,也就是说我们可以在这个回调中获取刚才扫描出的蓝牙设备
private BluetoothAdapter.LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//这里的device就是我们扫描的出来的蓝牙设备,我把他加到里mBluetoothDevice的集 合中。 当然我们也可以通过device获取 蓝牙的mac地址和名字 比如device.getAddress(),device.getName()
if (!mBluetoothDevice.contains(device)) {
mBluetoothDevice.add(device);
myAdapter.notifyDataSetChanged();
}
}
});
}
};
5.操作蓝牙的读写notify
read:获取蓝牙设备返回的信息 比如 血压,步行
write:app发送指令操作蓝牙设备
notify: 点击设备上的按钮操作app
BluetoothGatt bluetoothGatt = device.connectGatt(MainActivity.this, false, gattCallback);
我们通过上面获取的device(蓝牙设备),调用他的connectGatt方法来操作蓝牙的读写或者是notify方法,这个方法的第一参数是上下文,第二个参数 如果是ture表示 自动连接, false表示立刻进行一次连接。开发中我们一般用false,第三个参数就是我们操作的结果的回调,我们要获取的数据都在这个回调中。其实我们回调中操作的主要是 最开始我说的那个Value[] 数组 通过他来获取值和设置值
private android.bluetooth.BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
//蓝牙当前状态的回调 我们判断newState 来获取当前的状态
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, final int newState) {
super.onConnectionStateChange(gatt, status, newState);
runOnUiThread(new Runnable() {
@Override
public void run() {
switch (newState) {
case BluetoothGatt.STATE_CONNECTED:
//"已连接";
//你自己的操作逻辑
break;
case BluetoothGatt.STATE_CONNECTING:
//"连接中";
//你自己的操作逻辑
break;
case BluetoothGatt.STATE_DISCONNECTED:
//"已断开"
//你自己的操作逻辑
break;
case BluetoothGatt.STATE_DISCONNECTING:
//"正在断开"
//你自己的操作逻辑
break;
default:
break;
}
}
});
}
//蓝牙服务被发现的回调,我们可以通过他的不同UUID 来发送或者接受我们需要的指令
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
//获取蓝牙中所以的服务
List<BluetoothGattService> services = bluetoothGatt
.getServices();
for (BluetoothGattService bluetoothGattService : services) {
//获取服务中的特征
List<BluetoothGattCharacteristic> characteristics = bluetoothGattService
.getCharacteristics();
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : characteristics) {
//写数据 注意下面的UUID 是我测试用的,使用时换成你们设备的UUID的就行了
if (bluetoothGattCharacteristic.getUuid().toString()
.equals("00001001-0000-1000-8000-00005f9b34fb")) {
//你自己的操作逻辑
writeCharacteristicl = bluetoothGattCharacteristic;
//notify
//通知数据
} else if (bluetoothGattCharacteristic.getUuid().toString()
.equals("00001002-0000-1000-8000-00005f9b34fb")) {
//你自己的操作逻辑
notifyCharacteristic = bluetoothGattCharacteristic;
enableNotification(true, notifyCharacteristic);
//读数据
} else if (bluetoothGattCharacteristic.getUuid().toString()
.equals("00001003-0000-1000-8000-00005f9b34fb")) {
//你自己的操作逻辑
readCharacteristic = bluetoothGattCharacteristic;
bluetoothGatt.readCharacteristic(readCharacteristic);
}
}
}
}
}
//当执行完bluetoothGatt.readCharacteristic(readCharacteristic)的回调
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//你自己的操作逻辑
super.onCharacteristicRead(gatt, characteristic, status);
byte[] value = characteristic.getValue();
String data = bytesToHexString(value);
Log.e(TAG, "onCharacteristicRead: "+data );
}
@Override//bluetoothGatt.writeCharacteristic(writeCharacteristic)的回调
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//你自己的操作逻辑
super.onCharacteristicWrite(gatt, characteristic, status);
}
@Override//当执行完 enableNotification(true, notifyCharacteristic);的回调
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
//你自己的操作逻辑
super.onCharacteristicChanged(gatt, characteristic);
byte[] value = characteristic.getValue();
String data = bytesToHexString(value);
Log.e(TAG, "onCharacteristicChanged: "+data );
if (data.startsWith("550f03")){
String endData = data.substring(16, 18);
final Integer Hxueya = Integer.valueOf(endData, 16);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_XueYa.setText(Hxueya+"");
}
});
}
sendDataBMP();
}
};
最后欢迎加入我的QQ群讨论: 312327703
- -