You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
7.4 KiB

2 years ago
<template>
<view class="main-container">
<view class="headbtn">
<button @click="searchDevice">搜索设备</button>
</view>
<scroll-view scroll-y="true" :refresher-enabled="false">
<view v-for="(item, index) in deviceListDataShow" :key="item.id" class="list-item"
hover-class="list-item-hover" hover-start-time="0" hover-stay-time="100" @click="listViewTap(item)">
2 years ago
<!-- <image v-if="item.manufacturer==='eciot'" src="/static/img/ecble.png" class="list-item-img"></image> -->
<image src="/static/img/ble.png" class="list-item-img"></image>
<text class="list-item-name">{{item.name}}</text>
<image v-if="item.rssi >= -41" src="/static/img/s5.png" mode="aspectFit" class="list-item-rssi-img">
</image>
<image v-else-if="item.rssi >= -55" src="/static/img/s4.png" mode="aspectFit"
class="list-item-rssi-img"></image>
<image v-else-if="item.rssi >= -65" src="/static/img/s3.png" mode="aspectFit"
class="list-item-rssi-img"></image>
<image v-else-if="item.rssi >= -75" src="/static/img/s2.png" mode="aspectFit"
class="list-item-rssi-img"></image>
<image v-else="item.rssi < -75" src="/static/img/s1.png" mode="aspectFit" class="list-item-rssi-img">
</image>
2 years ago
<text class="list-item-rssi">{{item.rssi}}</text>
<view class="list-item-line"></view>
</view>
<view v-if="deviceListDataShow.length==0" class="notice"> - 未发现设备请确认蓝牙是否打开 -</view>
<view class="gap"></view>
<u-toast ref="uToast"></u-toast>
</scroll-view>
</view>
2 years ago
</template>
<script>
// #ifdef APP
import ecUI from '@/utils/ecUI.js'
import ecBLE from '@/utils/ecBLE/ecBLE.js'
// #endif
// #ifdef MP
const ecUI = require('@/utils/ecUI.js')
const ecBLE = require('@/utils/ecBLE/ecBLE.js')
// #endif
2 years ago
let ctx
let deviceListData = []
export default {
2 years ago
data() {
return {
deviceListDataShow: [],
debouncedSearch:null,
2 years ago
}
},
onLoad() {
ctx = this
this.requestAndroidPermission();
},
onShow() {
setTimeout(() => {
ctx.openBluetoothAdapter()
}, 100)
this.requestAndroidPermission().then((res) => {
2 years ago
console.log(res);
}).catch((error) => {
2 years ago
console.log(error);
})
this.debouncedSearch = this.debounce(() => {
this.searchDevice2();
}, 1000);
2 years ago
},
onHide() {
setTimeout(() => {
ecBLE.stopBluetoothDevicesDiscovery();
}, 100)
2 years ago
},
methods: {
requestAndroidPermission(permissionID) {
2 years ago
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
['android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.BLUETOOTH_ADMIN',
'android.permission.ACCESS_FINE_LOCATION'
2 years ago
], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function(resultObj) {
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
result = 1
console.log('已获取的权限:' + result);
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
result = 0
console.log('拒绝本次申请的权限:' + result);
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
result = -1
console.log('永久拒绝申请的权限:' + result);
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
},
listViewTap(item) {
2 years ago
let name = item.name.split('XS')[1];
let that = this;
getApp().globalData.id = name
getApp().globalData.deviceInfo = item
ecUI.showLoading('设备连接中');
ecBLE.onBLEConnectionStateChange(res => {
if (res.ok) {
ecUI.hideLoading()
ecBLE.stopBluetoothDevicesDiscovery()
uni.switchTab({
url: '/pages/configuration/index',
})
} else if (res.errCode != 0) {
2 years ago
ecUI.showModal(
'提示',
'连接失败,errCode=' + res.errCode + ',errMsg=' + res.errMsg
)
ecUI.hideLoading()
} else {
ecUI.hideLoading()
getApp().globalData.id = ''
2 years ago
}
})
ecBLE.createBLEConnection(item.id)
},
openBluetoothAdapter() {
ecBLE.onBluetoothAdapterStateChange(res => {
if (res.ok) {
console.log('Bluetooth adapter ok')
ctx.startBluetoothDevicesDiscovery()
} else {
ecUI.showModal(
'提示',
`Bluetooth adapter error | ${res.errCode} | ${res.errMsg}`,
() => {
}
)
}
})
ecBLE.openBluetoothAdapter()
},
startBluetoothDevicesDiscovery() {
console.log('start search')
ecBLE.onBluetoothDeviceFound(res => {
// if(res.id==="EC:22:05:13:78:49")
// console.log(`id:${res.id},name:${res.name},rssi:${res.rssi}`)
if (res.name.startsWith('XS') && Number(res.rssi) > -80) {
const existing = ctx.deviceListDataShow.find(d => d.id === res.id)
if (existing) {
existing.rssi = res.rssi; // 更新信号
} else {
ctx.deviceListDataShow.push({
id: res.id,
name: res.name,
rssi: res.rssi,
});
2 years ago
}
}
})
ecBLE.startBluetoothDevicesDiscovery()
},
debounce(fn, delay = 800) {
let that = this;
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(that, args)
}, delay)
}
},
async searchDevice2() {
let that = this;
await ecBLE.stopBluetoothDevicesDiscovery();
await ecBLE.startBluetoothDevicesDiscovery();
},
2 years ago
searchDevice(){
ctx.deviceListDataShow = []
this.debouncedSearch();
},
2 years ago
}
}
</script>
<style>
.main-container {
/* height: 100vh; */
}
.list-item {
height: 57px;
position: relative;
}
.list-item-hover {
background-color: #e5e4e9;
}
.list-item-img {
position: absolute;
width: 36px;
height: 36px;
left: 20px;
top: 10px;
}
.list-item-name {
position: absolute;
font-size: 22px;
left: 76px;
top: 0px;
line-height: 56px;
width: 290px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.list-item-rssi-img {
position: absolute;
width: 20px;
height: 20px;
right: 20px;
top: 13px;
}
.list-item-rssi {
position: absolute;
width: 40px;
height: 20px;
right: 10px;
top: 33px;
font-size: 12px;
font-weight: bold;
display: flex;
justify-content: center;
}
.list-item-line {
position: absolute;
height: 1px;
width: 100vw;
left: 20px;
top: 56px;
background-color: #c6c6c8;
}
.notice {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
font-size: 13px;
color: #909399;
}
.gap {
height: 57px;
}
.headbtn {
2 years ago
margin: 40rpx;
width: 200rpx;
}
.headbtn button {
2 years ago
background-color: #92CDDC;
color: #fff;
}
</style>