【原创】Android 5.0 BLE低功耗蓝牙从设备应用
如果各位觉得有用,转载+个出处。
现如今安卓的低功耗蓝牙应用十分普遍了,智能手环、手表遍地都是,基本都是利用BLE通信来交互数据。BLE基本在安卓、IOS两大终端设备上都有很好支持,所以有很好发展前景。
现市面上各种手环、手表的智能设备中基本都充当"从设备"这样的角色,基本由智能设备完成蓝牙广播,由手机进行连接,然后交互数据。
根据上述方式的应用在安卓4.3、IOS 7.0的版本上就得到了支持,应用也比较广泛,园里应该有很多相关实现,大家可以自己找找,如果不愿意找,抽空再写一篇。
今天主要是为了说在安卓5.0时升级了广播相关API,园里也有一些说明,但之所以还写这篇是因为数据交换的提及很少。
既然将手机要做广播了,那么实质手机就变成手环、手表的角色,一个从设备了。
如果你愿意,可以拿另一台手机做个主设备,这样他们就可以交流了。
好了,我们进入代码正题吧...
首先应用权限设置。在AndroidManifest.xml中还是要加入BLE控制权限,不然异常一定与你为伍。
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
接着我们上套路了,判断手机是否支持BLE以及是否支持BLE从设备。
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
showToast("该设备不支持蓝牙低功耗通讯");
this.finish();
return;
}
bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter == null) {
showToast("该设备不支持蓝牙低功耗通讯");
this.finish();
return;
}
bluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (bluetoothLeAdvertiser == null) {
showToast("该设备不支持蓝牙低功耗从设备通讯");
this.finish();
return;
}
我建议你先拿你调试设备试试,大多数同学走到这里都绝望了。你问我为啥?你试试就知道了。
如果你一脸what???的话,那恭喜你,你的调试设备是被选中的孩子,让我们继续乘风破浪吧。顺便在评论里告诉我下你用啥设备哦。
这时候我们开启广播的旋风吧。
//广播设置
AdvertiseSettings.Builder settingBuilder = new AdvertiseSettings.Builder();
settingBuilder.setConnectable(true);
settingBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
settingBuilder.setTimeout(0); //我填过别的,但是不能广播。后来我就坚定的0了
settingBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
AdvertiseSettings settings = settingBuilder.build(); //广播参数
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
bluetoothAdapter.setName("H8-BlePpl"); //你想叫啥名字,你愿意就好
dataBuilder.setIncludeDeviceName(true);
dataBuilder.setIncludeTxPowerLevel(true); dataBuilder.addServiceUuid(ParcelUuid.fromString(Const.UUID_SERVICE)); //可自定义UUID,看看官方有没有定义哦
AdvertiseData data = dataBuilder.build(); bluetoothLeAdvertiser.startAdvertising(settings, data, advertiseCallback);
然后你的小手机就开始广播了,说大家来连我啊连我啊。别总搜地址,貌似地址动态会变的,还是用名儿吧毕竟你起了啊。
我之前傻傻的查了手机蓝牙MAC地址,后来发现不是广播的那个...
广播回调我干了点新增服务的活儿,不干你拿啥通信来。
private AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("1.1 AdvertiseCallback-onStartSuccess");
}
});
bluetoothGattServer = bluetoothManager.openGattServer(getApplicationContext(),
bluetoothGattServerCallback);
BluetoothGattService service = new BluetoothGattService(UUID.fromString(Const.UUID_SERVICE),
BluetoothGattService.SERVICE_TYPE_PRIMARY);
UUID UUID_CHARREAD = UUID.fromString(Const.UUID_CHARACTERISTIC);
//特征值读写设置
BluetoothGattCharacteristic characteristicWrite = new BluetoothGattCharacteristic(UUID_CHARREAD,
BluetoothGattCharacteristic.PROPERTY_WRITE |
BluetoothGattCharacteristic.PROPERTY_READ |
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE);
UUID UUID_DESCRIPTOR = UUID.fromString(Const.UUID_CHARACTERISTIC_CONFIG);
BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UUID_DESCRIPTOR, BluetoothGattCharacteristic.PERMISSION_WRITE);
characteristicWrite.addDescriptor(descriptor);
service.addCharacteristic(characteristicWrite);
bluetoothGattServer.addService(service);
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("1.2. Service Builded ok");
}
});
}};
当你收到广播成功回调后,来吧,特征值啊~~反正要通信呐~~
被你发现了我偷懒读写特征值用了一个,其实你愿意用两个就用两个吧。
我用的NOTIFICATION方式做主设备的读取,你也可用INDICATION方式做。
服务建立完成后,也会收到通知。BLE嘛~~都是异步回调~~我是习惯了!
private BluetoothGattServerCallback bluetoothGattServerCallback = new BluetoothGattServerCallback() {
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
super.onServiceAdded(status, service);
final String info = service.getUuid().toString();
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("1.3 BluetoothGattServerCallback-onServiceAdded " + info);
}
});
}
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
final String info = device.getAddress() + "|" + status + "->" + newState;
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("1.4 onConnectionStateChange " + info);
}
});
}
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
final String deviceInfo = "Address:" + device.getAddress();
final String info = "Request:" + requestId + "|Offset:" + offset + "|characteristic:" + characteristic.getUuid() + "|Value:" +
Util.bytes2HexString(characteristic.getValue());
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("=============================================");
showInfo("设备信息 " + deviceInfo);
showInfo("数据信息 " + info);
showInfo("=========onCharacteristicReadRequest=========");
}
});
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, characteristic.getValue());
}
@Override
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onCharacteristicWriteRequest(device, requestId, characteristic,
preparedWrite, responseNeeded, offset, value);
final String deviceInfo = "Name:" + device.getAddress() + "|Address:" + device.getAddress();
final String info = "Request:" + requestId + "|Offset:" + offset + "|characteristic:" + characteristic.getUuid() + "|Value:" + Util.bytes2HexString(value);
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
//TODO:你做数据处理
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("=============================================");
showInfo("设备信息 " + deviceInfo);
showInfo("数据信息 " + info);
showInfo("=========onCharacteristicWriteRequest=========");
}
});
}
@Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
final String info = "Address:" + device.getAddress() + "|status:" + status;
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("onNotificationSent " + info);
}
});
}
@Override
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
final String deviceInfo = "Name:" + device.getAddress() + "|Address:" + device.getAddress();
final String info = "Request:" + requestId + "|Offset:" + offset + "|characteristic:" + descriptor.getUuid() + "|Value:" + Util.bytes2HexString(value);
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("=============================================");
showInfo("设备信息 " + deviceInfo);
showInfo("数据信息 " + info);
showInfo("=========onDescriptorWriteRequest=========");
}
});
// 告诉连接设备做好了
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
}
@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
super.onDescriptorReadRequest(device, requestId, offset, descriptor);
final String deviceInfo = "Name:" + device.getAddress() + "|Address:" + device.getAddress();
final String info = "Request:" + requestId + "|Offset:" + offset + "|characteristic:" + descriptor.getUuid();
runOnUiThread(new Runnable() {
@Override
public void run() {
showInfo("=============================================");
showInfo("设备信息 " + deviceInfo);
showInfo("数据信息 " + info);
showInfo("=========onDescriptorReadRequest=========");
}
});
// 告诉连接设备做好了
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null);
}
};
基本上从设备就做完了。
调试的时候你用主设备查服务列表可能查不到你的UUID_SERVICE,但是别慌,你getServcie(UUID_SERVICE)试试,说不定就柳暗花明了。
还有就是我拿的华为Honor 8做的调试机子,其他还有啥型号请各位分享下。姑娘我跪谢啦~~
【原创】Android 5.0 BLE低功耗蓝牙从设备应用的更多相关文章
- Android使用BLE(低功耗蓝牙,Bluetooth Low Energy)
背景 在学习BLE的过程中,积累了一些心得的DEMO,放到Github,形成本文.感兴趣的同学可以下载到源代码. github: https://github.com/vir56k/bluetooth ...
- BLE——低功耗蓝牙(Bluetooth Low Energy)
1.简介 以下蓝牙协议特指低功耗蓝牙协议. 蓝牙协议是由SIG制定并维护的通信协议,蓝牙协议栈是蓝牙协议的具体实现. 各厂商都根据蓝牙协议实现了自己的一套函数库——蓝牙协议栈,所以不同厂商的蓝牙协议栈 ...
- BLE低功耗蓝牙关键技术解析与应用
BLE基础知识 1.传统蓝牙的传输距离几十米到几百米不等,BLE 则规定为 100 米(实际上没有那么远,50米以内比较稳定,和设备发射功率有关) 2.为了实现极低的功耗,BLE 协议设计为:在不必要 ...
- 低功耗蓝牙BLE之连接事件、连接参数和更新方法
转自:http://blog.csdn.net/zzfenglin/article/details/51304084 连接事件 在一个连接当中,主设备会在每个连接事件里向从设备发送数据包.一个连接事件 ...
- TI低功耗蓝牙(BLE)介绍
TI低功耗蓝牙(BLE)介绍 本文档翻译和修改自参考资料:CC2540Bluetooth Low Energy Software Developer’s Guide (Rev. B),部分图片直接引用 ...
- TI低功耗蓝牙(BLE)介绍【转】
转自:http://blog.csdn.net/ooakk/article/details/7302425 TI低功耗蓝牙(BLE)介绍 本文档翻译和修改自参考资料:CC2540Bluetooth L ...
- 深入浅出讲解低功耗蓝牙(BLE)协议栈
详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...
- Android 6.0 新功能及主要 API 变更
运行时权限 这个版本中引入了新的权限模型,现在用户可以在运行时直接管理应用程序的权限.这个模型基于用户对权限控制的更多可见性,同时为应用程序的开发者提供更流畅的应用安装和自动升级.用户可以为已安装的每 ...
- Android 6.0 Changes
原文链接:http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html 伴随着新特性和功能,Andr ...
随机推荐
- RSA密码体制
公钥算法的基本数论知识 公钥密码学中大部分引用了数论的成果,所以必要在介绍RSA密码体制之前,详细介绍一下所使用的几个数论的知识点 欧几里得算法 欧几里得算法主要是解决最大公约数问题,记两个正整数\( ...
- 关于统一资源标志符URL的理解
URL由三部分构成 A:B:C A:URL使用的领域 B:在此领域的类型名称 C:标识资源的具体位置 C可以是一个绝对路径,也可以是端口号加上资源名称,总之是可以唯一标示资源的标识 例: 在网址中 S ...
- iOS开发之清除缓存
NSFileManager *mgr = [NSFileManager defaultManager]; NSString *cachePath = [NSSearchPathForDirectori ...
- deepin系统下如何设置wifi热点(亲测有效)
deepin系统下如何设置wifi热点(亲测有效) deepin wifi ap linux 热点 首先必须吐槽一下linux下设置wifi太累了....来来回回折腾了我好久的说.心累... 好了废话 ...
- Nginx+Tomcat动静分离脚本
#!/bin/bashsetenforce 0systemctl stop firewalldtar -zxvf nginx-1.8.0.tar.gz -C /usr/src/ cd /usr/src ...
- python selenium2示例 - 生成 HTMLTestRunner 测试报告
前言 在python selenium2自动化测试过程中,一个合适的报告是必须的,而HTMLTestRunner模块为我们提供了一个很好的报告生成功能. 什么是HTMLTestRunner HTMLT ...
- Java基础学习(三)—面向对象(上)
一.理解面向对象 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节:这种思想是将数据作为第一位,而方法或者说是 ...
- git教程(简单的带你学好git)
刚开始使用的时候没有找到好的资源学习,下面这个资源不错,大家可以参考学习. http://www.liaoxuefeng.com/wiki/0013739516305929606dd183612485 ...
- reids数据类型
今天第一次开通,写的不好,请谅解 redis并不是简单的key-value存储,实际上它是一个数据结构服务器,支持不同类型的值,也就是说,我们不仅仅把字符串当作键所指向的值, 如下这些数据 ...
- 【局域网聊天客户端篇】基于socket与Qt
前言 暑假把linux下的高级编程和网络编程学习了一遍,学习很重要,但是也得有个练手的地方,所以必须做做项目来认识下自己所学习的知识. 能够找到小伙伴一起做项目也是一件很快乐的事情的,很幸运的有两个小 ...