Ble蓝牙设备之(搜索/链接/获取uuid数据)思路分析以及完整Demo

您所在的位置:网站首页 如何查看蓝牙连接的设备 Ble蓝牙设备之(搜索/链接/获取uuid数据)思路分析以及完整Demo

Ble蓝牙设备之(搜索/链接/获取uuid数据)思路分析以及完整Demo

2023-12-02 14:07| 来源: 网络整理| 查看: 265

1,本文主要讲解蓝牙数据的搜索–链接–获取数据值–写入数据值;蓝牙Demo

一:搜索蓝牙设备名称 二:建立链接 三:读取传递过来的值 四:写入数据

蓝牙项目该配置的具体事件

结合自己最近的项目需求,和自身所学所得,代码基本上利用官方的sever服务和gatt链接,只是通过修改获得自己想要的结果,下面就简单介绍一下自己的理解。

一:扫描BLE设备activity

if (!mBluetoothAdapter.isEnabled()) { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } // Initializes list view adapter. mLeDeviceListAdapter = new LeDeviceListAdapter(this); //添加到蓝牙设备 devicelist.setAdapter(mLeDeviceListAdapter);

二:初始化获得一个bluetoothManager,并检测设备是否支持蓝牙

private void checkBluetooth() { // 检查当前手机是否支持ble 蓝牙,如果不支持退出程序 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, "没有提供蓝牙", Toast.LENGTH_SHORT).show(); //finish(); } // 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本) final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); // 检查设备上是否支持蓝牙 if (mBluetoothAdapter == null) { Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show(); //finish(); return; } }

三:蓝牙控制的服务BluetoothLeService

在这个服务里面有一个很重要的回调函数BluetoothGattCallback(),蓝牙的数据读取和状态改变都会回调这个函数。 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { /** * 判断连接是否成功 * @param gatt * @param status * @param newState */ @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if(status==BluetoothGatt.GATT_SUCCESS) { //连接成功的时候 if (newState == BluetoothProfile.STATE_CONNECTED) { //连接成功 intentAction = BroadCast.ACTION_GATT_CONNECTED; //发送广播 broadcastUpdate(intentAction); //打印连接服务 Log.i(TAG, "连接到GATT服务器"); //立即去执行发现服务 gatt.discoverServices(); } //当断开连接的时候 else if (newState == BluetoothProfile.STATE_DISCONNECTED) { //断开连接 intentAction = BroadCast.ACTION_GATT_DISCONNECTED; //打印断开连接 Log.i(TAG, "与GATT服务器断开连接"); //发送广播 broadcastUpdate(intentAction); } } } }

四,发现服务

/** * 发现服务 * @param gatt * @param status */ @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { //连接成功 if(status==BluetoothGatt.GATT_SUCCESS){ //发送发现服务的广播 broadcastUpdate(BroadCast.ACTION_GATT_SERVICES_DISCOVERED); Log.i(TAG,"发现服务是可以的"); }else { Log.w(TAG, "发现接收到的服务: " + status);//发现设备的时候 发送广播 } }

五,数据读取和数据改变

/** * 数据读取 * @param gatt * @param characteristic * @param status */ @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { Log.i("读取出来的值",gatt+" "+characteristic+" "+status); if (status == BluetoothGatt.GATT_SUCCESS) { //读取到里面的数据时候发送广播 broadcastUpdate(BroadCast.ACTION_DATA_AVAILABLE, characteristic); Log.i(TAG,""); } } /** * 数据改变 * @param gatt * @param characteristic */ @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { broadcastUpdate(BroadCast.ACTION_DATA_AVAILABLE, characteristic); } /** * 数据描述读取 * @param gatt * @param descriptor * @param status */ @Override public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { if(status == BluetoothGatt.GATT_SUCCESS){ BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); broadcastUpdate(BroadCast.ACTION_DATA_AVAILABLE, characteristic); Log.i(TAG,"success is data"); } }

六,广播接受和发送数据,重点看如下:

/** * 发送广播数据处理 * @param action * @param characteristic */ private void broadcastUpdate(final String action,final BluetoothGattCharacteristic characteristic){ final Intent intent = new Intent(action); // 当为温度值的时候 以及所有的数据处理 if (characteristic.getUuid().equals(UUIDDataBase.UUID_HEALTH_THERMOMETER_SENSOR_LOCATION)) { String a = BWDataParser.getTempData(characteristic); intent.putExtra(BroadCast.EXTRA_DATA, a); } // 当为温度值的时候 以及所有的数据处理 else if (characteristic.getUuid().equals(UUIDDataBase.UUID_HEALTH_THERMOMETER)) { String health_temp = BWDataParser.getTempData(characteristic); intent.putExtra(BroadCast.EXTRA_DATA_DISPLAY, health_temp); } else if (characteristic.getUuid().equals(UUIDDataBase.UUID_HEALTH_THERMOMETER_NAME)) { String aa = BWDataParser.getTempData(characteristic); intent.putExtra(BroadCast.EXTRA_DATA_DISPLAY_TEMPTWO, aa); } else if (characteristic.getUuid().equals(UUIDDataBase.UUID_HEALTH_TONGDAONAMEDATE)) { Log.i("===3333333333===",characteristic.toString()); String tdname = BWDataParser.getTempData(characteristic); intent.putExtra(BroadCast.EXTRA_DATA_DISPLAY_TONGDAONAME, tdname); } sendBroadcast(intent); }

七,写入数据到蓝牙设备 还有几个重要的函数比如writeCharacteristic(BluetoothGattCharacteristic characteristic)函数,读取蓝牙中数据。

/** * 写入蓝牙数据的方法 * @param charac * @param message * @return boolean */ public static boolean writeCharacteristic(BluetoothGattCharacteristic charac,String message){ //check mBluetoothGatt is available if (bluetoothGatt == null) { Log.e(TAG, "lost connection"); return false; } if(charac!=null&&!message.equals(null)&&!message.equals("")){ //int a = Integer.parseInt(message); byte []a = convertingTobyteArray(message); charac.setValue(a); boolean status = bluetoothGatt.writeCharacteristic(charac); return status; }else{ return false; } }

八:广播的注册事件:

private static IntentFilter makeGattUpdateIntentFilter() { final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); return intentFilter; }

九:断开广播与服务

@Override protected void onDestroy() { super.onDestroy(); // 断开广播连接 if(isunbind) { unregisterReceiver(mGattUpdateReceiver); if(progressDialog!=null){ progressDialog.dismiss(); } //断开蓝牙服务连接 if(bluetoothService!=null){ BluetoothService.disconnect(); } //断开服务连接 if(mServiceConnection!=null) unbindService(mServiceConnection); if(mediaPlayerUtil!=null){ mediaPlayerUtil.mExit(); } ActivityCollector.finishAll(); isunbind = false; } }

十:在发现了有可支持的服务之后会回调Service中的onServicesDiscovered()函数,并发送广播,在官方的demo中发现了可用的Service之后,就查找该BLE设备支持的所有服务和characteristic,在这里不需要查找所有的服务,只需要向蓝牙写数据和读取数据的Service和characteristic的UUID即可。通过查询低功耗蓝牙(BLE)的数据手册可以得到所需要的UUID。

public class GattAttributes { //温度类型 public static final String TEMPERATURE_TYPE = "00002a1d-0000-1000-8000-00805f9b34fb"; //usual public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; //温度探头one public static final String HEALTH_TEMP_MEASUREMENT = "333-0e0d-4bd4-33-9868ddsa"; //温度探头two public static final String TEMP_DATA_NAME = "900876-a249-4443-a04e-7655750"; //通道名字 public static final String TEMP_DATA_TONGDAONAME = "89765tg-f54d-4abb-aa79-87544ffd21"; }

十一:蓝牙开发的具体思路,关于数据传输的一些服务,在这之前我们得先了解一下一些专业词汇:

1、profile profile可以理解为一种规范,一个标准的通信协议,它存在于从机中。蓝牙组织规定了一些标准的profile,例如 HID OVER GATT ,防丢器 ,心率计等。每个profile中会包含多个service,每个service代表从机的一种能力。 2、service service可以理解为一个服务,在ble从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个characteristic特征值。每个具体的characteristic特征值才是ble通信的主题。比如当前的电量是80%,所以会通过电量的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取80%这个数据 3、characteristic characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。 4、UUID UUID,统一识别码,我们刚才提到的service和characteristic,都需要一个唯一的uuid来标识

十二:具体的蓝牙ble开发总结就这些,如果需要完整蓝牙demo,可以进行下载,博主亲自测试完毕,Demo搜索–链接–读取–写入,若有不理解的地方可以私信回复,希望帮助到更多的初学者!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3