鸿蒙开源组件——简单易用的BLE library

发布于 2021-11-29 17:10
浏览
0收藏

okble

项目介绍

  • 项目名称:okble
  • 所属系列:openharmony的第三方组件适配移植
  • 功能:简单易用的BLE library
  • 项目移植状态:主功能完成
  • 调用差异:无
  • 开发版本:sdk6,DevEco Studio 2.2 Beta1
  • 基线版本:okble组件 Releases 1.1.3

效果演示

鸿蒙开源组件——简单易用的BLE library-开源基础软件社区

安装教程

1.在项目根目录下的build.gradle文件中,

allprojects {
   repositories {
       maven {
           url 'https://s01.oss.sonatype.org/content/repositories/releases/'
       }
   }
}

2.在entry模块的build.gradle文件中,

dependencies {
   implementation('com.gitee.chinasoft_ohos:okble:1.0.0')
   ......  
}

在sdk6,DevEco Studio 2.2 Beta1下项目可直接运行 如无法运行,删除项目.gradle,.idea,build,gradle,build.gradle文件, 并依据自己的版本创建新项目,将新项目的对应文件复制到根目录下

使用说明
扫描外设

OKBLEScanManager scanManager = new OKBLEScanManager(this);
 scanManager.setScanCallBack(scanCallBack);
    DeviceScanCallBack scanCallBack = new DeviceScanCallBack() {
        @Override
        public void onBLEDeviceScan(BLEScanResult device, int rssi) {
           LogUtils.e(" scan:"+device.toString());
       }

       @Override
       public void onFailed(int code) {
          switch (code) {
                case DeviceScanCallBack.SCAN_FAILED_BLE_NOT_SUPPORT:
                    showToast("该设备不支持BLE");
                    break;
                case DeviceScanCallBack.SCAN_FAILED_BLUETOOTH_DISABLE:
                    showToast("请打开手机蓝牙");
                    break;
                case DeviceScanCallBack.SCAN_FAILED_LOCATION_PERMISSION_DISABLE:
                    showToast("请授予位置权限以扫描周围的蓝牙设备");
                    break;
                case DeviceScanCallBack.SCAN_FAILED_LOCATION_PERMISSION_DISABLE_FOREVER:
                    showToast("位置权限被您永久拒绝,请在设置里授予位置权限以扫描周围的蓝牙设备");
                    break;
            }
       }

       @Override
       public void onStartSuccess() {
       }
   };
  • 连接外设
    OKBLEDevice okbleDevice=new OKBLEDeviceImp(mContext,bleScanResult);
    //okbleDevice=new OKBLEDeviceImp(mContext);
    //okbleDevice.setBluetoothDevice(mBluetoothDevice);
    okbleDevice.addDeviceListener(this);
    okbleDevice.connect(true);//true表示连接断开后OKBLE的会自动重连​
  • APP主动断开连接
    okbleDevice.disConnect(false); //false表示断开后不需要OKBLE的自动重连; disConnect断开后,可以使用okbleDevice.connect()重新连接回来​
  • 数据通讯
    // Read
      application.okbleDevice.addReadOperation(characteristicModel.getUuid(), new OKBLEOperation.ReadOperationListener() {
                        @Override
                        public void onReadValue(final byte[] value) {
                            eventHandler.postTask(new Runnable() {
                                @Override
                                public void run() {
                                    addLog("onReadValue:" + OKBLEDataUtils.BytesToHexString(value) + " (" + new String(value) + ")");
                                }
                            });
                        }
    
                        @Override
                        public void onFail(int code, final String errMsg) {
                            eventHandler.postTask(new Runnable() {
                                @Override
                                public void run() {
                                    addLog("read onFail:" + errMsg);
                                }
                            });
                        }
    
                        @Override
                        public void onExecuteSuccess(OKBLEOperation.OperationType type) {
                        }
                    });
                    ​

 

 // Write
 application.okbleDevice.addWriteOperation(characteristicModel.getUuid(), value, new OKBLEOperation.WriteOperationListener() {
                                    @Override
                                    public void onWriteValue(final byte[] byteValue) {
                                        eventHandler.postTask(new Runnable() {
                                            @Override
                                            public void run() {
                                                addLog(" onWriteValue:" + byteValue);
                                            }
                                        });
                                    }
                                    @Override
                                    public void onFail(int code, final String errMsg) {
                                        eventHandler.postTask(new Runnable() {
                                            @Override
                                            public void run() {
                                                addLog("write onFail:" + errMsg);
                                            }
                                        });
                                    }
                                    @Override
                                    public void onExecuteSuccess(OKBLEOperation.OperationType type) {
                                        eventHandler.postTask(new Runnable() {
                                            @Override
                                            public void run() {
                                                addLog("write value execute success value length:" + OKBLEDataUtils.hexStringToBytes(value).length + " value:" + value);
                                            }
                                        });
                                    }
                                });
                                

 

 // Notify/Indicate
 application.okbleDevice.addNotifyOrIndicateOperation(characteristicModel.getUuid(), true, new OKBLEOperation.NotifyOrIndicateOperationListener() {
                    @Override
                    public void onNotifyOrIndicateComplete() {
                      eventHandler.postTask(new Runnable() {
                            @Override
                            public void run() {
                                addLog("onNotifyOrIndicateComplete");
                             
                            }
                        });
                    }

                    @Override
                    public void onFail(int code, final String errMsg) {
                      eventHandler.postTask(new Runnable() {
                            @Override
                            public void run() {
                                addLog("NotifyOrIndicate onFail:" + errMsg);
                            }
                        });
                    }

                    @Override
                    public void onExecuteSuccess(OKBLEOperation.OperationType type) {
                        operationType[0] = type;
                    }
                });
  • 发送大数据(应用场景1:OAD/空中升级) OAD原理其实就是把固件(如.bin文件)加载成byte[]数组,然后把byte[]数据分段发送给设备,以下代码演示了主要分段部分,OAD细节不展示(如每个包的整合),根据需求会有变化
        final int sendInterval=50;//每个包之间的发送间隔,有些手机会因为发送太快而导致蓝牙奔溃,OAD失败率很高,可以适当增大,如80-100;
            okbleDevice.setOperationInterval(sendInterval);
            byte[] oadValues=loadBytesFromFile(filePath);
            final int blockSize=20;//表示一个包发送20个字节
            final int blockCount= (int) Math.ceil(oadValues.length*1.0f/blockSize);//发送的总包数
            percent=0;
            for (int i=0;i<blockCount;i++){
                byte[] value=new byte[blockSize];
                System.arraycopy(oadValues,i*blockSize,value,0,blockSize);
                okbleDevice.addWriteOperation(OAD_WRITE_UUID, value, new OKBLEOperation.WriteOperationListener() {
                    @Override
                    public void onWriteValue(byte[] value) {
                        percent++;
                        float progress=percent*1.0f/blockCount;
                        int leftSeconds= (int) ((sendInterval*blockCount)/1000*(1-progress));              
                        HiLog.error(LABEL, "OAD 进度:"+progress+" 剩余时间:"+leftSeconds +"秒");
                    }
    
                    @Override
                    public void onFail(int code, String errMsg) {
                        HiLog.error(LABEL, " OAD failed");
                        okbleDevice.clearOperations();
                        break;
                    }
    
                    @Override
                      public void onExecuteSuccess(OKBLEOperation.OperationType type) {
                    }
                });
            }​
  • APP模拟成外设(可被扫描并连接)
        OKBLEAdvertiseManager okbleAdvertiseManager;
            OKBLEServerDevice serverDevice;
            okbleAdvertiseManager=new OKBLEAdvertiseManager(this);
            serverDevice=new OKBLEServerDeviceImp(this);
            OKBLEAdvertiseSettings settings= new OKBLEAdvertiseSettings.Builder().setConnectable(true).build();
            OKBLEAdvertiseData.Builder dataBuilder = new OKBLEAdvertiseData.Builder().setIncludeDeviceName(true);
            //开启广播
            okbleAdvertiseManager.startAdvertising(settings, okbleAdvertiseData, new OKBLEAdvertiseCallback() {  
             @Override
                public void onStartSuccess() {
                    LogUtils.e("---onStartSuccess ---");
                    new EventHandler(EventRunner.getMainEventRunner()).postTask(() -> 
                    ToastUtil.toast(mContext,"Advertising Success");
                    configServer();//配置service 和characteristic
                }
                @Override
                public void onStartFailure(int errorCode, String errMsg) {
                    LogUtils.e("---onStartFailure errMsg:" + errMsg);
                    int screenWidht = DisplayManager.getInstance().getDefaultDisplay(mContext).get().getAttributes().width;
                    DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(mContext)
                            .parse(ResourceTable.Layout_layout_toast, null, false);
                    Text msg_toast = (Text) toastLayout.findComponentById(ResourceTable.Id_msg_toast);
    
                    msg_toast.setText("Advertising Failed:"+errMsg);
                    new ToastDialog(mContext) .setComponent(toastLayout)
                            .setSize((int) (screenWidht*0.7), DirectionalLayout.LayoutConfig.MATCH_CONTENT).show();
                }      
            });
            
            private void configServer() {
                OKBLEServiceModel serviceModel = new OKBLEServiceModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff0"));
                OKBLECharacteristicModel characteristicModel = new OKBLECharacteristicModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff1"));
                characteristicModel.setCanWrite(true);
                characteristicModel.setCanNotify(true);
                characteristicModel.setCanRead(true);
                OKBLECharacteristicModel characteristicModel_2 = new OKBLECharacteristicModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff2"));
                characteristicModel_2.setCanWriteNoResponse(true);
                List<OKBLECharacteristicModel> characteristicModels = new ArrayList<>();
                characteristicModels.add(characteristicModel);
                characteristicModels.add(characteristicModel_2);
                serverDevice.addCharacteristic(characteristicModels, serviceModel, new OKBLEServerOperation.BLEServerOperationListener() {
                    @Override
                    public void onAddCharacteristicFailed(int errorCode, String errorMsg) {
                        LogUtils.e("onAddCharacteristicFailed:" + errorMsg);
                    }
                    @Override
                    public void onAddCharacteristicSuccess() {
                        LogUtils.e("onAddCharacteristicSuccess");
                    }
                });
            }​
  • 扫描iBeacon设备
      OKBLEBeaconScanManager scanManager;
        scanManager=new OKBLEBeaconScanManager(this);
        scanManager.setBeaconScanCallback(scanCallBack);
        OKBLEBeaconManager.OKBLEBeaconScanCallback scanCallBack = new OKBLEBeaconManager.OKBLEBeaconScanCallback() {
            @Override
            public void onScanBeacon(OKBLEBeacon beacon) {
                refreshBtn.setEnabled(true);
                int value[] = scanedResults.put(beacon.getIdentifier(), beacon);
                new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
                    @Override
                    public void run() {
                        if (value[1] == 1) {
                            //这是新增数据
                            provider.notifyDataChanged();
                        } else {
                            //这是重复数据,刷新rssi
                            int index = value[0];
                            updatePosition(index);
                        }
                    }
                });
            }
        };​
  • APP模拟成iBeacon
      OKBLEBeBeaconManager beBeaconManager;
        beBeaconManager = new OKBLEBeBeaconManager(this);
        beBeaconManager.setOKBLEBeBeaconListener(startBeaconListener);
        
        String uuid ="12345678-1234-1234-1234-1234567890ab";
        int major=1;
        int minor=2;
        beBeaconManager.startIBeacon(uuid, major, minor);
        
         OKBLEBeBeaconManager.OKBLEStartBeaconListener startBeaconListener = new OKBLEBeBeaconManager.OKBLEStartBeaconListener() {
            @Override
            public void onStartSuccess() {
                eventHandler.postTask(new Runnable() {
                    @Override
                    public void run() {
                     ToastUtil.toast(mContext,"start success");
                    }
                });
            }
            @Override
            public void onStartFailure(String errMsg) {
                eventHandler.postTask(new Runnable() {
                    @Override
                    public void run() {
                     ToastUtil.toast(mContext,"start failed:" + errMsg);
                    }
                });
            }
        };​
  • 检测进入、退出iBeacon区域
        OKBLEBeaconManager beaconManager=new OKBLEBeaconManager(this);
        beaconManager.setRegionListener(this);
        String uuid ="12345678-1234-1234-1234-1234567890ab";
        int major=1;
        int minor=2;
        OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid,major,minor);
        //OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid,major);
        //OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid);
        beaconManager.startMonitoringForRegion(okbleBeaconRegion);
        
        @Override
        public void onEnterBeaconRegion(OKBLEBeaconRegion beaconRegion) {
        
        }
        
        @Override
        public void onExitBeaconRegion(OKBLEBeaconRegion beaconRegion) {
        
        }​

测试信息

CodeCheck代码测试无异常

CloudTest代码测试无异常

病毒安全检测通过

当前版本demo功能与原组件基本无差异

版本迭代

  • 1.0.0

版权和许可信息

Copyright 2018 a1anwang

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

okble-master.zip 1.06M 4次下载
已于2021-11-29 17:10:13修改
1
收藏
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐