| New file | 
|  |  |  | 
|---|
|  |  |  | <template> | 
|---|
|  |  |  | <view> | 
|---|
|  |  |  | <page-head :title="title"></page-head> | 
|---|
|  |  |  | <view class="uni-padding-wrap uni-common-mt"> | 
|---|
|  |  |  | <view> | 
|---|
|  |  |  | 本蓝牙协议只支持低功耗蓝牙协议ble。如果想连接非ble蓝牙设备,请在社区搜索 Native.js 蓝牙。 | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-btn-v"> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[0]" @click="openBluetoothAdapter"> | 
|---|
|  |  |  | 初始化蓝牙模块 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <view v-if="!adapterState.available"> | 
|---|
|  |  |  | {{ '蓝牙适配器不可用,请初始化蓝牙模块' }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <button | 
|---|
|  |  |  | type="primary" | 
|---|
|  |  |  | :loading="searchLoad" | 
|---|
|  |  |  | :disabled="disabled[1]" | 
|---|
|  |  |  | @click="startBluetoothDevicesDiscovery" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | 开始搜索蓝牙设备 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <button | 
|---|
|  |  |  | type="primary" | 
|---|
|  |  |  | :disabled="disabled[2]" | 
|---|
|  |  |  | @click="stopBluetoothDevicesDiscovery(false)" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | 停止搜索蓝牙设备 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <button | 
|---|
|  |  |  | type="primary" | 
|---|
|  |  |  | :loading="newDeviceLoad" | 
|---|
|  |  |  | :disabled="disabled[3]" | 
|---|
|  |  |  | @click="queryDevices" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | 选择设备 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <view v-if="equipment.length > 0"> | 
|---|
|  |  |  | {{ | 
|---|
|  |  |  | (connected ? '已连接设备' : '已选择设备') + | 
|---|
|  |  |  | ' : ' + | 
|---|
|  |  |  | equipment[0].name + | 
|---|
|  |  |  | ' (' + | 
|---|
|  |  |  | equipment[0].deviceId + | 
|---|
|  |  |  | ')' | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[4]" @click="createBLEConnection"> | 
|---|
|  |  |  | 连接蓝牙设备 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[5]" @click="getBLEDeviceServices"> | 
|---|
|  |  |  | 选择设备服务 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <view v-if="servicesData.length > 0">已选服务uuid:{{ servicesData[0].uuid }}</view> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[6]" @click="getBLEDeviceCharacteristics"> | 
|---|
|  |  |  | 获取服务的特征值 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <view v-if="characteristicsData.length > 0"> | 
|---|
|  |  |  | <view class="uni-list_name">uuid:{{ characteristicsData[0].uuid }}</view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 read 操作:{{ characteristicsData[0].properties.read }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 write 操作:{{ characteristicsData[0].properties.write }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 notify 操作:{{ characteristicsData[0].properties.notify }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 indicate 操作:{{ characteristicsData[0].properties.indicate }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <!-- <button type="primary" :disabled="disabled[7]" @click="readBLECharacteristicValue"> | 
|---|
|  |  |  | 读取特征值数据 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <view v-if="valueChangeData.serviceId"> | 
|---|
|  |  |  | <view class="list-name"> | 
|---|
|  |  |  | 特征值最新的值:{{ valueChangeData.value || '还没有最新值' }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> --> | 
|---|
|  |  |  | <!-- <button type="primary" :disabled="disabled[8]" @click="w">写入特征值数据</button> --> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[9]" @click="closeBLEConnection"> | 
|---|
|  |  |  | 断开蓝牙设备 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | <button type="primary" :disabled="disabled[10]" @click="closeBluetoothAdapter"> | 
|---|
|  |  |  | 关闭蓝牙模块 | 
|---|
|  |  |  | </button> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <!-- 遮罩 --> | 
|---|
|  |  |  | <view v-if="maskShow" class="uni-mask" @touchmove.stop.prevent="moveHandle" @click="maskclose"> | 
|---|
|  |  |  | <scroll-view class="uni-scroll_box" scroll-y @touchmove.stop.prevent="moveHandle" @click.stop="moveHandle"> | 
|---|
|  |  |  | <view class="uni-title"> | 
|---|
|  |  |  | 已经发现{{ list.length }}{{ showMaskType === 'device' ? '台设备' : '个服务' }}: | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view | 
|---|
|  |  |  | class="uni-list-box" | 
|---|
|  |  |  | v-for="(item, index) in list" | 
|---|
|  |  |  | :key="index" | 
|---|
|  |  |  | @click="tapQuery(item)" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <view v-if="showMaskType === 'device'"> | 
|---|
|  |  |  | <view class="uni-list_name">{{ item.name || item.localName }}</view> | 
|---|
|  |  |  | <view class="uni-list_item">信号强度:{{ item.RSSI }}dBm</view> | 
|---|
|  |  |  | <view class="uni-list_item">UUID:{{ item.deviceId }}</view> | 
|---|
|  |  |  | <!-- <view class="list-item" v-if="showMaskType === 'device'"> | 
|---|
|  |  |  | Service数量:{{ item.advertisServiceUUIDs.length }} | 
|---|
|  |  |  | </view> --> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view v-if="showMaskType === 'service'"> | 
|---|
|  |  |  | <view class="uni-list_item" style="line-height:2.2;"> | 
|---|
|  |  |  | UUID: {{ item.uuid }} | 
|---|
|  |  |  | <text v-if="showMaskType === 'service'"> | 
|---|
|  |  |  | {{ item.isPrimary ? '(主服务)' : '' }} | 
|---|
|  |  |  | </text> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view v-if="showMaskType === 'characteristics'"> | 
|---|
|  |  |  | <view class="uni-list_name">uuid:{{ item.uuid }}</view> | 
|---|
|  |  |  | <view class="uni-list_item">是否支持 read 操作:{{ item.properties.read }}</view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 write 操作:{{ item.properties.write }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 notify 操作:{{ item.properties.notify }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <view class="uni-list_item"> | 
|---|
|  |  |  | 是否支持 indicate 操作:{{ item.properties.indicate }} | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </scroll-view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <script> | 
|---|
|  |  |  | export default { | 
|---|
|  |  |  | data() { | 
|---|
|  |  |  | return { | 
|---|
|  |  |  | title: 'bluetooth', | 
|---|
|  |  |  | disabled: [false, true, true, true, true, true, true, true, true, true, true], | 
|---|
|  |  |  | newDeviceLoad: false, | 
|---|
|  |  |  | searchLoad: false, | 
|---|
|  |  |  | maskShow: false, | 
|---|
|  |  |  | equipment: [], | 
|---|
|  |  |  | adapterState: { | 
|---|
|  |  |  | discovering: false, | 
|---|
|  |  |  | available: false | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | connected: false, | 
|---|
|  |  |  | showMaskType: 'device', | 
|---|
|  |  |  | servicesData: [], | 
|---|
|  |  |  | characteristicsData: [], | 
|---|
|  |  |  | valueChangeData: {}, | 
|---|
|  |  |  | isStop:true , | 
|---|
|  |  |  | list: [] | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | onLoad() { | 
|---|
|  |  |  | this.onBLEConnectionStateChange(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | methods: { | 
|---|
|  |  |  | moveHandle() {}, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 关闭遮罩 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | maskclose(){ | 
|---|
|  |  |  | this.maskShow = false; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 选择设备 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | queryDevices() { | 
|---|
|  |  |  | // this.newDeviceLoad = true; | 
|---|
|  |  |  | this.showMaskType = 'device'; | 
|---|
|  |  |  | this.maskShow = true; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | tapQuery(item) { | 
|---|
|  |  |  | if (this.showMaskType === 'device') { | 
|---|
|  |  |  | this.$set(this.disabled, 4, false); | 
|---|
|  |  |  | if (this.equipment.length > 0) { | 
|---|
|  |  |  | this.equipment[0] = item; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | this.equipment.push(item); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.newDeviceLoad = false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (this.showMaskType === 'service') { | 
|---|
|  |  |  | this.$set(this.disabled, 6, false); | 
|---|
|  |  |  | if (this.servicesData.length > 0) { | 
|---|
|  |  |  | this.servicesData[0] = item; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | this.servicesData.push(item); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (this.showMaskType === 'characteristics') { | 
|---|
|  |  |  | this.$set(this.disabled, 7, false); | 
|---|
|  |  |  | if (this.characteristicsData.length > 0) { | 
|---|
|  |  |  | this.characteristicsData[0] = item; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | this.characteristicsData.push(item); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.maskShow = false; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 初始化蓝牙设备 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | openBluetoothAdapter() { | 
|---|
|  |  |  | uni.openBluetoothAdapter({ | 
|---|
|  |  |  | success: e => { | 
|---|
|  |  |  | console.log('初始化蓝牙成功:' + e.errMsg); | 
|---|
|  |  |  | console.log(JSON.stringify(e)); | 
|---|
|  |  |  | this.isStop = false ; | 
|---|
|  |  |  | this.$set(this.disabled, 0, true); | 
|---|
|  |  |  | this.$set(this.disabled, 1, false); | 
|---|
|  |  |  | this.$set(this.disabled, 10, false); | 
|---|
|  |  |  | this.getBluetoothAdapterState(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log(e) | 
|---|
|  |  |  | console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg)); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode,e.errMsg); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 开始搜索蓝牙设备 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | startBluetoothDevicesDiscovery() { | 
|---|
|  |  |  | uni.startBluetoothDevicesDiscovery({ | 
|---|
|  |  |  | success: e => { | 
|---|
|  |  |  | console.log('开始搜索蓝牙设备:' + e.errMsg); | 
|---|
|  |  |  | this.searchLoad = true; | 
|---|
|  |  |  | this.$set(this.disabled, 1, true); | 
|---|
|  |  |  | this.$set(this.disabled, 2, false); | 
|---|
|  |  |  | this.$set(this.disabled, 3, false); | 
|---|
|  |  |  | this.onBluetoothDeviceFound(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('搜索蓝牙设备失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 停止搜索蓝牙设备 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | stopBluetoothDevicesDiscovery(types) { | 
|---|
|  |  |  | uni.stopBluetoothDevicesDiscovery({ | 
|---|
|  |  |  | success: e => { | 
|---|
|  |  |  | console.log('停止搜索蓝牙设备:' + e.errMsg); | 
|---|
|  |  |  | if (types) { | 
|---|
|  |  |  | this.$set(this.disabled, 1, true); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | this.$set(this.disabled, 1, false); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.$set(this.disabled, 2, true); | 
|---|
|  |  |  | // this.$set(this.disabled, 3, true); | 
|---|
|  |  |  | this.searchLoad = false; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 发现外围设备 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | onBluetoothDeviceFound() { | 
|---|
|  |  |  | uni.onBluetoothDeviceFound(devices => { | 
|---|
|  |  |  | console.log('开始监听寻找到新设备的事件'); | 
|---|
|  |  |  | // this.$set(this.disabled, 3, false); | 
|---|
|  |  |  | this.getBluetoothDevices(); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | getBluetoothDevices() { | 
|---|
|  |  |  | uni.getBluetoothDevices({ | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | this.newDeviceLoad = false; | 
|---|
|  |  |  | console.log('获取蓝牙设备成功:' + res.errMsg); | 
|---|
|  |  |  | // console.log(JSON.stringify(res)) | 
|---|
|  |  |  | this.list = res.devices; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('获取蓝牙设备错误,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取本机蓝牙适配器状态 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | getBluetoothAdapterState() { | 
|---|
|  |  |  | console.log('--->'); | 
|---|
|  |  |  | uni.getBluetoothAdapterState({ | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log(JSON.stringify(res)); | 
|---|
|  |  |  | this.adapterState = res; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('获取本机蓝牙适配器状态失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 连接低功耗蓝牙 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | createBLEConnection() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | uni.showToast({ | 
|---|
|  |  |  | title: '连接蓝牙...', | 
|---|
|  |  |  | icon: 'loading', | 
|---|
|  |  |  | duration: 99999 | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | uni.createBLEConnection({ | 
|---|
|  |  |  | // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log(res); | 
|---|
|  |  |  | console.log('连接蓝牙成功:' + res.errMsg); | 
|---|
|  |  |  | // 连接设备后断开搜索 并且不能搜索设备 | 
|---|
|  |  |  | this.stopBluetoothDevicesDiscovery(true); | 
|---|
|  |  |  | uni.hideToast(); | 
|---|
|  |  |  | uni.showToast({ | 
|---|
|  |  |  | title: '连接成功', | 
|---|
|  |  |  | icon: 'success', | 
|---|
|  |  |  | duration: 2000 | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | this.$set(this.disabled, 3, true); | 
|---|
|  |  |  | this.$set(this.disabled, 4, true); | 
|---|
|  |  |  | this.$set(this.disabled, 5, false); | 
|---|
|  |  |  | this.$set(this.disabled, 9, false); | 
|---|
|  |  |  | this.connected = true; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('连接低功耗蓝牙失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 断开与低功耗蓝牙设备的连接 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | closeBLEConnection() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | uni.closeBLEConnection({ | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log(res); | 
|---|
|  |  |  | console.log('断开低功耗蓝牙成功:' + res.errMsg); | 
|---|
|  |  |  | this.$set(this.disabled, 1, false); | 
|---|
|  |  |  | this.$set(this.disabled, 3, true); | 
|---|
|  |  |  | this.$set(this.disabled, 4, true); | 
|---|
|  |  |  | this.$set(this.disabled, 5, true); | 
|---|
|  |  |  | this.$set(this.disabled, 6, true); | 
|---|
|  |  |  | this.$set(this.disabled, 7, true); | 
|---|
|  |  |  | this.$set(this.disabled, 8, true); | 
|---|
|  |  |  | this.$set(this.disabled, 9, true); | 
|---|
|  |  |  | this.equipment = []; | 
|---|
|  |  |  | this.servicesData = []; | 
|---|
|  |  |  | this.characteristicsData = []; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('断开低功耗蓝牙成功,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取所有服务 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | getBLEDeviceServices() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | console.log('获取所有服务的 uuid:' + deviceId); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | uni.getBLEDeviceServices({ | 
|---|
|  |  |  | // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log(JSON.stringify(res.services)); | 
|---|
|  |  |  | console.log('获取设备服务成功:' + res.errMsg); | 
|---|
|  |  |  | this.$set(this.disabled, 7, true); | 
|---|
|  |  |  | this.$set(this.disabled, 8, true); | 
|---|
|  |  |  | this.showMaskType = 'service'; | 
|---|
|  |  |  | this.list = res.services; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.characteristicsData = []; | 
|---|
|  |  |  | if (this.list.length <= 0) { | 
|---|
|  |  |  | toast('获取服务失败,请重试!'); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.maskShow = true; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('获取设备服务失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取某个服务下的所有特征值 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | getBLEDeviceCharacteristics() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | let serviceId = this.servicesData[0].uuid; | 
|---|
|  |  |  | console.log(deviceId); | 
|---|
|  |  |  | console.log(serviceId); | 
|---|
|  |  |  | uni.getBLEDeviceCharacteristics({ | 
|---|
|  |  |  | // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 | 
|---|
|  |  |  | serviceId, | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log(JSON.stringify(res)); | 
|---|
|  |  |  | console.log('获取特征值成功:' + res.errMsg); | 
|---|
|  |  |  | this.$set(this.disabled, 7, true); | 
|---|
|  |  |  | this.valueChangeData = {}; | 
|---|
|  |  |  | this.showMaskType = 'characteristics'; | 
|---|
|  |  |  | this.list = res.characteristics; | 
|---|
|  |  |  | if (this.list.length <= 0) { | 
|---|
|  |  |  | toast('获取特征值失败,请重试!'); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.maskShow = true; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail: e => { | 
|---|
|  |  |  | console.log('获取特征值失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | onBLEConnectionStateChange() { | 
|---|
|  |  |  | uni.onBLEConnectionStateChange(res => { | 
|---|
|  |  |  | // 该方法回调中可以用于处理连接意外断开等异常情况 | 
|---|
|  |  |  | console.log(`蓝牙连接状态 -------------------------->`); | 
|---|
|  |  |  | console.log(JSON.stringify(res)); | 
|---|
|  |  |  | if (!res.connected) { | 
|---|
|  |  |  | if(this.isStop) return ; | 
|---|
|  |  |  | console.log('断开低功耗蓝牙成功:'); | 
|---|
|  |  |  | this.$set(this.disabled, 1, false); | 
|---|
|  |  |  | this.$set(this.disabled, 3, true); | 
|---|
|  |  |  | this.$set(this.disabled, 4, true); | 
|---|
|  |  |  | this.$set(this.disabled, 5, true); | 
|---|
|  |  |  | this.$set(this.disabled, 6, true); | 
|---|
|  |  |  | this.$set(this.disabled, 7, true); | 
|---|
|  |  |  | this.$set(this.disabled, 8, true); | 
|---|
|  |  |  | this.$set(this.disabled, 9, true); | 
|---|
|  |  |  | this.searchLoad = false; | 
|---|
|  |  |  | this.equipment = []; | 
|---|
|  |  |  | this.servicesData = []; | 
|---|
|  |  |  | this.characteristicsData = []; | 
|---|
|  |  |  | this.valueChangeData = {}; | 
|---|
|  |  |  | toast('已经断开当前蓝牙连接'); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 读取低功耗蓝牙设备的特征值的二进制数据值。注意:必须设备的特征值支持 read 才可以成功调用 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | readBLECharacteristicValue() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | let serviceId = this.servicesData[0].uuid; | 
|---|
|  |  |  | let characteristicId = this.characteristicsData[0].uuid; | 
|---|
|  |  |  | console.log(deviceId); | 
|---|
|  |  |  | console.log(serviceId); | 
|---|
|  |  |  | console.log(characteristicId); | 
|---|
|  |  |  | uni.readBLECharacteristicValue({ | 
|---|
|  |  |  | // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 | 
|---|
|  |  |  | serviceId, | 
|---|
|  |  |  | // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取 | 
|---|
|  |  |  | characteristicId, | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log('读取设备数据值成功'); | 
|---|
|  |  |  | console.log(JSON.stringify(res)); | 
|---|
|  |  |  | this.notifyBLECharacteristicValueChange(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | fail(e) { | 
|---|
|  |  |  | console.log('读取设备数据值失败,错误码:' + e.errCode); | 
|---|
|  |  |  | if (e.errCode !== 0) { | 
|---|
|  |  |  | initTypes(e.errCode); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | this.onBLECharacteristicValueChange(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | onBLECharacteristicValueChange() { | 
|---|
|  |  |  | // 必须在这里的回调才能获取 | 
|---|
|  |  |  | uni.onBLECharacteristicValueChange(characteristic => { | 
|---|
|  |  |  | console.log('监听低功耗蓝牙设备的特征值变化事件成功'); | 
|---|
|  |  |  | console.log(JSON.stringify(characteristic)); | 
|---|
|  |  |  | this.valueChangeData = characteristic; | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | notifyBLECharacteristicValueChange() { | 
|---|
|  |  |  | let deviceId = this.equipment[0].deviceId; | 
|---|
|  |  |  | let serviceId = this.servicesData[0].uuid; | 
|---|
|  |  |  | let characteristicId = this.characteristicsData[0].uuid; | 
|---|
|  |  |  | let notify = this.characteristicsData[0].properties.notify; | 
|---|
|  |  |  | console.log(deviceId); | 
|---|
|  |  |  | console.log(serviceId); | 
|---|
|  |  |  | console.log(characteristicId); | 
|---|
|  |  |  | console.log(notify); | 
|---|
|  |  |  | uni.notifyBLECharacteristicValueChange({ | 
|---|
|  |  |  | state: true, // 启用 notify 功能 | 
|---|
|  |  |  | // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 | 
|---|
|  |  |  | deviceId, | 
|---|
|  |  |  | // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 | 
|---|
|  |  |  | serviceId, | 
|---|
|  |  |  | // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取 | 
|---|
|  |  |  | characteristicId, | 
|---|
|  |  |  | success(res) { | 
|---|
|  |  |  | console.log('notifyBLECharacteristicValueChange success:' + res.errMsg); | 
|---|
|  |  |  | console.log(JSON.stringify(res)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | *     断开蓝牙模块 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | closeBluetoothAdapter(OBJECT) { | 
|---|
|  |  |  | uni.closeBluetoothAdapter({ | 
|---|
|  |  |  | success: res => { | 
|---|
|  |  |  | console.log('断开蓝牙模块成功'); | 
|---|
|  |  |  | this.isStop = true ; | 
|---|
|  |  |  | this.$set(this.disabled, 0, false); | 
|---|
|  |  |  | this.$set(this.disabled, 1, true); | 
|---|
|  |  |  | this.$set(this.disabled, 2, true); | 
|---|
|  |  |  | this.$set(this.disabled, 3, true); | 
|---|
|  |  |  | this.$set(this.disabled, 4, true); | 
|---|
|  |  |  | this.$set(this.disabled, 5, true); | 
|---|
|  |  |  | this.$set(this.disabled, 6, true); | 
|---|
|  |  |  | this.$set(this.disabled, 7, true); | 
|---|
|  |  |  | this.$set(this.disabled, 8, true); | 
|---|
|  |  |  | this.$set(this.disabled, 9, true); | 
|---|
|  |  |  | this.$set(this.disabled, 10, true); | 
|---|
|  |  |  | this.equipment = []; | 
|---|
|  |  |  | this.servicesData = []; | 
|---|
|  |  |  | this.characteristicsData = []; | 
|---|
|  |  |  | this.valueChangeData = {}; | 
|---|
|  |  |  | this.adapterState = []; | 
|---|
|  |  |  | this.searchLoad =false; | 
|---|
|  |  |  | toast('断开蓝牙模块'); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 判断初始化蓝牙状态 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | function initTypes(code, errMsg) { | 
|---|
|  |  |  | switch (code) { | 
|---|
|  |  |  | case 10000: | 
|---|
|  |  |  | toast('未初始化蓝牙适配器'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10001: | 
|---|
|  |  |  | toast('未检测到蓝牙,请打开蓝牙重试!'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10002: | 
|---|
|  |  |  | toast('没有找到指定设备'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10003: | 
|---|
|  |  |  | toast('连接失败'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10004: | 
|---|
|  |  |  | toast('没有找到指定服务'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10005: | 
|---|
|  |  |  | toast('没有找到指定特征值'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10006: | 
|---|
|  |  |  | toast('当前连接已断开'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10007: | 
|---|
|  |  |  | toast('当前特征值不支持此操作'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10008: | 
|---|
|  |  |  | toast('其余所有系统上报的异常'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 10009: | 
|---|
|  |  |  | toast('Android 系统特有,系统版本低于 4.3 不支持 BLE'); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | default: | 
|---|
|  |  |  | toast(errMsg); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 弹出框封装 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | function toast(content, showCancel = false) { | 
|---|
|  |  |  | uni.showModal({ | 
|---|
|  |  |  | title: '提示', | 
|---|
|  |  |  | content, | 
|---|
|  |  |  | showCancel | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | </script> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <style> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .uni-title { | 
|---|
|  |  |  | /* width: 100%; */ | 
|---|
|  |  |  | /* height: 80rpx; */ | 
|---|
|  |  |  | text-align: center; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .uni-mask { | 
|---|
|  |  |  | position: fixed; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | align-items: center; | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | background: rgba(0, 0, 0, 0.6); | 
|---|
|  |  |  | padding: 0 30rpx; | 
|---|
|  |  |  | box-sizing: border-box; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .uni-scroll_box { | 
|---|
|  |  |  | height: 70%; | 
|---|
|  |  |  | background: #fff; | 
|---|
|  |  |  | border-radius: 20rpx; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-list-box { | 
|---|
|  |  |  | margin: 0 20rpx; | 
|---|
|  |  |  | padding: 15rpx 0; | 
|---|
|  |  |  | border-bottom: 1px #f5f5f5 solid; | 
|---|
|  |  |  | box-sizing: border-box; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-list:last-child { | 
|---|
|  |  |  | border: none; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-list_name { | 
|---|
|  |  |  | font-size: 30rpx; | 
|---|
|  |  |  | color: #333; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-list_item { | 
|---|
|  |  |  | font-size: 24rpx; | 
|---|
|  |  |  | color: #555; | 
|---|
|  |  |  | line-height: 1.5; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .uni-success_box { | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | min-height: 100rpx; | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | background: #fff; | 
|---|
|  |  |  | box-sizing: border-box; | 
|---|
|  |  |  | border-top: 1px #eee solid; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-success_sub { | 
|---|
|  |  |  | /* width: 100%%; */ | 
|---|
|  |  |  | height: 100rpx; | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | justify-content: space-between; | 
|---|
|  |  |  | align-items: center; | 
|---|
|  |  |  | padding: 0 30rpx; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-close_button { | 
|---|
|  |  |  | padding: 0 20rpx; | 
|---|
|  |  |  | height: 60rpx; | 
|---|
|  |  |  | line-height: 60rpx; | 
|---|
|  |  |  | background: #ce3c39; | 
|---|
|  |  |  | color: #ffffff; | 
|---|
|  |  |  | border-radius: 10rpx; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-success_content { | 
|---|
|  |  |  | height: 600rpx; | 
|---|
|  |  |  | margin: 30rpx; | 
|---|
|  |  |  | margin-top: 0; | 
|---|
|  |  |  | border: 1px #eee solid; | 
|---|
|  |  |  | padding: 30rpx; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-content_list { | 
|---|
|  |  |  | padding-bottom: 10rpx; | 
|---|
|  |  |  | border-bottom: 1px #f5f5f5 solid; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .uni-tips { | 
|---|
|  |  |  | text-align: center; | 
|---|
|  |  |  | font-size: 24rpx; | 
|---|
|  |  |  | color: #666; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | </style> | 
|---|