uniapp:蓝牙模块

模拟的是蓝牙设备签到/签出:

  1. 获取指定蓝牙设备
  2. 蓝牙初始搜索次数限制,超过限制就停止搜索
  3. 蓝牙连接失败次数限制,超过限制标识蓝牙连接失败(离开蓝牙范围或其他原因)
  4. 自动重连指定蓝牙
const device = ref<any>(null); // 设备信息
const crpBlueList = ref<any[]>([]); // 扫描到的蓝牙信息列表
const linkStatus = ref(false); // 连接状态
const searchTimes = ref(0); // 搜索次数
const searchLimit = 5; // 搜索次数限制
const linkTimes = ref(0); // 扫描次数
const failTimes = ref(0); // 失败次数
const failLimit = 5; // 失败次数限制
const blueName = 'zo-crp'; // 指定蓝牙设备的名称前缀
let isSignIn = false; // 是否签到
// 签到
const signIn = () => {
  searchTimes.value = 0;
  uni.showLoading({
    title: '蓝牙搜索中...',
    mask: true
  });
  openBluetoothAdapter(() => {
    startBluetoothDeviceDiscovery();
  });
};
// 签出
const logout = () => {
  closeBlueTooth(device.value, () => {
    isSignIn = false;
    device.value = null;
    linkStatus.value = false;
    searchTimes.value = 0;
    linkTimes.value = 0;
    failTimes.value = 0;
    crpBlueList.value = [];

    uni.showToast({
      title: '已签出'
    });
  });
};
// 初始化蓝牙
const openBluetoothAdapter = (callback: Function) => {
  uni.openBluetoothAdapter({
    //打开蓝牙适配器接口
    success: (res) => {
      //已打开
      callback();
    },
    fail: (err) => {
      uni.hideLoading();
      uni.showModal({
        title: '',
        content: '该操作需要蓝牙支持!请打开蓝牙',
        showCancel: false,
        success: (res) => {
          if (res.confirm) {
            // #ifdef APP
            let main = plus.android.runtimeMainActivity();
            let Intent = plus.android.importClass('android.content.Intent');
            let mIntent = new Intent('android.settings.BLUETOOTH_SETTINGS');
            main.startActivity(mIntent);
            // #endif
          } else {
            navigateBack();
          }
        },
        complete: () => {}
      });
    }
  });
};
// 搜索蓝牙
const startBluetoothDeviceDiscovery = () => {
  if (searchTimes.value > searchLimit - 1) {
    uni.showModal({
      content:
        '没有找到指定的蓝牙设备,请确认所在位置周边有指定蓝牙设备,且手机已开启位置信息并授权',
      confirmText: '重试',
      success: (res) => {
        if (res.confirm) {
          signIn();
        } else {
          stopBluetoothDevicesDiscovery(() => {
            uni.closeBluetoothAdapter({
              complete: () => {
                navigateBack();
              }
            });
          });
        }
      }
    });
    return;
  }
  searchTimes.value += 1;
  uni.startBluetoothDevicesDiscovery({
    success: (res) => {
      // 发现外围设备
      onBluetoothDeviceFound();
    },
    fail: (err) => {
      console.log(err, '开始搜索蓝牙设备备错误信息');
    }
  });
};
// 发现设备
const onBluetoothDeviceFound = () => {
  let t: any = setTimeout(() => {
    clearTimeout(t);
    t = null;
    stopBluetoothDevicesDiscovery(() => {
      // 停止搜索蓝牙
      uni.getBluetoothDevices({
        success: (res) => {
          const blueList = res.devices
            .filter((item: any) => item.name.toLowerCase().startsWith(blueName))
            .sort((a: any, b: any) => b.RSSI - a.RSSI);
          crpBlueList.value = blueList;
          if (!blueList.length) {
            startBluetoothDeviceDiscovery();
            return;
          }
          const Device: any = blueList[0];
          isSignIn = true;
          // 获取电量
          const serviceData = Array.prototype.map
            .call(new Uint8Array(Device.serviceData[Object.keys(Device.serviceData)[0]]), (bit) =>
              bit.toString(16)
            )
            .join('');
          const Electric = parseInt(serviceData.slice(-2), 16);
          // 获取uuid
          const UUID = Array.prototype.map
            .call(new Uint8Array(Device.advertisData), (bit) => ('00' + bit.toString(16)).slice(-2))
            .join('')
            .substring(8, 40)
            .toUpperCase();
          device.value = {
            name: Device.name,
            deviceId: Device.deviceId,
            electric: Electric,
            RSSI: Device.RSSI,
            UUID: UUID
          };
          linkStatus.value = true;
          createBLEConnection(Device);
        }
      });
    });
  }, 2000);
};
// 连接设备
const createBLEConnection = (item: any) => {
  uni.showLoading({
    title: '连接中,请稍等',
    mask: true
  });
  linkTimes.value += 1;
  uni.createBLEConnection({
    deviceId: item.deviceId,
    success(res) {
      linkStatus.value = true;
      failTimes.value = 0;
      uni.showToast({
        title: '蓝牙已连接',
        mask: true
      });
      onBLEConnectionStateChange(item);
    },
    fail(res) {
      linkStatus.value = false;
      plus.device.vibrate(500);
      if (failTimes.value < failLimit) {
        failTimes.value += 1;
        uni.showToast({
          title: item.name + '蓝牙连接失败',
          icon: 'none'
        });
        reLink(item);
      } else {
        closeBlueTooth(item, () => {
          uni.showToast({
            title: item.name + '蓝牙连接失败,取消连接',
            icon: 'none'
          });
        });
      }
    }
  });
};
// 监听蓝牙状态
const onBLEConnectionStateChange = (item: any) => {
  uni.onBLEConnectionStateChange((res) => {
    m_Debounce(() => {
      if (!res.connected && isSignIn) {
        reLink(item);
      }
    }, 500);
  });
};
// 蓝牙重连
const reLink = (item: any) => {
  closeBlueTooth(item, () => {
    let t: any = setTimeout(() => {
      clearTimeout(t);
      t = null;
      openBluetoothAdapter(() => {
        createBLEConnection(item);
      });
    }, 1000);
  });
};

// 关闭连接+关闭蓝牙模块
const closeBlueTooth = (item: any, callback: Function) => {
  // 关闭连接
  uni.closeBLEConnection({
    deviceId: item.deviceId,
    complete: () => {
      // 关闭蓝牙模块
      uni.closeBluetoothAdapter({
        complete: () => {
          callback();
        }
      });
    }
  });
};

// 停止搜索
const stopBluetoothDevicesDiscovery = (callback: Function) => {
  uni.stopBluetoothDevicesDiscovery({
    complete: (e) => {
      callback();
    },
    fail: (e) => {
      console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
    }
  });
};
// 后退
const navigateBack = () => {
  uni.navigateBack({
    delta: 1,
    fail: () => {
      uni.reLaunch({
        url: '/pages/home/home'
      });
    }
  });
};

你可能感兴趣的:(uniapp,uni-app)