微信小程序蓝牙模块开发

微信小程序蓝牙模块开发,第1张

//index.js

//获取应用实例

const app = getApp()

const util = require('../../utils/util.js')

const bletool = require('../../utils/bletool.js')

Page({

data: {

// lists: [{ 'order_no': '1111', 'car_no': '321', 'car_type'绝枣: '尚好捷', 'order_date': '2018-01-02 08:00', 'order_money': '16.00', 'order_time': '4' }],

car_no: '',

order_no: '',

lists: [],

bleList: [], //蓝牙设备数组

serviceId: '',//592B3370-3900-9A71-4535-35D4212D2837

serviceMac: '',//散陵C9:9B:4C:E7:DE:10

service_psd: '',//855525B837253705595800000329

service_uuid: '',

deviceId:'',

characteristics:[] //特征值

},

onLoad: function (options) {

this.initBle()

},

onReady: function () {

// 页面渲染完成

},

onShow: function () {

if (app.globalData.car_no.length>0){

this.getDeviceInfo()

}

},

onHide: function () {

// 页面隐藏

},

onUnload: function () {

// 页面关闭

app.globalData.car_no=''

},

//蓝牙相关

//初始化蓝牙

initBle: function () {

var that = this

wx.onBluetoothAdapterStateChange(function (res) {

console.log('adapterState changed, now is', res)

app.globalData.ble_state = res.available

if (res.available) {

that.initBle()

} else {

util.showToast('手机蓝牙已关闭')

app.globalData.ble_isonnectting = false

}

})

//打开蓝牙适配器

wx.openBluetoothAdapter({

success: function (res) {

console.log('打开蓝牙适配器成功冲宏戚')

that.getBluetoothAdapterState()

app.globalData.ble_state = true

that.onBluetoothDeviceFound()

},

fail: function (res) {

// fail

console.log(res)

util.showToast('请打开手机蓝牙')

},

complete: function (res) {

// complete

}

})

},

onBluetoothDeviceFound:function(){

var that = this

//监听扫描

wx.onBluetoothDeviceFound(function (res) {

// res电脑模拟器返回的为数组;手机返回的为蓝牙设备对象

console.log('监听搜索新设备:', res)

that.updateBleList([res])

})

},

getBluetoothAdapterState: function () {

var that = this

wx.getBluetoothAdapterState({

success: function (res) {

var available = res.available

var discovering = res.discovering

if (!available) {

util.showToast('蓝牙不可用')

} else {

if (!discovering) {

// that.startBluetoothDevicesDiscovery()

}

}

}

})

},

startBluetoothDevicesDiscovery: function () {

var that = this

var services = []

services.push(this.data.serviceId)

wx.showLoading({

title: '设备搜索中'

})

setTimeout(function () {

wx.hideLoading()

if (app.globalData.deviceId.length==0){

util.showModal('设备搜索失败,请重试')

}

}, 10000)

if(bletool.isIOS()){

wx.startBluetoothDevicesDiscovery({

services: services,

allowDuplicatesKey: true,

success: function (res) {

console.log('ios搜索成功')

console.log(res)

},

fail: function (err) {

console.log(err)

}

})

}else{

wx.startBluetoothDevicesDiscovery({

// services: services,

allowDuplicatesKey: true,

success: function (res) {

console.log('Android搜索成功')

console.log(res)

},

fail: function (err) {

console.log(err)

wx.hideLoading()

that.startBluetoothDevicesDiscovery()

// that.getBluetoothAdapterState()

util.showToast('搜索失败')

}

})

}

},

startConnectDevices: function (ltype, array) {

var that = this

clearTimeout(that.getConnectedTimer)

that.getConnectedTimer = null

wx.stopBluetoothDevicesDiscovery({

success: function (res) {

// success

}

})

app.globalData.ble_isonnectting = true

console.log('连接前:'+that.deviceId)

wx.createBLEConnection({

deviceId: that.deviceId,

success: function (res) {

if (res.errCode == 0) {

console.log('连接成功:')

that.getService(that.deviceId)

}

},

fail: function (err) {

console.log('连接失败:', err)

wx.hideLoading()

util.showModal('设备连接失败,请重试')

// if (ltype == 'loop') {

// that.connectDeviceIndex += 1

// that.loopConnect(array)

// } else {

// that.startBluetoothDevicesDiscovery()

// that.getConnectedBluetoothDevices()

// }

app.globalData.ble_isonnectting = false

},

complete: function () {

}

})

},

getService: function (deviceId) {

var that = this

// 监听蓝牙连接

wx.onBLEConnectionStateChange(function (res) {

console.log(res)

app.globalData.ble_isonnectting = res.connected

if (!res.connected) {

util.showToast('连接断开')

}

})

// 获取蓝牙设备service值

wx.getBLEDeviceServices({

deviceId: deviceId,

success: function (res) {

console.log('获取蓝牙设备service值')

console.log(res)

that.getCharacter(deviceId, res.services)

}

})

},

getCharacter: function (deviceId, services) {

var that = this

services.forEach(function (value, index, array) {

if (value.isPrimary) {

that.setData({

service_uuid: value.uuid,

deviceId: deviceId

})

app.globalData.service_uuid= value.uuid

app.globalData.deviceId=deviceId

}

})

//监听通知

wx.onBLECharacteristicValueChange(function (res) {

// callback

console.log('value change', res)

const hex = bletool.buf2char(res.value)

console.log('返回的数据:', hex)

//配对密码

if (hex.indexOf('855800000106') != -1) {

wx.hideLoading()

var charact_write = that.data.characteristics[1]

bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, that.data.service_psd)

wx.showToast({

title: '设备已连接',

icon: 'success',

duration: 3000

})

setTimeout(function () {

bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, '235525B837253705590400000273')

}, 2000)

} else if (hex.indexOf('23040000') != -1) {

//启动成功

that.starRenting()

}

})

wx.getBLEDeviceCharacteristics({

deviceId: deviceId,

serviceId: that.getServiceUUID(),

success: function (res) {

wx.getBLEDeviceCharacteristics({

deviceId: deviceId,

serviceId: that.getServiceUUID(),

success: function (res) {

console.log('特征', res)

that.setData({

characteristics:res.characteristics

})

app.globalData.characteristics = res.characteristics

var charact_read = res.characteristics[0]

},

loopConnect: function (devicesId) {

var that = this

var listLen = devicesId.length

if (devicesId[this.connectDeviceIndex]) {

this.deviceId = devicesId[this.connectDeviceIndex]

this.startConnectDevices('loop', devicesId)

} else {

console.log('已配对的设备小程序蓝牙连接失败')

that.startBluetoothDevicesDiscovery()

that.getConnectedBluetoothDevices()

}

},

//更新数据 devices为数组类型

updateBleList: function (devices) {

console.log('设备数据:',devices)

var newData = this.data.bleList

var that = this

var tempDevice = null

for (var i = 0i <devices.lengthi++) {

//ios设备

if (devices[i].devices != null) {

if (devices[i].devices.length >0) {

tempDevice = devices[i].devices[0]

}

else {

continue

}

}

//安卓

else {

tempDevice = devices[i]

}

if (!this.isExist(tempDevice)) {

newData.push(tempDevice)

}

}

console.log('数据:')

console.log(newData)

this.setData({

bleList: newData

})

if (!app.globalData.ble_isonnectting) {

var that = this

this.data.bleList.forEach(function (value, index, array) {

//找到对应id的设备,ios判断服务id安卓判断mac地址

var deviceId = value['deviceId']

if(bletool.isIOS()){

let advertisServiceUUID = value['advertisServiceUUIDs'][0]

if (advertisServiceUUID == that.data.serviceId.toUpperCase()){

that.deviceId = deviceId

console.log(that.deviceId)

that.startConnectDevices()

}

}else{

if (deviceId == that.data.serviceMac) {

that.deviceId = deviceId

console.log(that.deviceId)

that.startConnectDevices()

}

}

})

}

},

//是否已存在 存在返回true 否则false

isExist: function (device) {

var tempData = this.data.bleList

for (var i = 0i <tempData.lengthi++) {

if (tempData[i].deviceId == device.deviceId) {

return true

}

}

return false

},

//服务uuid

getServiceUUID: function () {

return bletool.stringTransition(this.data.service_uuid)

},

getDeviceInfo: function () {

let car_no = app.globalData.car_no

var that = this

wx.request({

url: app.globalData.serverURL + '?c=car&a=getDeviceInfo&open_id=' + app.globalData.open_id + '&car_no=' + car_no,

method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT

header: { 'content-type': 'application/json' }, // 设置请求的 header

success: function (res) {

// success

var data = res.data

console.log(data)

if (data.result == 1) {

app.globalData.serviceId = data.data.service_id

app.globalData.serviceMac = data.data.service_mac,

app.globalData.service_psd = '85' + data.data.service_psd + '5800000329'

that.setData({

serviceId: data.data.service_id,

serviceMac: data.data.service_mac,

service_psd: '85' + data.data.service_psd+'5800000329',

})

app.startBluetoothDevicesDiscovery()

// that.onBLECharacteristicValueChange()

} else {

util.showModal(data.msg)

}

},

fail: function () {

},

complete: function () {

// complete

}

})

},

})

整个功能基于canvas实现,首先添加画布组件,并设定样式

<!--index.wxml--><view class="container">

<canvas canvas-id="id-gesture-lock" class="gesture-lock" bindtouchstart="onTouchStart"

bindtouchmove="onTouchMove" bindtouchend="onTouchEnd"></canvas></view>.gesture-lock {

margin: 100rpx auto

width: 300px

height: 300px

background-color: #ffffff

}123456789101112

手势解锁实现代码在gesture_lock.js中(完整源码地址见末尾)。

初始化

constructor(canvasid, context, cb, opt){this.touchPoints = [] this.checkPoints = [] this.canvasid = canvasid this.ctx = context this.width = opt &&opt.width || 300//画布长度

this.height = opt &&opt.height || 300//画布宽度族毕

this.cycleNum = opt &&opt.cycleNum || 3 this.radius = 0 //触摸点半径

this.isParamOk = false this.marge = this.margeCircle = 25//触摸点及触摸点和画布边界间隔

this.initColor = opt &&opt.initColor || '#C5C5C3'

this.checkColor = opt &&opt.checkColor || '陆厅#5AA9EC' this.errorColor = opt &&opt.errorColor || '#e19984' this.touchState = "unTouch" this.checkParam() this.lastCheckPoint = null if (this.isParamOk) {// 计算触摸点的半径长度

this.radius = (this.width - this.marge * 2 - (this.margeCircle * (this.cycleNum - 1))) / (this.cycleNum * 2)this.radius = Math.floor(this.radius) // 计算每个触摸点的圆心位置

this.calCircleParams()

}this.onEnd = cb//滑动手势结束时的回调函数

}1234567891011121314151617181920212223242526

主要设置一些参数,如canvas的长宽,canvas的context,手势锁的个数(3乘3, 4乘4),手势锁的颜色,手势滑动结束时的回调函数等。并计算出手势锁的半径。

计算每个手早穗隐势锁的圆心位置

calCircleParams() {let n = this.cycleNum let count = 0 for (let i = 0i <ni++) {for (let j = 0j <nj++){

count++ let touchPoint = {

x: this.marge + i * (this.radius * 2 + this.margeCircle) + this.radius,

y: this.marge + j * (this.radius * 2 + this.margeCircle) + this.radius,

index: count,

check: "uncheck",

}this.touchPoints.push(touchPoint)

}

}

}1234567891011121314151617

绘制手势锁

for (let i = 0i <this.touchPoints.lengthi++){this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)

} this.ctx.draw(true)1234

接下来就是识别用户的滑动行为,判断用户划过了哪些圆圈,进而识别出用户的手势。

在touchstart和touchmove事件中检测触发并更新画布

onTouchStart(e) {// 不识别多点触控

if (e.touches.length >1){this.touchState = "unTouch" return

}this.touchState = "startTouch" this.checkTouch(e) let point = {x:e.touches[0].x, y:e.touches[0].y} this.drawCanvas(this.checkColor, point)

}

onTouchMove(e) {if (e.touchState === "unTouch") {return

}if (e.touches.length >1){this.touchState = "unTouch" return

}this.checkTouch(e) let point = {x:e.touches[0].x, y:e.touches[0].y} this.drawCanvas(this.checkColor, point)

}123456789101112131415161718192021222324

检测用户是否划过某个圆圈

checkTouch(e) {for (let i = 0i <this.touchPoints.lengthi++){let point = this.touchPoints[i] if (isPointInCycle(e.touches[0].x, e.touches[0].y, point.x, point.y, this.radius)) {if (point.check === 'uncheck') {this.checkPoints.push(point) this.lastCheckPoint = point

}

point.check = "check"

return

}

}

}12345678910111213

更新画布

drawCanvas(color, point) {//每次更新之前先清空画布

this.ctx.clearRect(0, 0, this.width, this.height) //使用不同颜色和形式绘制已触发和未触发的锁

for (let i = 0i <this.touchPoints.lengthi++){let point = this.touchPoints[i] if (point.check === "check") {this.drawCircle(point.x, point.y, this.radius, color) this.drawCircleCentre(point.x, point.y, color)

}else {this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)

}

}//绘制已识别锁之间的线段

if (this.checkPoints.length >1) { let lastPoint = this.checkPoints[0]for (let i = 1i <this.checkPoints.lengthi++) { this.drawLine(lastPoint, this.checkPoints[i], color)

lastPoint = this.checkPoints[i]

}

}//绘制最后一个识别锁和当前触摸点之间的线段

if (this.lastCheckPoint &&point) {this.drawLine(this.lastCheckPoint, point, color)

}this.ctx.draw(true)

}12345678910111213141516171819202122232425262728

当用户滑动结束时调用回调函数并传递识别出的手势

onTouchEnd(e) {typeof this.onEnd === 'function' &&this.onEnd(this.checkPoints, false)

}

onTouchCancel(e) {typeof this.onEnd === 'function' &&this.onEnd(this.checkPoints, true)

}1234567

重置和显示手势错误

gestureError() {this.drawCanvas(this.errorColor)

}

reset() {for (let i = 0i <this.touchPoints.lengthi++) {this.touchPoints[i].check = 'uncheck'

}this.checkPoints = [] this.lastCheckPoint = null this.drawCanvas(this.initColor)

}123456789101112

如何调用

在onload方法中创建lock对象并在用户触摸事件中调用相应方法

onLoad: function () {

var s = this this.lock = new Lock("id-gesture-lock", wx.createCanvasContext("id-gesture-lock"), function(checkPoints, isCancel) {

console.log('over')

s.lock.gestureError()

setTimeout(function() {

s.lock.reset()

}, 1000)

}, {width:300, height:300})this.lock.drawGestureLock()

console.log('onLoad')var that = this

//调用应用实例的方法获取全局数据

app.getUserInfo(function(userInfo){

//更新数据

that.setData({

userInfo:userInfo

})

that.update()

})

},

onTouchStart: function (e) {

this.lock.onTouchStart(e)

},

onTouchMove: function (e) {

this.lock.onTouchMove(e)

},

onTouchEnd: function (e) {

this.lock.onTouchEnd(e)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12562734.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存