深入了解Android蓝牙Bluetooth ——《总结篇》
在我的上两篇博文中解说了有关android蓝牙的认识以及API的相关的介绍,蓝牙BLE的搜索,连接以及读取。
没有了解的童鞋们请參考:
眼下项目中的效果图:

接下来我们就对蓝牙BLE4.0进行一下总结。
蓝牙API
Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才干够使用,假设手机系统版本号API level < 18,也是用不了蓝牙4.0的哦
1. BluetoothGatt
继承BluetoothProfile。通过BluetoothGatt能够连接设备(connect),发现服务(discoverServices)。并把相应地属性返回到BluetoothGattCallback
2. BluetoothGattCharacteristic
相当于一个数据类型。它包含一个value和0~n个value的描写叙述(BluetoothGattDescriptor)
3. BluetoothGattDescriptor
描写叙述符,对Characteristic的描写叙述,包含范围、计量单位等
BluetoothGattService
服务。Characteristic的集合。
BluetoothProfile
一个通用的规范。依照这个规范来收发数据。
BluetoothManager
通过BluetoothManager来获取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);BluetoothAdapter
一个Android系统仅仅有一个BluetoothAdapter 。通过BluetoothManager 获取
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
1.8 BluetoothGattCallback已经连接上设备。对设备的某些操作后返回的结果。这里必须提醒下,已经连接上设备后的才干够返回,没有返回的认真看看有没有连接上设备。
private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
// 这里有9个要实现的方法,看情况要实现那些。用到那些就实现那些
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){};
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){};
};
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
BluetoothGatt gatt = device.connectGatt(this, false, mGattCallback);notification相应onCharacteristicChanged
gatt.setCharacteristicNotification(characteristic, true);readCharacteristic相应onCharacteristicRead
gatt.readCharacteristic(characteristic);- writeCharacteristic相应onCharacteristicWrite
gatt.wirteCharacteristic(mCurrentcharacteristic);
连接蓝牙或者断开蓝牙 相应 onConnectionStateChange
readDescriptor相应onDescriptorRead;
writeDescriptor相应onDescriptorWrite;
gatt.writeDescriptor(descriptor);- readRemoteRssi相应onReadRemoteRssi
gatt.readRemoteRssi()
executeReliableWrite相应onReliableWriteCompleted;
discoverServices相应onServicesDiscovered
gatt.discoverServices()- BluetoothDevice
扫描后发现可连接的设备,获取已经连接的设备
二、开启蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
Android ble 蓝牙4.0,也就是说API level >= 18。且支持蓝牙4.0的手机才干够使用,假设手机系统版本号API level < 18。也是用不了蓝牙4.0的
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "设备不支持蓝牙4.0", Toast.LENGTH_SHORT).show();
finish();
}
或者是
// 检查当前手机是否支持blue 蓝牙,假设不支持退出程序
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
showToast("不支持蓝牙4.0通讯");
return;
}
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// 检查设备上是否支持蓝牙
if (mBluetoothAdapter == null) {
showToast("没有发现蓝牙模块");
return;
}
三、对蓝牙的启动关闭操作
- isEnabled()
假设本地蓝牙处在可用状态(比如手机蓝牙开启)就返回true
- getState()
获得蓝牙状态 一般有BluetoothAdapter.STATE_BLE_ON ,STATE_BLE_TURNING_ON ,STATE_BLE_TURNING_OFF ,STATE_OFF - enable()
打开蓝牙设备,这样的方式不友好,建议使用以下方法
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,OPEN_REQUEST_CODE);
这样会有个弹窗提示用户是否开启蓝牙 - disable()
关闭全部的蓝牙连接后关闭本地蓝牙服务 - getAddress()
获得蓝牙mac地址 - getName()
获得蓝牙名称,也就收我们常常设置的蓝牙名称 - setName()
设置蓝牙名称 - startDiscovery()
開始发现设备(注意是设备,比如另外一个手机,而不是蓝牙耳机之类的) - getBondedDevices()
获取绑定(配对)的设备,測试发现仅仅有手动取消绑定才管用,否则即使关闭蓝牙,间隔一会再打开,这些仍然是绑定的.
同一时候一些绑定的设备(比如手环)用这种方法并没有返回相应的device - startLeScan(LeScanCallback)
開始对Bluetooth LE devices设备(蓝牙耳机,手环,电子称等)的扫描.回调函数会把扫描到的设备返回,
注意设备会反复被扫描到,最好去掉反复,去重时能够用mac地址,也能够用名称,可是扫描到的Device第一次没有把
名称带回,所以获取名称时最好做非空推断 - stopLeScan(LeScanCallback)
停止扫描 - >利用系统默认开启蓝牙对话框
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Android蓝牙服务的相关类简单介绍之BluetoothGatt
Generic Attribute Profile (GATT)—The GATT profile is a general specification for sending and receiving short
pieces of data known as “attributes” over a BLE link. All current Low Energy application profiles are based on
GATT.主从设备都维护了GATT 各自是client 和 server
获得方法,创建连接时返回
mConnGatt = bleDevie.connectGatt(this, false, mGattcallback);
回调
public abstract class BluetoothGattCallback {
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
int status) {
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
}
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
}
设置通知
public boolean setCharacteristicNotification(UUID serviceUuid, UUID characteristicUuid, boolean enable) {
BluetoothGattCharacteristic characteristic = mConnGatt.getService(serviceUuid).getCharacteristic(characteristicUuid);
mConnGatt.setCharacteristicNotification(characteristic, enable);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
descriptor.setValue(enable ?
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[]{0x00, 0x00});
return mConnGatt.writeDescriptor(descriptor); // descriptor write
}
以前遇到的坑
蓝牙接连时超时
解决方法:
在广播中相应的方法里进行又一次连接private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {//蓝牙已连接
tvBluetooth.setText("(已连接)");
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
showToast("蓝牙连接断开,请重试");
//这里又一次连接蓝牙
hideLoading();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {//发现蓝牙。设置命令
......
} else if(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //接收到数据
......
}
}
};蓝牙搜索进行匹配不来BLE设备
有些手性能比較低端。这里能够重新启动蓝牙,进行又一次连接
- ##### 连接成功后断开
- 保证BLE小设备没有被其它连接
- 先停止扫描—》又一次扫描—》又一次连接
读取过程中蓝牙断开
首先要保证连接蓝牙之前,上一次断开连接时的操作:
- 断开连接
- 断开(关闭)service
- 关闭蓝牙
然后运行:
先停止扫描—》又一次扫描—》又一次连接上传数据失败
把读取到的数据解析后进行保存在本地。下次上传的时候一起上传。
上传成功后记得进行本低数据的清空
注意:BLE蓝牙连接小设备时一般属于主从模块,当中主模块蓝牙能够同一时候连接多个设备。但读取时仅仅能读取一个。
- 主机:可主动搜索从机,能够发送数据。也能够接收数据
- 从机:能够发送数据,也能够接收数据。但仅仅能被搜索
有关项目下载地址: http://download.csdn.net/detail/lqw770737185/8116019
GitHub下载链接:https://github.com/androidstarjack/Bluetooth_4.3-master
接下来推荐两个关于Android蓝牙BLE的学习网址:
具体解析BluetoothAdapter的具体api
http://www.open-open.com/lib/view/open1390879771695.html
Android:蓝牙4.0-BLE-小结=1.0
http://www.itnose.net/detail/6095842.html
假设你认为此文对您有所帮助。欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

(欢迎关注学习和交流)
深入了解Android蓝牙Bluetooth ——《总结篇》的更多相关文章
- 深入了解Android蓝牙Bluetooth——《进阶篇》
在 [深入了解Android蓝牙Bluetooth--<基础篇>](http://blog.csdn.net/androidstarjack/article/details/6046846 ...
- android -- 蓝牙 bluetooth (三)搜索蓝牙
接上篇打开蓝牙继续,来一起看下蓝牙搜索的流程,触发蓝牙搜索的条件形式上有两种,一是在蓝牙设置界面开启蓝牙会直接开始搜索,另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索,也可能还有其它触发方式,但 ...
- ZT android -- 蓝牙 bluetooth (三)搜索蓝牙
android -- 蓝牙 bluetooth (三)搜索蓝牙 分类: Android的原生应用分析 2013-05-31 22:03 2192人阅读 评论(8) 收藏 举报 bluetooth蓝牙s ...
- ZT android -- 蓝牙 bluetooth (四)OPP文件传输
android -- 蓝牙 bluetooth (四)OPP文件传输 分类: Android的原生应用分析 2013-06-22 21:51 2599人阅读 评论(19) 收藏 举报 4.2源码AND ...
- ZT android -- 蓝牙 bluetooth (二) 打开蓝牙
android -- 蓝牙 bluetooth (二) 打开蓝牙 分类: Android的原生应用分析 2013-05-23 23:57 4773人阅读 评论(20) 收藏 举报 androidblu ...
- ZT android -- 蓝牙 bluetooth (五)接电话与听音乐
android -- 蓝牙 bluetooth (五)接电话与听音乐 分类: Android的原生应用分析 2013-07-13 20:53 2165人阅读 评论(9) 收藏 举报 蓝牙android ...
- android -- 蓝牙 bluetooth (四)OPP文件传输
在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录 ...
- ZT android -- 蓝牙 bluetooth (一) 入门
android -- 蓝牙 bluetooth (一) 入门 分类: Android的原生应用分析 2013-05-19 21:44 4543人阅读 评论(37) 收藏 举报 bluetooth4.2 ...
- 深入了解Android蓝牙Bluetooth——《基础篇》
什么是蓝牙? 也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用"蓝牙"技术,能够有效地简化掌上电脑.笔记本电 ...
随机推荐
- 【转】Ubuntu VI基本用法
转自:http://blog.sina.com.cn/s/blog_4f3b79d0010166ai.html 1.vi的基本概念 基本上vi可以分为三种状态,分别是命令模式(command mode ...
- Windows Store Apps 开发转载
懒得写了,就直接记录转载一下文章地址吧. 如何为应用定义全局默认字体:http://blogs.msdn.com/b/gautamdh/archive/2014/03/16/how-to-change ...
- android的一些控件
原来朋友给过的一个 显示时间的 样例,还能够改动时间,可是要机子有root权限才干改动. 在这个时间表盘的样例基础上 改动改动 图片.背景图什么的 就能够达到自己想要的效果了.. 下载地址 ...
- 【Android】7.7 以后改为在Win10下开发了
分类:C#.Android.VS2015: 创建日期:2016-02-12 修改日期:2016-02-13 一.鼠标点击时千万别一心二用 在Win10升级提醒不厌其烦的持续轰炸下,今天看手机时一不留神 ...
- 一些有用的Sql语句
1.插入数据后,返回插入的Id ')
- 【java web】Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
javaweb报错如下:22:49:22.155 [http-nio-8081-exec-9] ERROR org.apache.struts2.dispatcher.DefaultDispatche ...
- LeetCode: Word Search 解题报告
Word SearchGiven a 2D board and a word, find if the word exists in the grid. The word can be constru ...
- Permission denied (publickey). fatal: The remote end hung up unexpectedly 解决办法
这两天学习git的时候,在本地创建了一个库,同时自己在GitHub上面也创建了一个库,照着廖老师的教程一步一步走到了push的环节突然出现了这样的错误: [zhangxiyu@localhost le ...
- 教程-Delphi中比较两个对象是否一致及地址是否相同
资料说明: 1.http://blog.csdn.net/diligentcatrich/article/details/7077294 说明: 实例代码: procedure TForm1.btn1 ...
- 【Unity】UGUI控件大小适配父容器
需求:需要把UGUI控件的尺寸调整到指定大小,如匹配至设计的分辨率.或者说想制定覆盖全屏的背景图片. 做法:将这个UGUI控件的RectTransform组件里的Anchor Presets设为预设的 ...