2 Star 3 Fork 2

CHINASOFT3_OHOS / okble

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

okble

项目介绍

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

效果演示

okbleGIF图

安装教程

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()重新连接回来
  • APP清除连接
okbleDevice.remove(); //remove会清除连接的外设信息; 重新连接前需要重新调用setBleScanResult/setBluetoothDevice 来设置外设信息
  • 数据通讯
  // 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.

空文件

简介

BLE实现库 展开 收起
Java
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/chinasoft3_ohos/okble.git
git@gitee.com:chinasoft3_ohos/okble.git
chinasoft3_ohos
okble
okble
master

搜索帮助