上篇文章主要介绍了关于BLE的一些基础操作,我们能够大概了解到蓝牙操作的一些流程,上文末介绍了本人的一个BLE开源库,支持蓝牙一对多的连接方式,该库封装了蓝牙的开启、扫描、连接、断开、连接超时...一系列的操作流程,大大简化了开发者的负担,那么接下来将重点讲解该蓝牙库的用法。

1、我们先来看一下该库的结构,以及每个类的作用。如下图:

结构.png

这里先不讲解iQppCallback和QppApi两个类,这两个类暂时并未用到,后期维护时会详细讲解。

第一个类BleDevice,该类的主要是来描述并记录蓝牙的属性和状态,如记录蓝牙名称、蓝牙MAC地址、蓝牙别名(即修改之后的名称)、蓝牙连接状态等。

第二个类BleConfig,该类是蓝牙配置类,里面包含了蓝牙服务的UUID、蓝牙特征的UUID、描述的UUID、以及蓝牙状态的静态常量值的标记等等,其中蓝牙相关的UUID的设置是对外提供了接口的,用的时候可以自行传入特定的UUID即可。

第三个类BleLisenter,该类提供了蓝牙各个状态的接口,此处做成了抽象类,目的是为了可以让用户有条件的去实现想要实现的方法,比如说客户想要在蓝牙扫描开始的时候添加一些动画效果,那么你就可以实现onStart()方法,然后在其中做你想做的事情,默认是不需要实现的,如果你想要在蓝牙设备返回数据时做出反应,那就去实现onRead()方法,如果你想在蓝牙连接失败或者超时的情况下去做特殊的处理,你就去实现onError()或者onConnectTimeOut()方法等等。

第四个类BleManager,该类提供了几乎所有你需要用到的方法,包括蓝牙扫描、连接、断开、蓝牙当前连接状态等等,管理了蓝牙操作的所有接口和方法。

第五个类BluetoothLeService,该类是最重要的一个类,主要是蓝牙操作中用到的各个方法的实现类。

2、具体用法:

首先要现在AndroidManifest文件中加入蓝牙操作所需要的一些权限,此处不再赘述,大致流程可参考Android BLE蓝牙详细解读(一),接下来我们一步一步来详细讲解用法。

1. 初始化蓝牙(包含了动态授权蓝牙操作权限、打开蓝牙、判断设备是否支持蓝牙)

private void initBle() {

try {

mManager = BleManager.getInstance(this);

mManager.registerBleListener(mLisenter);

boolean result = false;

if (mManager != null) {

result = mManager.startService();

if (!mManager.isBleEnable()) {//蓝牙未打开

mManager.turnOnBlueTooth(this);

} else {//已打开

requestPermission(new String[]{Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_COARSE_LOCATION}, getString(R.string.ask_permission), new GrantedResult() {

@Override

public void onResult(boolean granted) {

if (!granted) {

finish();

} else {

//开始扫描

mManager.scanLeDevice(true);

}

}

});

}

}

if (!result) {

Logger.e("服务绑定失败");

if (mManager != null) {

mManager.startService();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

如果没有打开蓝牙,当点击打开蓝牙的提示框后,会在

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// User chose not to enable Bluetooth.

if (requestCode == BleManager.REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {

finish();

return;

} else {

if (mManager != null) {

mManager.scanLeDevice(true);

}

}

super.onActivityResult(requestCode, resultCode, data);

}

该方法中收到回调信息,打开后则开启扫描,否则则根据你自己的需要进行操作。

2. 通过注册监听的方式,这里我们可以看到我们把lisenter的实例传进去,那么我们就会在这里得到蓝牙的所有回调监听,从而在此处进行各种操作。如下图(注:下面回调方法大多数都可以根据你的需要选择性实现,不需要可以不用实现):

private BleLisenter mLisenter = new BleLisenter() {

@Override

public void onStart() {

...

//可以选择性实现该方法 不需要则不用实现(以下类同)

}

@Override

public void onStop() {

...

}

@Override

public void onConnectTimeOut() {

...

}

@Override

public void onLeScan(final BleDevice device, int rssi, byte[] scanRecord) {

...

}

@Override

public void onConnectionChanged(final BleDevice device) {

...

}

@Override

public void onServicesDiscovered(BluetoothGatt gatt) {

...

}

@Override

public void onReady(BluetoothDevice device) {

...

}

@Override

public void onChanged(BluetoothGattCharacteristic characteristic) {

Logger.e("data===" + Arrays.toString(characteristic.getValue()));

//可以选择性实现该方法 不需要则不用实现

//硬件mcu 返回数据

}

@Override

public void onWrite(BluetoothGatt gatt) {

...

}

@Override

public void onRead(BluetoothDevice device) {

...

}

@Override

public void onDescriptorWriter(BluetoothGatt gatt) {

...

}

};

3. 这里对几个重要的回调做解读,当我们收到onLeScan()回调时,则说明已经扫描到设备,只需要加入到你的设备列表中即可,当收到onConnectionChanged()方法时,说明蓝牙连接状态已经改变,则只需要判断BleDevice的状态即可,当收到onServicesDiscovered()回调时,说明已经搜索到蓝牙服务,这时可以根据自己的需求去设置通知Notify,如下图:

//设置通知数组

private void displayGattServices(final String address, List gattServices) {

if (gattServices == null)

return;

String uuid = null;

// Loops through available GATT Services.

for (BluetoothGattService gattService : gattServices) {

uuid = gattService.getUuid().toString();

Log.d(TAG, "displayGattServices: " + uuid);

if (uuid.equals(BleConfig.UUID_SERVICE_TEXT)) {

Log.d(TAG, "service_uuid: " + uuid);

List gattCharacteristics = gattService.getCharacteristics();

for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {

uuid = gattCharacteristic.getUuid().toString();

if (uuid.equals(BleConfig.UUID_CHARACTERISTIC_TEXT)) {

Log.e("mWriteCharacteristic", uuid);

mWriteCharacteristicMap.put(address,gattCharacteristic);

//通知特性

} else if (gattCharacteristic.getProperties() == BluetoothGattCharacteristic.PROPERTY_NOTIFY) {

mNotifyCharacteristics.add(gattCharacteristic);

Log.e("mNotifyCharacteristics", "PROPERTY_NOTIFY");

}

}

//真正设置通知

if (mNotifyCharacteristics != null && mNotifyCharacteristics.size() > 0) {

Log.e("setCharaNotification", "setCharaNotification");

setCharacteristicNotification(address, mNotifyCharacteristics.get(mNotifyIndex++), true);

}

}

}

}

根据服务的UUID来进行过滤,然后根据服务获取到特征的UUID,然后在进行过滤,然后再从特征中取出通知的UUID,这时设置通知为true就可以了。

当收到onChanged()回调时,则说明蓝牙设备的数据发生改变了,通知程序作出改变。还有很多回调,他们对应的情况不懂得可以参考上篇。

4. 发送数据到蓝牙设备

这里可以通过调用BleManager中的sendData()方法即可,只需要传入指定的蓝牙设备地址以及需要发送的二进制数据即可,返回值是发送成功或者失败的布尔值。

上面的所有情况是针对特定的蓝牙设备,针对发送通知和收发数据的形式,具体还要看硬件的协议,看是否需要设置通知,想详细进行了解的可以去下载本人的github上面的DEMO进行详细了解。

androidstudio依赖地址: compile ‘cn.com.superLei:blelibrary:1.0.1’

对BLE蓝牙感兴趣的朋友可以加入我们讨论群:

QQ:494309361(Android蓝牙开发小纵队)

作者:艾神一不小心

链接:http://www.jianshu.com/p/0c6aedd6640b

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

android蓝牙设置特征属性,Android BLE蓝牙详细解读(二)相关推荐

  1. Android中设置显示文本,Android文本显示控件-TextView属性详解

    android:autoLink //设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web /email/phone/map/all) andr ...

  2. 计算机设置位蓝牙播放xp,蓝牙设置在哪里,教你蓝牙设置在哪里

    蓝牙设置在哪里?说到蓝牙,大家首先想到就是手机上的,现在蓝牙用于将各种设备连接到您的计算机. 可能是你的键盘,鼠标,手机,耳机等等.一些用户反馈说在Windows10系统中无法找到蓝牙设置,win10 ...

  3. 基于pytorch搭建多特征CNN-LSTM时间序列预测代码详细解读(附完整代码)

    系列文章目录 lstm系列文章目录 1.基于pytorch搭建多特征LSTM时间序列预测代码详细解读(附完整代码) 2.基于pytorch搭建多特征CNN-LSTM时间序列预测代码详细解读(附完整代码 ...

  4. android蓝牙设置名称流程,Android 8 设置蓝牙名称 流程

    记录android 8设置蓝牙名称的流程.java packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDeviceR ...

  5. android 动态设置style属性值,android中的style属性值,以及一些预定义样式

    Android平台定义的主题样式:android:theme="@android:style/Theme.Dialog" // 将一个Activity显示为对话框模式 androi ...

  6. 安卓蓝牙开发(1)BLE蓝牙基础知识和一般开发流程

    一.BLE(Bluetooth Low Energy)低功耗蓝牙基本知识 Android 4.3(API级别18)引入了以低功耗蓝牙(BLE)为中心角色的内置平台支持,并提供应用程序可用于发现设备,查 ...

  7. android动态设置错误页面,Android中替换WebView加载网页失败时的页面

    我们用webView去请求一个网页链接的时候,如果请求网页失败或无网络的情况下,它会返回给我们这样一个页面,如下图所示: 上面这个页面就是系统自带的页面,你觉得是不是很丑?反正小编本人觉得非常丑,很难 ...

  8. android image设置adjustviewbounds_探索 Android 平台的 CameraX

    前言 如果你曾经用过 Android 的 Camera APIs,你可能已经感受到了,它们一直没有成为最容易实现的东西.最开始是 Camera API,然后又推荐使用 Camera2 API - 这个 ...

  9. android动态设置全屏,Android开发之全屏与非全屏的切换设置方法小结

    本文实例讲述了Android开发之全屏与非全屏的切换设置方法.分享给大家供大家参考,具体如下: 静态方法 1. 代码方式 在Activity类OnCreate方法中设置,代码如下 @Override ...

最新文章

  1. java 异或_Java之超级基础且实用的知识点
  2. 【机器学习】基于蚁群算法的多元非线性函数极值寻优
  3. JVM的监控工具之jinfo
  4. mysql中约束_【MySQL】:MySQL中四大约束
  5. springMVC中数据流解析与装载
  6. 刘作虎曝光一加7真机视频 最流畅的手机来了!
  7. 计算机所有相关系统设置在哪,Win7系统高级设置在哪里 win7系统怎么打开高级设置...
  8. MD5摘要算法的几种破解方法!
  9. matlab 齐次线性方程组,Matlab中利用null函数解齐次线性方程组
  10. nginx日志json化后问题(\x22)解决
  11. 你为什么总是很忙碌,却还在原地踏步!
  12. 峰会回顾 | 阿里云与StarRocks合作、开放、共赢
  13. 量子计算机是否存在相对论,从量子到宇宙——颠覆人类认知的科学之旅
  14. 如何炼就数据分析的思维?
  15. Beyond Compare软件使用详解
  16. 计算机学院校友论坛,西工大计算机学院北京校友论坛成立并举办第一次活动
  17. 计算机应用基础实验指导实验八,计算机应用基础第八章上机实验
  18. Oracle 中一些主要的V$视图种类
  19. 7620 Reset按键GPIO
  20. EXCEL 批量生成条形码、二维码方案

热门文章

  1. 07: redis分布式锁解决超卖问题
  2. 【报告分享】2021年中国新一代信息技术创投生态研究报告.pdf(附下载链接)...
  3. 【干货】数字化转型工作手册.pdf(附下载链接)
  4. 【报告分享】腾讯研究院-AI生成内容报告2020.pdf(附下载链接)
  5. 算法工程师面试备战笔记11_朴素贝叶斯分类某个类别概率为0怎么办
  6. php设计一个盒子类代码_PHP设计模式之简单工厂模式(Simple Factory)代码实例大全(七)...
  7. extjs4 冻结列_extjs4 事件处理
  8. 怎么把文件导入云服务器,怎么把文件放到云服务器里
  9. Leetcod每日一题:151.reverse-words-in-a-string(翻转字符串里的单词)
  10. BP(反向传播)神经网络