博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android蓝牙那点事——深入了解蓝牙BlE蓝牙 《总结篇》
阅读量:5822 次
发布时间:2019-06-18

本文共 6930 字,大约阅读时间需要 23 分钟。

在我的上两篇博文中讲解了有关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的描述,包括范围、计量单位等

  4. BluetoothGattService

    服务,Characteristic的集合。

  5. BluetoothProfile

    一个通用的规范,按照这个规范来收发数据。

  6. BluetoothManager

    通过BluetoothManager来获取BluetoothAdapter

    BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);复制代码
  1. 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);复制代码
  2. notification对应onCharacteristicChanged

    gatt.setCharacteristicNotification(characteristic, true);复制代码
  3. readCharacteristic对应onCharacteristicRead

    gatt.readCharacteristic(characteristic);复制代码
  4. writeCharacteristic对应onCharacteristicWrite
    gatt.wirteCharacteristic(mCurrentcharacteristic);复制代码
  5. 连接蓝牙或者断开蓝牙 对应 onConnectionStateChange

  6. readDescriptor对应onDescriptorRead;

  7. writeDescriptor对应onDescriptorWrite;

    gatt.writeDescriptor(descriptor);复制代码
  8. readRemoteRssi对应onReadRemoteRssi
    gatt.readRemoteRssi()复制代码
  9. executeReliableWrite对应onReliableWriteCompleted;

  10. discoverServices对应onServicesDiscovered

    gatt.discoverServices()复制代码
  11. BluetoothDevice
    扫描后发现可连接的设备,获取已经连接的设备

    二、开启蓝牙权限

复制代码

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设备

    有些手性能比较低端,这里可以重启蓝牙,进行重新连接

  • 连接成功后断开
    1. 保证BLE小设备没有被其他连接
    2. 先停止扫描---》重新扫描---》重新连接
  • 读取过程中蓝牙断开

    首先要保证连接蓝牙之前,上一次断开连接时的操作:

    1. 断开连接
    2. 断开(关闭)service
    3. 关闭蓝牙

    然后执行:

    先停止扫描---》重新扫描---》重新连接

  • 上传数据失败

    把读取到的数据解析后进行保存在本地,下次上传的时候一起上传。上传成功后记得进行本低数据的清空

    注意:BLE蓝牙连接小设备时一般属于主从模块,其中主模块蓝牙可以同时连接多个设备,但读取时只能读取一个。
    • 主机:可主动搜索从机,可以发送数据,也可以接收数据
    • 从机:可以发送数据,也可以接收数据,但只能被搜索
有关项目下载地址:
GitHub下载链接:

接下来推荐两个关于Android蓝牙BLE的学习网址:

详细解析BluetoothAdapter的详细api

Android:蓝牙4.0-BLE-小结=1.0

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809   

微信公众号:终端研发部

Markdown

(欢迎关注学习和交流)

转载地址:http://bmbdx.baihongyu.com/

你可能感兴趣的文章
使用《Deep Image Prior》来做图像复原
查看>>
Linux基础命令---rmdir
查看>>
Android图片添加水印图片并把图片保存到文件存储
查看>>
BigDecimal 舍入模式(Rounding mode)介绍
查看>>
开源 免费 java CMS - FreeCMS1.2-标签 infoSign
查看>>
开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据
查看>>
Squid 反向代理服务器配置
查看>>
Java I/O操作
查看>>
Tomcat性能调优
查看>>
Android自学--一篇文章基本掌握所有的常用View组件
查看>>
灰度图像和彩色图像
查看>>
TCP segmentation offload
查看>>
FreeMarker-Built-ins for strings
查看>>
argparse - 命令行选项与参数解析(转)
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>
Php实现版本比较接口
查看>>
删除设备和驱动器中软件图标
查看>>
第四章 TCP粘包/拆包问题的解决之道---4.1---
查看>>
html语言
查看>>
从源码看集合ArrayList
查看>>