zoukankan      html  css  js  c++  java
  • 关于Ble通信库BluetoothKit的使用 以及可能出现的问题分析





      首先,这个库是用于BLE(低功耗蓝牙)通信的,地址:https://github.com/dingjikerbo/BluetoothKit 

    
    

        当然,也可以选择根据andorid提供的底层接口自己完成这部分的通信,这个库优点在于确实很方便使用,基本都是回调就能完成。作者好像也是前就职于阿里?

     介绍下用法:

       先在gradle加入:

    compile 'com.inuker.bluetooth:library:1.4.0'

      在Menifest中配置:

      (ps:在6.0以上需要使用动态权限)

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />
    
    <application
        android:label="@string/app_name">
        <service
            android:name="com.inuker.bluetooth.library.BluetoothService" />
    </application>

     在Application里设置  

      

            BluetoothContext.set(this);

     核心类BluetoothClient,创建一个这样的单例对象,可以借用其例子中的ClientManager类

    BluetoothClient mClient = new BluetoothClient(context); //自己写
    BluetoothClient mClient = ClientManager.getClient(); //借用作者的ClientManager
    

      一般都需要做个扫描界面来选择设备吧,这个库是支持普通蓝牙和低功耗蓝牙混扫的

    SearchRequest request = new SearchRequest.Builder()
            .searchBluetoothLeDevice(3000, 3)   // 先扫BLE设备3次,每次3s
            .searchBluetoothClassicDevice(5000) // 再扫经典蓝牙5s
            .searchBluetoothLeDevice(2000)      // 再扫BLE设备2s
            .build();
    
    mClient.search(request, new SearchResponse() {
        @Override
        public void onSearchStarted() {
    
        }
    
        @Override
        public void onDeviceFounded(SearchResult device) {
         //发现设备 Beacon beacon = new Beacon(device.scanRecord);
         //beacon用于解析广播 BluetoothLog.v(String.format("beacon for %s %s", device.getAddress(), beacon.toString()));
         //device对象就包括了设备的mac地址和蓝牙名称 ,将device放在list里面 按mac地址做唯一区别 } @Override public void onSearchStopped() {       //扫描停止 } @Override public void onSearchCanceled() {       //扫描取消 } });

       手动停止扫描:

    mClient.stopSearch();
    

     

     通过上面的代码我们可以完成设备的扫描,获取到扫描结果,也可以得到目标设备的mac地址;

     广播的作用是可以不连接设备,就能够获取到设备的一些信息,比如电量或者其他的一些厂家信号;

        言归正传,我们得到了mac地址就可以连接设备了,通过一些代码既可以完成连接设备:

    //连接参数
    BleConnectOptions options = new BleConnectOptions.Builder()
            .setConnectRetry(2)   // 连接如果失败重试2次
            .setConnectTimeout(3000)   // 连接超时3s
            .setServiceDiscoverRetry(2)  // 发现服务如果失败重试3次
            .setServiceDiscoverTimeout(2000)  // 发现服务超时2s
            .build();
    
    mClient.connect(MAC, options, new BleConnectResponse() {
        @Override
        public void onResponse(int code, BleGattProfile data) {
    
        }
    });
    

     个人建议不能确定双方通信都及其正常的情况下,是需要设置连接参数的,可以保证连接的成功率。如果要监听蓝牙连接状态可以注册回调,只有两个状态:连接和断开,建议把监听设置放在连接前面

    mClient.registerConnectStatusListener(MAC, mBleConnectStatusListener);
    
    private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {
    
        @Override
        public void onConnectStatusChanged(String mac, int status) {
            if (status == STATUS_CONNECTED) {
          //连接
            } else if (status == STATUS_DISCONNECTED) {
          //断开
            }
        }
    };
    
    mClient.unregisterConnectStatusListener(MAC, mBleConnectStatusListener);
    

      也可以通过mClient获取连接状态:

    int status = mClient.getConnectStatus(MAC)
    

      连接成功后一般都要打开notify使能,以便获得硬件回复的数据:

    //打开notify
    mClient.notify(MAC, serviceUUID, characterUUID, new BleNotifyResponse() { //是notify的UUID @Override public void onNotify(UUID service, UUID character, byte[] value) { //硬件回复的数据在这里,统一处理
          handleResult(value); } @Override public void onResponse(int code) { if (code == REQUEST_SUCCESS) {       //我一般都在打开notify成功后才开始发送数据 } } });

    //关闭notify
    mClient.unnotify(MAC, serviceUUID, characterUUID, new BleUnnotifyResponse() {
        @Override
        public void onResponse(int code) {
            if (code == REQUEST_SUCCESS) {
    
            }
        }
    });

      写数据,只有通过mClient.write写数据才有可能收到notify回来的数据,如果通过writeNoRsp写是不可能收到的,作者注明writeNoRsp建议用于固件升级:

    mClient.write(MAC, serviceUUID, characterUUID, bytes, new BleWriteResponse() {
        @Override
        public void onResponse(int code) {
            if (code == REQUEST_SUCCESS) {
    
            }
        }
    });
    

      这样就可以实现write-->notify的读写操作了。

      说一些我遇到的问题:

      1.android6.0以上动态权限不仅需要蓝牙相关权限,还需要GPS权限,必须保证GPS也打开,才能正常搜索;

      2.连接速度问题,经测试,这个库在nexus5上连接较慢,底层从发现设备到发现服务有时候甚至需要2,3s左右;

      3.部分设备有时候出现 notify 返回 -1,尝试过在连接的时候把扫描停止了,有好转,不过并未彻底解决;

      4.在部分华为机型上蓝牙连接不稳定

      5.一定要在Application里设置  BluetoothContext.set(this);

     

  • 相关阅读:
    mysql(二)数据类型
    mysql(一)
    MySQL8 安装官方示例 employees 数据库
    Elasticsearch入门
    redis入门
    git 基本使用
    vue-cli4环境变量配置和代理跨域配置
    nginx配置
    彻底搞清浏览器和服务器跨域
    File文件过滤器
  • 原文地址:https://www.cnblogs.com/yjpjy/p/7554410.html
Copyright © 2011-2022 走看看