开发低功耗蓝牙4.0血压计连接与收发数据
来源:互联网 发布:鸟哥linux基础篇 pdf 编辑:程序博客网 时间:2024/05/01 10:04
最近在开发鱼跃YE680A蓝牙血压计,获取测量到的血压和心率数据,之前也做有一个爱奥乐蓝牙血压计的,连接流程是一样的,在收发数据时有一些区别,下面做一些笔记:
一、整体的可定义三个类,一个Bluetooth服务的,用于连接,一个包含各类UUID的,用于收发数据,最后一个封装工具类,给调用者调用。
1. 先说连接吧,判断是不是支持蓝牙功能,是否打开蓝牙和请求打开蓝牙涉及到的,代码详细可能没贴出来了,网上一搜大把的。
private BluetoothAdapter mBluetoothAdapter; private BluetoothLeScanner mBluetoothLeScanner; private boolean isScanning; // 是否正在搜索 private void initBluetooth() { BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if(mBluetoothAdapter == null) { app.showToast(R.string.msg_bluetooth_no_support); return; } else { if(!mBluetoothAdapter.isEnabled()) { requestOpenBluetooth(); // 请求打开蓝牙 } mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); } } /** * 开始搜索设备 * @param scan */ public void scanLeDevice(boolean scan) { if(mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) { requestOpenBluetooth(); // 请求打开蓝牙 return; } else if(mBluetoothAdapter == null || mBluetoothLeScanner == null) { MyLg.e("scanLeDevice", "mBluetoothLeScanner == null"); return; } if(scan) { if(!isScanning) { mBluetoothLeScanner.startScan(mScanCallback); // 开始搜索设备 } isScanning = true; } else { mBluetoothLeScanner.stopScan(mScanCallback); isScanning = false; } }
下面是扫描设备时的回调:
private ScanCallback mScanCallback = new ScanCallback() { @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); MyLg.e("onScanFailed", "onScanFailed"); } @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); String deviceName = result.getDevice().getName(); // 搜索到的设备名称 if(!TextUtils.isEmpty(deviceName)) { if(deviceName.equals(DEVICE_NAME1)) { // 连接爱奥乐蓝牙血压计 mDeviceAddress = result.getDevice().getAddress(); // 蓝牙血压计地址 boolean isBind = bindService(); // 连接绑定服务 MyLg.d("onScanResult", "isBind=" + isBind); scanLeDevice(false); // 停止扫描 } else if(deviceName.equals(DEVICE_NAME2)) { // 连接鱼跃蓝牙血压计 mDeviceAddress = result.getDevice().getAddress(); // 蓝牙血压计地址 boolean isBind = bindService(); // 连接绑定服务 MyLg.d("onScanResult", "isBind=" + isBind); scanLeDevice(false); // 停止扫描 } } } }; /** * 开启后台服务,需要在获取到设备地址后才可连接 */ private boolean bindService() { Intent serIntent = new Intent(mContext, BluetoothLeService.class); isBindService = mContext.bindService(serIntent, mServiceConnection, Context.BIND_AUTO_CREATE); return isBindService; }
上面连接绑定服务时就用到了BluetoothLeService这个类,主要是连接,贴出代码。
private final ServiceConnection mServiceConnection = new ServiceConnection() { // 服务绑定成功就会回调 @Override public void onServiceConnected(ComponentName componentName, IBinder service) { mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); if (!mBluetoothLeService.initialize()) { MyLg.e("onServiceConnected", "Unable to initialize Bluetooth"); } // 传入设备地址,这里就开始连接 if (mBluetoothLeService.connect(mDeviceAddress)) { MyLg.e("onServiceConnected", "mDeviceAddress=" + mDeviceAddress); mBluetoothGatt = mBluetoothLeService.getGatt(); } } @Override public void onServiceDisconnected(ComponentName componentName) { MyLg.e("onServiceDisconnected", "componentName=" + componentName); mBluetoothLeService = null; } };/** * 连接操作 */public boolean connect(final String address) { if (mBluetoothAdapter == null || address == null) { Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); return false; } final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { Log.w(TAG, "Device not found. Unable to connect."); return false; } // We want to directly connect to the device, so we are setting the // autoConnect // parameter to false. mBluetoothGatt = device.connectGatt(this, false, mGattCallback); // 这里有个连接状态的回调mGattCallback Log.e(TAG, "Trying to create a new connection."); mBluetoothDeviceAddress = address; mConnectionState = STATE_CONNECTING; return true; }// 连接后状态回调private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { boolean discover = mBluetoothGatt.discoverServices(); // 搜索发现可用服务 Log.e(TAG, "连接成功>>discoverServeices=" + discover); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { Log.e(TAG, "83失败"); } } /** * 可用服务时回调 */ @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { MyLg.e("onServicesDiscovered", "status=" + status); if (status == BluetoothGatt.GATT_SUCCESS) { boolean notify = SampleGattAttributes.notify(gatt); // 这里就涉及到收发数据了,可以发命令给蓝牙设备,也可以单单notify,indicate监听回传的数据 Log.e(TAG, "98notify>>>" + notify); } else { Log.e(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { Log.e(TAG, "onCharacteristicRead()"); if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, EXTRA_READ_DATA, characteristic); } else { Log.e(TAG, "onCharacteristicRead() - status = " + status); } } /** * 下面是数据接收的回调 */ @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { byte[] value = characteristic.getValue(); // 数据 Log.e(TAG, "127=" + value.length); broadcastUpdate(ACTION_DATA_AVAILABLE, EXTRA_NOTIFY_DATA, characteristic); } };
最后就是收发数据的类,这里比较重要了,有一些需要注意。
/** * 向蓝牙设备发送命令 * @param gatt * @param data 要发送的字节命令 * @return */ public static boolean sendMessage(BluetoothGatt gatt, byte[] data) { Log.e("TAG_sendMessage", "sending start"); if (gatt == null || data.length == 0) return false; BluetoothGattService service = gatt.getService(UUID.fromString(GATT_SERVICE_PRIMARY2)); // 这个是对应的蓝牙设备哪个功能的Primary Service UUID if (service == null) {// sendDataByte(gatt); // 若为空重新发命令 return false; } BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_WRITEABLE2)); // 这个是对应的蓝牙设备写操作的write service UUID if (characteristic == null) {// sendMessage(gatt, data); // 若为空重新发命令 return false; } characteristic.setValue(data); // 设置发送的命令 characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); // 命令类型 boolean succ = gatt.writeCharacteristic(characteristic); // 向蓝牙设备发送命令了 Log.e("TAG", "writeCharacteristic_succ=" + succ); return succ; }
上面这是要发送命令的,下面这种是notify或indicate就可以在onCharacteristicChanged直接监听回传的数据了
/** * notify或indicate * @param gatt * @return */ public static boolean notify(BluetoothGatt gatt) { if (gatt == null) { return false; } BluetoothGattService service = gatt.getService(UUID.fromString(GATT_SERVICE_PRIMARY2)); // 这个一样的,是对应的蓝牙设备哪个功能的Primary Service UUID if (service == null) { return false; }// BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_NOTIFY2)); // 这是notify的UUID// Log.e("TAG_notify", "notify_characteristic=" + characteristic); BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(CHARACTERISTIC_INDICATE)); // 这是indicate的UUID Log.e("TAG_notify", "indicate_characteristic=" + characteristic); if (characteristic != null) { BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)); // config的UUID descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); // 这里就根据上面是notify还是indicate的UUID,设置对应的值(还有BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE等) gatt.writeDescriptor(descriptor); } return gatt.setCharacteristicNotification(characteristic, true); // 这样就可以监听蓝牙设备回传的数据,该如何处理解析自己看着办咯(每个蓝牙设备都有协议,解析规则等) }
到这里已经大功告成,代码量确实有点多,有点乱(纯属手打,自己开发记的笔记),但是重要的注释我都写出来了,相信你有耐心看肯定能懂,当然你若知道了这个流程,不用仔细看也知道思路了。
阅读全文
1 0
- 开发低功耗蓝牙4.0血压计连接与收发数据
- Android 低功耗蓝牙的多设备连接与数据接收,简单实现
- Android BLE低功耗蓝牙开发极简系列(一)之扫描与连接
- Android蓝牙低功耗开发
- iOS开发—蓝牙4.0(BLE)与外设连接及收发数据的流程
- 4.0低功耗蓝牙解决方案
- 低功耗蓝牙BLE之连接建立
- 低功耗蓝牙的连接过程
- 开发android蓝牙4.0 BLE低功耗应用的感受
- 低功耗蓝牙4.0BLE编程-nrf51822开发(1)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(2)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(3)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(4)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(5)-链路层
- 低功耗蓝牙4.0BLE编程-nrf51822开发(8)-GATT
- 低功耗蓝牙4.0BLE编程-nrf51822开发(9)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(1)
- 低功耗蓝牙4.0BLE编程-nrf51822开发(2)
- Python3.0版本中特定语言的删除
- Linux/Ubuntu校园网下ipv6无法有效上网问题解决办法
- 118. Pascal's Triangle
- 自己实现简单的RPC
- java设计模式--单例模式
- 开发低功耗蓝牙4.0血压计连接与收发数据
- CSU-ACM2017暑期训练1-Debug与STL E
- 耦合所隐藏的信息
- 【C#】在窗口输出字符串
- 精通css 第六章 (1)导航栏
- 百练_4002:谁是你的潜在朋友
- php autoload 应用2
- 生成spfile
- MindManager教你玩转微信营销