Android BLE蓝牙详细解读(二)

上篇文章主要介绍了关于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<BluetoothGattService> 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<BluetoothGattCharacteristic> 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进行详细了解。

附DEMO下载地址

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

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

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



作者:艾神一不小心
链接:http://www.jianshu.com/p/0c6aedd6640b
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://my.oschina.net/JiangTun/blog/1537711

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值