满堂花醉三千客,一剑霜寒十四洲。这篇文章主要讲述深入了解Android蓝牙Bluetooth ——《总结篇》相关的知识,希望能为你提供帮助。
在我的上两篇博文中讲解了有关android蓝牙的认识以及API的相关的介绍,
蓝牙BLE的搜索,
连接以及读取。
没有了解的童鞋们请参考:
- 深入了解Android蓝牙Bluetooth——《基础篇》
- 深入了解Android蓝牙Bluetooth——《进阶篇》
文章图片
接下来我们就对蓝牙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
- 关闭蓝牙
先停止扫描—》重新扫描—》重新连接
- 上传数据失败
把读取到的数据解析后进行保存在本地, 下次上传的时候一起上传。上传成功后记得进行本低数据的清空
- 主机: 可主动搜索从机, 可以发送数据, 也可以接收数据
- 从机: 可以发送数据, 也可以接收数据, 但只能被搜索
详细解析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 使用Java8新特性之Lambda expression
- Android_Button_注册监听
- Android内存优化篇
- android HDMI (HDMI基础篇)
- Android 中使用https
- Android之广播
- JavaScript weakMap.has()方法用法示例
- JavaScript weakMap.set()方法用法示例
- JavaScript WeakSet