更新记录

1.1.2(2024-03-14)

修改文档

1.1.1(2024-03-14)

  1. 兼容安卓12,请求最新的权限CODE
  2. 权限校验失败,通过callback进行返回

1.1.0(2024-03-13)

  1. 新增开发文档
  2. 在所有方法上新增权限校验,权限校验通过才会执行后续方法
查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.6.8,Android:支持,iOS:支持 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

hj-ttlock

开始使用

下载导入项目后,直接在文件内导入即可

 import * as LockApi from "@/uni_modules/hj-ttlock";

注入开始和结束方法:
由于官方插件需要在启动时做些处理,所以统一提出两个方法分别在 onLoadonUnload 中运行

onLoad() {
    // 加载时调用----IOS会在这一步请求权限,安卓会在执行具体方法前校验
    LockApi.initBLE();
}

onUnload() {
    // 卸载时调用
    LockApi.stopBLE();
}

方法介绍

注: 方法callback固定为一个对象,内含success: ()=>{}fail: (e)=>{}
success的方法内根据不同的方法会返回不同的参数,具体参考下面的方法介绍
fail的方法内固定返回参数e为一个error对象,对象内的属性为

  • errorCode 错误码
  • errorMsg 错误内容
  • desc 详细描述

1.1改动:会在每个方法执行前校验蓝牙权限是否充足,权限不足则不会继续执行并提示或请求缺失的权限

1. 开始扫描

LockApi.startScanLock({success: (deviceFromScan, deviceFromScanList)=>{}, fail: (e)=>{}});

扫描方法会一直刷新,但是列表可能没有变化,每次可能返回同一个设备
deviceFromScan:当次扫描到的设备
deviceFromScanList:当前最新的设备列表
具体设备对象内的字段可实际测试时打印查看
由于通通锁官方SDK对于安卓和IOS返回的字段不同,所以扫描设备时,需要兼容一下字段保证两端代码通用
具体兼容代码如下:

// #ifdef APP-IOS
let list = [];
deviceFromScanList.forEach(item => {
let device = JSON.parse(item);
device.name = device.lockName;
device.isSettingMode = !device.isInited;
device.mAddress = device.lockMac;
list.push(device);
});
deviceFromScanList = list;
// #endif

兼容后会统一输出三个字段:

  • name:设备名称
  • isSettingMode:是否为初始化状态
  • mAddress:蓝牙MAC地址

2. 停止扫描

LockApi.stopScanLock();

如无需继续扫描请主动调用此方法,避免资源占用

3. 初始化锁

LockApi.initLock(i, mac, {success: (lockData)=>{}, fail: (e)=>{}});

锁的初始化,为了避免扫描到的数据列表频繁变动,这里使用列表中的索引作为定位数据的依据,同时传入Mac地址用来校验当前操作的锁 的确是用户选择的那条数据。 i: 扫描方法回调会返回deviceFromScanListi为该数组的索引,即用户选择数组中的某个锁则传入锁的索引
mac: 需要初始化的锁的Mac地址
lockData: 初始化成功后返回的锁数据,请将该数据回传服务端进行房间绑定。如若上传失败,需要考虑重试或者调用重置锁的方法, 避免锁不可用。

4. 锁数据绑定

因为锁的操作是单线程的,一次只能响应一个指令,同时后续所有操作都需要用到lockDatamac两个参数, 所以这里抽出了统一设置的方法,设置过之后,后续所有锁操作都无需关心这俩参数,只传输业务数据即可。

// 设置锁数据
LockApi.setLockData(lockData);
// 设置锁的Mac地址
LockApi.setLockMac(mAddress);

这里我的开发思路是这样的:

  • 在进入锁页面时先校验是否绑定锁
  • 未绑定展示绑定页面,通过扫描锁,初始化锁进行添加,添加后通过上述方法绑定数据。
  • 已绑定则通过上述方法直接把服务端获取到的锁数据绑定起来即可。

5. 蓝牙开门

LockApi.openDoor(1,{success: ()=>{}, fail: (e)=>{}});

第一个参数固定传1,代表开门

6. 蓝牙关门

LockApi.closeDoor(2, {success: ()=>{}, fail: (e)=>{}});

第一个参数固定传2,代表关门

7. 重置锁

LockApi.reset({success: ()=>{}, fail: (e)=>{}});

将锁重置为初始化状态,等待重新绑定

8. 获取锁内日期

LockApi.getLockDate({success: (timestamp)=>{}, fail: (e)=>{}});

返回锁内的时间,格式为时间戳 new Date()转换下即可

9. 同步锁时间

LockApi.setLockDate({success: ()=>{}, fail: (e)=>{}});

该方法不接收指定时间进行更新,内部方法取的当前时间为参数更新

10. 获取锁内操作记录

LockApi.getOperationLogs(0, {success: (log)=>{}, fail: (e)=>{}});

返回锁内的开门记录列表
第一个参数代表返回的记录类型 0:最新的记录(从上次查询开始)1:所有记录
返回值log是JSONArray字符串,自行格式化后使用即可
内部字段很好理解,实际调用一次,打印下结果就能看到了
对于密码类型keyboardPwdType的描述:
1:临时密码
2:永久密码
3:期限密码
4:清空码
其他:循环码,有周一循环,周二循环之类的,不常用

11. 获取锁电量

LockApi.getSurplusBattery({success: (power)=>{}, fail: (e)=>{}});

获取锁当前剩余电量,返回值power为数字0-100

12. 创建密码

LockApi.createPwd(pwd, start, end, {success: ()=>{}, fail: (e)=>{}});

蓝牙创建密码
pwd: 密码数字 4-9位
start: 开始时间-时间戳
end: 结束时间-时间戳

13. 重置所有密码

LockApi.resetPwd({success: (lockData)=>{}, fail: (e)=>{}});

重置锁内的所有密码
此时会返回新的锁数据lockData,需要将锁数据同步到服务端,否则后续所有功能不可用!!!

14. 修改密码

LockApi.modifyPwd(oldPwd, newPwd, start, end, {success: ()=>{}, fail: (e)=>{}});

修改指定密码 oldPwd: 旧密码
newPwd: 新密码数字 4-9位
start: 开始时间-时间戳
end: 结束时间-时间戳

15. 删除密码

LockApi.deletePwd(oldPwd, {success: ()=>{}, fail: (e)=>{}});

删除已有密码oldPwd

16. 获取锁内有效密码

LockApi.getAllValidPwd({success: (pwds)=>{}, fail: (e)=>{}});

返回锁内所有有效的密码
返回值pwds为JSONArray字符串,自行格式化后使用,字段基本同操作记录

17. 添加IC卡

LockApi.addICCard(start, end, {success: (res)=>{}, fail: (e)=>{}});

添加卡片钥匙,这里回调会触发多次,第一次res返回-1,代表等待刷卡,否则是刷卡成功,返回卡号
start: 开始时间-时间戳
end: 结束时间-时间戳

18. 修改IC卡有效期

LockApi.modifyICCardValidityPeriod(start, end, cardNum, {success: ()=>{}, fail: (e)=>{}});

根据卡号修改IC卡有效期
卡号在添加IC卡成功后会返回,或者通过查询IC卡列表接口获取。 start: 开始时间-时间戳
end: 结束时间-时间戳
cardNum: 卡号

19. 获取锁内所有有效的IC卡

LockApi.getAllValidICCards({success: (cards)=>{}, fail: (e)=>{}});

返回所有有效的IC卡列表
cards返回的是JSONArray字符串,字段基本和操作记录相似,其中cardNum为卡号

20. 删除IC卡

LockApi.deleteICCard(cardNum, {success: ()=>{}, fail: (e)=>{}});

根据卡号cardNum删除这张IC卡

21. 清空所有IC卡

LockApi.clearAllICCard({success: ()=>{}, fail: (e)=>{}});

清除锁内所有的IC卡

补充说明

安卓使用gradle引入的SDK 版本是3.3.7 IOS通过CocoaPods引入的SDK 版本是3.3.1

此插件是基于我们项目需要封装出来的一套功能。
由于UTS当下使用者不多,网上相关的文档也不多,大多都是官方文档的翻版,所以经过N次尝试加请教原生
开发者后,完成的IOS版的封装。(UTS是基于TS的语法,先编译成swift代码再线上编译,所以很多问题
IOS原生开发者也无能为力,所以这里耗费了大量时间,官方群里也基本得不到解决方案。)
通通锁插件是OC开发的,swift调用OC就需要复杂转换,再加上这里是UTS语法再转swift..... 希望该插件可以给你带来帮助。

插件配了微信小程序的包,目的是为了使项目在小程序内运行也不报错,但对应api都不可用

参考示例

示例方法是在vue2中编写并测试的,所有方法均通过测试
loading 是页面遮罩的开关,content是测试时用来输出方法返回值时用的

startScan: function() {
    const that = this;
    this.loading = true;

    LockApi.startScanLock({
        success: function(deviceFromScan, deviceFromScanList) {
            // #ifdef APP-IOS
            let list = [];
            deviceFromScanList.forEach(item => {
                let device = JSON.parse(item);
                device.name = device.lockName;
                device.isSettingMode = !device.isInited;
                device.mAddress = device.lockMac;

                list.push(device);
            });
            deviceFromScanList = list;
            // #endif
            that.lockList = deviceFromScanList;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
        }
    });

},
stopScan: function() {
    LockApi.stopScanLock();
    this.loading = false;
},
initLock: function(i, row) {
    const that = this;
    LockApi.setLockMac(row.mAddress);
    this.loading = false;
    LockApi.initLock(i, row.mAddress, {
        success: function(lockData) {
            console.log('lockDataaaaaaaaaaaa:', lockData);
            that.initSuccess = true;
            LockApi.setLockData(lockData);
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
        }
    });
},
openDoor: function() {
    this.loading = true;
    const that = this;
    LockApi.openDoor(1, {
        success: function(res) {
            console.log('success:');
            that.content = res.controlLockResult;
            that.loading = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });
},
resetLock: function() {
    this.loading = true;
    const that = this;
    LockApi.reset({
        success: function() {
            console.log('success:');
            that.loading = false;
            that.$u.toast("重置成功");
            that.initSuccess = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });
},
getLockDate: function() {
    this.loading = true;
    const that = this;
    LockApi.getLockDate({
        success: function(res) {
            console.log('success:', res);
            that.loading = false;
            let a = new Date(res);
            that.content = a.getFullYear() + "-" + (a.getMonth() + 1) + "-" + a.getDate() + " " + a.getHours() + ":" + a.getMinutes() + ":" + a.getSeconds();
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });

},
setLockDate: function() {
    this.loading = true;
    const that = this;
    LockApi.setLockDate({
        success: function() {
            console.log('success:');
            that.loading = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });

},
getOperationLog: function() {
    this.loading = true;
    const that = this;
    LockApi.getOperationLogs(0, {
        success: function(log) {
            console.log('success:', log);
            that.content = log;
            that.loading = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });

},
getBatteryLevel: function() {
    this.loading = true;
    const that = this;
    LockApi.getSurplusBattery({
        success: function(res) {
            console.log('success:', res);
            that.content = res;
            that.loading = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });

},
createCustomPasscode: function() {
    this.loading = true;
    const that = this;
    let a = new Date();
    let b = a.getTime();
    a.setDate(a.getDate() + 1);
    let c = a.getTime();
    LockApi.createPwd(this.value1, b, c, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
resetPasscode: function() {
    this.loading = true;
    const that = this;
    LockApi.resetPwd({
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        LockApi.setLockData(res);
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
modifyPasscode: function() {
    this.loading = true;
    const that = this;
    let a = new Date();
    let b = a.getTime();
    a.setDate(a.getDate() + 1);
    let c = a.getTime();
    LockApi.modifyPwd(this.value2, this.value1, b, c, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
deletePasscode: function() {
    this.loading = true;
    const that = this;
    LockApi.deletePwd(this.value2, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
getAllValidPasscodes: function() {
    this.loading = true;
    const that = this;
    LockApi.getAllValidPwd({
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
addICCard: function() {
    this.loading = true;
    const that = this;
    let a = new Date();
    let b = a.getTime();
    a.setDate(a.getDate() + 1);
    let c = a.getTime();
    LockApi.addICCard(b, c, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
        if (res == -1) {
            that.show = true;
            return;
        }
        // 刷卡成功
        that.show = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
        if (error.errorCode == "0x404") {
            that.$u.toast("该锁不支持IC卡相关功能");
        }
      }
    });
},
modifyICCardValidityPeriod: function() {
    this.loading = true;
    const that = this;
    let a = new Date();
    let b = a.getTime();
    a.setDate(a.getDate() + 1);
    let c = a.getTime();
    LockApi.modifyICCardValidityPeriod(b, c, this.value1, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
getAllValidICCards: function() {
    this.loading = true;
    const that = this;
    LockApi.getAllValidICCards({
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
deleteICCard: function() {
    this.loading = true;
    const that = this;
    LockApi.deleteICCard(this.value1, {
      success: function(res) {
        console.log('success:', res);
        that.content = res;
        that.loading = false;
      },
      fail: function(error) {
        console.log('CCCCCCCCCCCC', JSON.stringify(error));
        that.content = error;
        that.loading = false;
      }
    });
},
clearAllICCard: function() {
    this.loading = true;
    const that = this;
    LockApi.clearAllICCard({
        success: function(res) {
            console.log('success:', res);
            that.content = res;
            that.loading = false;
        },
        fail: function(error) {
            console.log('CCCCCCCCCCCC', JSON.stringify(error));
            that.content = error;
            that.loading = false;
        }
    });
}

参考文档

UTS 语法 UTS API插件 UTS 组件插件 Hello UTS

隐私、权限声明

1. 本插件需要申请的系统权限列表:

安卓:BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_COARSE_LOCATION、ACCESS_FINE_LOCATION、BLUETOOTH_SCAN、BLUETOOTH_CONNECT IOS:蓝牙

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问