HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

这玩意bug 是真的多呀

bug反馈

这玩意bug 是真的多呀

这玩意bug 是真的多呀

uniapp 拉起Google地图导航

网上搜索到的案例太少了,要么就是调起后不显示定位点,要么就是会自动搜索传入的地点名字然后瞎跳转

最后在stackoverflow上找到了一段代码,安卓原生的想着拿过来也应该也可以用,没想到还真行,直接上代码吧:

传参方式

url = `geo:0,0?q=${lat},${lng} (${address})`

调这个URL就行了

plus.runtime.openURL( url, function( e ) {    
    plus.nativeUI.alert("本机未安装指定的地图应用");    
});  

详情见原文链接
Google地图 Intent调用

继续阅读 »

网上搜索到的案例太少了,要么就是调起后不显示定位点,要么就是会自动搜索传入的地点名字然后瞎跳转

最后在stackoverflow上找到了一段代码,安卓原生的想着拿过来也应该也可以用,没想到还真行,直接上代码吧:

传参方式

url = `geo:0,0?q=${lat},${lng} (${address})`

调这个URL就行了

plus.runtime.openURL( url, function( e ) {    
    plus.nativeUI.alert("本机未安装指定的地图应用");    
});  

详情见原文链接
Google地图 Intent调用

收起阅读 »

全栈定制开发

移动APP 微信小程序 外包接单

全栈定制开发
1,各平台小程序开发
2,app(android,ios) 技术栈 uni-app x 获原生开发
3,工厂数字化升级, mes方向;集成各厂商PLC,及数字孪生;
4,企业级门户网站
5,ai 行业助手定制;

有意站内私信 或:
电话:15210908900
邮箱:279955152@qq.com

继续阅读 »

全栈定制开发
1,各平台小程序开发
2,app(android,ios) 技术栈 uni-app x 获原生开发
3,工厂数字化升级, mes方向;集成各厂商PLC,及数字孪生;
4,企业级门户网站
5,ai 行业助手定制;

有意站内私信 或:
电话:15210908900
邮箱:279955152@qq.com

收起阅读 »

安卓app蓝牙打印票据(二维码)完整代码(vue2)

Native.JS 安卓 蓝牙打印

蓝牙搜索用的uni-app的低功耗蓝牙的方法,连接和打印用的安卓原生的方法,连接蓝牙会出现连接不成功的问题(或者连接成功但是连接状态是false)需要额外处理

<!-- 蓝牙打印页面 -->  
<template>  
  <view style="height: 100vh; display: flex; flex-direction: column">  
    <view style="flex: 1; overflow-y: auto; padding-bottom: 20rpx">  
      <button  
        class="button"  
        hover-class="hover"  
        @click="startSearch"  
        :loading="isScanning"  
      >  
        搜索蓝牙设备  
      </button>  
      <text class="td">(Android8.0+系统需开启定位)</text>  
      <view v-if="list.length > 0" style="text-align: center">  
        <view style="font-size: 18px">蓝牙设备列表</view>  
        <view style="color: #666; font-size: 10px">点击连接蓝牙设备</view>  
      </view>  
      <view v-if="deviceinfo.deviceId" class="linkcss"  
        >蓝牙设备已连接:{{ deviceinfo.name }}</view  
      >  
      <scroll-view class="device_list" scroll-y scroll-with-animation>  
        <view  
          :class="item.deviceId === deviceinfo.deviceId ? 'sign_step' : ''"  
          v-for="item in list"  
          :data-title="item.deviceId"  
          :data-name="item.name"  
          :data-advertisData="item.advertisServiceUUIDs"  
          :key="item.deviceId"  
          @click="bindViewTap(item)"  
          class="item"  
          hover-class="item_hover"  
        >  
          <view>  
            <view style="font-size: 16px">{{ item.name }}</view>  
            <view style="font-size: 12px">{{ item.deviceId }}</view>  
            <view style="font-size: 10px; color: #666"  
              >信号强度: {{ item.RSSI }}dBm  
            </view>  
          </view>  
        </view>  
      </scroll-view>  
    </view>  
    <view class="btncss">  
      <u-button  
        :disabled="!deviceinfo.deviceId"  
        :custom-style="{ width: '200rpx' }"  
        type="primary"  
        @click="submitPrinte"  
        >打 印</u-button  
      >  
    </view>  
  </view>  
</template>  

<script>  
function printAlignment(writer, align) {  
  // 对齐方式,0:左,1:中,2:右  
  writer.write(0x1b);  
  writer.write(0x61);  
  writer.write(align);  
  writer.write(0x1b);  
  writer.write(0x45);  
  writer.write(0x00);  
}  
function printFontsize(writer, size) {  
  // 字体大小  
  writer.write(0x1b);  
  writer.write(0x21);  
  writer.write(size);  
  writer.write(0x1b);  
  writer.write(0x45);  
  writer.write(0x00);  
}  
export default {  
  data() {  
    return {  
      list: [],  
      isScanning: false,  
      BLEInformation: {},  
    };  
  },  
  computed: {  
    deviceinfo() {  
      return this.BLEInformation;  
    },  
  },  
  methods: {  
    submitPrinte() {  
      console.log("进入打印方法中");  
      const that = this;  
      var main = plus.android.runtimeMainActivity();  
      var BluetoothAdapter = plus.android.importClass(  
        "android.bluetooth.BluetoothAdapter"  
      );  
      var UUID = plus.android.importClass("java.util.UUID");  
      var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
      var BAdapter = BluetoothAdapter.getDefaultAdapter();  
      var device = BAdapter.getRemoteDevice(that.BLEInformation.deviceId);  
      plus.android.importClass(device);  
      var bluetoothSocket =  
        device.createInsecureRfcommSocketToServiceRecord(uuid);  
      plus.android.importClass(bluetoothSocket);  
      if (!bluetoothSocket.isConnected()) {  
        console.log("检测到设备未连接,尝试连接....");  
        bluetoothSocket.connect();  
      }  
      console.log(bluetoothSocket.isConnected());  
      var outputStream = bluetoothSocket.getOutputStream();  
      plus.android.importClass(outputStream);  
      const OutputStreamWriter = plus.android.importClass(  
        "java.io.OutputStreamWriter"  
      );  
      const writer = new OutputStreamWriter(outputStream, "GBK");  
      plus.android.importClass(writer);  

      writer.write("\r\n"); //打印空行并换行  
      writer.write("\r\n"); //打印空行并换行  
      //标题  
      writer.write("标题:打印测试\r\n");  
      printFontsize(writer, 14); // 设置字体14  
      printAlignment(writer, 1); // 设置居中  
      writer.write("打印居中14号字体\r\n");  

      printFontsize(writer, 16); // 设置字体14  
      printAlignment(writer, 0); // 设置居中  
      writer.write("打印居左16号字体\r\n");  

      printAlignment(writer, 2); // 设置居中  
      writer.write("打印居右16号字体\r\n");  
      writer.write("\r\n"); //打印空行并换行  
      // 二维码打印——start  
      const qrcode = "二维码内容放在这里了";  
      var moduleSize = 8;  
      var qrcodebytes = plus.android.invoke(qrcode, "getBytes", "gbk");  
      var length = qrcodebytes.length;  
      writer.write(0x1b);  
      writer.write(0x40);  
      writer.flush();  
      printAlignment(writer, 1);  
      // 缓存二维码数据  
      writer.write(0x1d); // init  
      writer.write("(k"); // adjust height of barcode  
      writer.write(length + 3); // pl  
      writer.write(0); // ph  
      writer.write(49); // cn  
      writer.write(80); // fn  
      writer.write(48); //  
      writer.write(qrcode);  
      // 二维码纠错等级  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3);  
      writer.write(0);  
      writer.write(49);  
      writer.write(69);  
      writer.write(48);  
      // 设置二维码块大小  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3);  
      writer.write(0);  
      writer.write(49);  
      writer.write(67);  
      writer.write(moduleSize);  
      // 打印已缓存的数据二维码  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3); // pl  
      writer.write(0); // ph  
      writer.write(49); // cn  
      writer.write(81); // fn  
      writer.write(48); // m  

      writer.flush();  
      writer.write(0x1b);  
      writer.write(0x64);  
      writer.write(2); // 行数  
      writer.flush();  
      // 二维码打印——end  
      writer.flush();  
      // device = null; //这里关键  
      // bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误  
    },  
    startSearch() {  
      var that = this;  
      uni.openBluetoothAdapter({  
        success: function (res) {  
          uni.getBluetoothAdapterState({  
            success: function (res) {  
              console.log("openBluetoothAdapter success", res);  
              if (res.available) {  
                if (res.discovering) {  
                } else {  
                  that.getBluetoothDevices();  
                }  
              } else {  
                uni.showModal({  
                  title: "提示",  
                  content: "本机蓝牙不可用",  
                  showCancel: false,  
                });  
              }  
            },  
          });  
        },  
        fail: function (res) {  
          console.log(res);  
          uni.showModal({  
            title: "提示",  
            content: "蓝牙初始化失败,请到设置打开蓝牙",  
            showCancel: false,  
          });  
        },  
      });  
    },  
    getBluetoothDevices() {  
      var that = this;  
      uni.showLoading({  
        title: "正在搜索",  
        icon: "loading",  
      });  
      that.isScanning = true;  
      uni.startBluetoothDevicesDiscovery({  
        success: function (res) {  
          console.log(res);  
          setTimeout(function () {  
            // 不设置延迟获取的servers为空数组  
            uni.getBluetoothDevices({  
              success: function (res) {  
                var devices = [];  
                var num = 0;  
                for (var i = 0; i < res.devices.length; ++i) {  
                  if (  
                    res.devices[i].name != "未知设备"  
                  ) {  
                    devices[num] = res.devices[i];  
                    num++;  
                  }  
                }  
                that.list = devices;  
                that.isScanning = false;  
                uni.hideLoading();  
                uni.stopPullDownRefresh();  
                uni.stopBluetoothDevicesDiscovery({  
                  success: function (res) {  
                    console.log("停止搜索蓝牙");  
                    that.isScanning = false;  
                    uni.hideLoading();  
                  },  
                });  
              },  
            });  
          }, 5000);  
        },  
      });  
    },  
    bindViewTap(item) {  
      var that = this;  
      uni.showLoading({  
        title: "正在连接",  
      });  

      var main = plus.android.runtimeMainActivity();  
      var BluetoothAdapter = plus.android.importClass(  
        "android.bluetooth.BluetoothAdapter"  
      );  
      var UUID = plus.android.importClass("java.util.UUID");  
      var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
      var BAdapter = BluetoothAdapter.getDefaultAdapter();  
      var device = BAdapter.getRemoteDevice(item.deviceId);  
      plus.android.importClass(device);  
      var bluetoothSocket =  
        device.createInsecureRfcommSocketToServiceRecord(uuid);  
      plus.android.importClass(bluetoothSocket);  
      bluetoothSocket.connect();  
      console.log("连接:", bluetoothSocket.isConnected());  
      if (bluetoothSocket.isConnected()) {  
        that.openControl();  
        that.BLEInformation.deviceId = item.deviceId;  
        that.BLEInformation.name = item.name;  
        that.$forceUpdate();  
        console.log("that.BLEInformation:", that.BLEInformation);  
      }  
    },  
    openControl() {  
      // 连接成功后打印  
      uni.hideLoading();  
      const that = this;  
      uni.showModal({  
        title: "提示",  
        content: "蓝牙设备连接成功,是否确认打印",  
        success(res) {  
          if (res.confirm) {  
            that.submitPrinte();  
          }  
        },  
      });  
    },  
  },  
};  
</script>  

<style scoped lang="scss">  
.btncss {  
  background-color: white;  
  padding-inline: 20rpx;  
  width: 100%;  
  padding-top: 30rpx;  
  padding-bottom: 50rpx;  
  box-shadow: 2px 2px 4px 4px rgba(223, 223, 223, 0.5);  
  z-index: 9999;  
}  

.linkcss {  
  border: 2px solid #54bec2;  
  padding: 10px;  
  margin: 10px;  
}  

.button {  
  margin-top: 20px;  
  margin-bottom: 20px;  
  width: 70%;  
  background-color: #54bec2;  
  color: white;  
  border-radius: 98rpx;  
  background: bg_red;  
}  

/* 按下变颜色 */  
.hover {  
  background: #dcdcdc;  
}  

.device_list {  
  height: auto;  
  margin-left: 20rpx;  
  margin-right: 20rpx;  
  margin-top: 10px;  
  margin-bottom: 20px;  
  /* border: 1px solid #EEE; */  
  width: auto;  
}  

.td {  
  display: flex;  
  align-items: center;  
  justify-content: center;  
  margin-top: 10px;  
}  
.item {  
  display: block;  
  background-color: white;  
  border-radius: 18rpx;  
  margin-bottom: 16rpx;  
  padding: 8px;  
}  

.item_hover {  
  background-color: rgba(0, 0, 0, 0.1);  
}  

.block {  
  display: block;  
  color: #ffffff;  
  padding: 5px;  
}  

.button::after {  
  border-width: 0px;  
}  

.sign_step > view::after {  
  // 对钩的三角行底色  
  position: absolute;  
  right: 0;  
  top: 0;  
  width: 0;  
  height: 0;  
  content: "";  
  border: 16px solid;  
  border-color: #70cad3 #70cad3 transparent transparent;  
  border-bottom-right-radius: 2px;  
}  

.sign_step {  
  position: relative;  
  border: 2px solid #54bec2;  
}  

.sign_step > view::before {  
  // 对钩样式  
  position: absolute;  
  right: 2px;  
  top: 4px;  
  z-index: 1;  
  width: 10px;  
  height: 5px;  
  content: "";  
  background: transparent;  
  border: 2px solid white;  
  border-top: none;  
  border-right: none;  
  -webkit-transform: rotate(-55deg);  
  -ms-transform: rotate(-55deg);  
  transform: rotate(-55deg);  
}  
</style>  
继续阅读 »

蓝牙搜索用的uni-app的低功耗蓝牙的方法,连接和打印用的安卓原生的方法,连接蓝牙会出现连接不成功的问题(或者连接成功但是连接状态是false)需要额外处理

<!-- 蓝牙打印页面 -->  
<template>  
  <view style="height: 100vh; display: flex; flex-direction: column">  
    <view style="flex: 1; overflow-y: auto; padding-bottom: 20rpx">  
      <button  
        class="button"  
        hover-class="hover"  
        @click="startSearch"  
        :loading="isScanning"  
      >  
        搜索蓝牙设备  
      </button>  
      <text class="td">(Android8.0+系统需开启定位)</text>  
      <view v-if="list.length > 0" style="text-align: center">  
        <view style="font-size: 18px">蓝牙设备列表</view>  
        <view style="color: #666; font-size: 10px">点击连接蓝牙设备</view>  
      </view>  
      <view v-if="deviceinfo.deviceId" class="linkcss"  
        >蓝牙设备已连接:{{ deviceinfo.name }}</view  
      >  
      <scroll-view class="device_list" scroll-y scroll-with-animation>  
        <view  
          :class="item.deviceId === deviceinfo.deviceId ? 'sign_step' : ''"  
          v-for="item in list"  
          :data-title="item.deviceId"  
          :data-name="item.name"  
          :data-advertisData="item.advertisServiceUUIDs"  
          :key="item.deviceId"  
          @click="bindViewTap(item)"  
          class="item"  
          hover-class="item_hover"  
        >  
          <view>  
            <view style="font-size: 16px">{{ item.name }}</view>  
            <view style="font-size: 12px">{{ item.deviceId }}</view>  
            <view style="font-size: 10px; color: #666"  
              >信号强度: {{ item.RSSI }}dBm  
            </view>  
          </view>  
        </view>  
      </scroll-view>  
    </view>  
    <view class="btncss">  
      <u-button  
        :disabled="!deviceinfo.deviceId"  
        :custom-style="{ width: '200rpx' }"  
        type="primary"  
        @click="submitPrinte"  
        >打 印</u-button  
      >  
    </view>  
  </view>  
</template>  

<script>  
function printAlignment(writer, align) {  
  // 对齐方式,0:左,1:中,2:右  
  writer.write(0x1b);  
  writer.write(0x61);  
  writer.write(align);  
  writer.write(0x1b);  
  writer.write(0x45);  
  writer.write(0x00);  
}  
function printFontsize(writer, size) {  
  // 字体大小  
  writer.write(0x1b);  
  writer.write(0x21);  
  writer.write(size);  
  writer.write(0x1b);  
  writer.write(0x45);  
  writer.write(0x00);  
}  
export default {  
  data() {  
    return {  
      list: [],  
      isScanning: false,  
      BLEInformation: {},  
    };  
  },  
  computed: {  
    deviceinfo() {  
      return this.BLEInformation;  
    },  
  },  
  methods: {  
    submitPrinte() {  
      console.log("进入打印方法中");  
      const that = this;  
      var main = plus.android.runtimeMainActivity();  
      var BluetoothAdapter = plus.android.importClass(  
        "android.bluetooth.BluetoothAdapter"  
      );  
      var UUID = plus.android.importClass("java.util.UUID");  
      var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
      var BAdapter = BluetoothAdapter.getDefaultAdapter();  
      var device = BAdapter.getRemoteDevice(that.BLEInformation.deviceId);  
      plus.android.importClass(device);  
      var bluetoothSocket =  
        device.createInsecureRfcommSocketToServiceRecord(uuid);  
      plus.android.importClass(bluetoothSocket);  
      if (!bluetoothSocket.isConnected()) {  
        console.log("检测到设备未连接,尝试连接....");  
        bluetoothSocket.connect();  
      }  
      console.log(bluetoothSocket.isConnected());  
      var outputStream = bluetoothSocket.getOutputStream();  
      plus.android.importClass(outputStream);  
      const OutputStreamWriter = plus.android.importClass(  
        "java.io.OutputStreamWriter"  
      );  
      const writer = new OutputStreamWriter(outputStream, "GBK");  
      plus.android.importClass(writer);  

      writer.write("\r\n"); //打印空行并换行  
      writer.write("\r\n"); //打印空行并换行  
      //标题  
      writer.write("标题:打印测试\r\n");  
      printFontsize(writer, 14); // 设置字体14  
      printAlignment(writer, 1); // 设置居中  
      writer.write("打印居中14号字体\r\n");  

      printFontsize(writer, 16); // 设置字体14  
      printAlignment(writer, 0); // 设置居中  
      writer.write("打印居左16号字体\r\n");  

      printAlignment(writer, 2); // 设置居中  
      writer.write("打印居右16号字体\r\n");  
      writer.write("\r\n"); //打印空行并换行  
      // 二维码打印——start  
      const qrcode = "二维码内容放在这里了";  
      var moduleSize = 8;  
      var qrcodebytes = plus.android.invoke(qrcode, "getBytes", "gbk");  
      var length = qrcodebytes.length;  
      writer.write(0x1b);  
      writer.write(0x40);  
      writer.flush();  
      printAlignment(writer, 1);  
      // 缓存二维码数据  
      writer.write(0x1d); // init  
      writer.write("(k"); // adjust height of barcode  
      writer.write(length + 3); // pl  
      writer.write(0); // ph  
      writer.write(49); // cn  
      writer.write(80); // fn  
      writer.write(48); //  
      writer.write(qrcode);  
      // 二维码纠错等级  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3);  
      writer.write(0);  
      writer.write(49);  
      writer.write(69);  
      writer.write(48);  
      // 设置二维码块大小  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3);  
      writer.write(0);  
      writer.write(49);  
      writer.write(67);  
      writer.write(moduleSize);  
      // 打印已缓存的数据二维码  
      writer.write(0x1d);  
      writer.write("(k");  
      writer.write(3); // pl  
      writer.write(0); // ph  
      writer.write(49); // cn  
      writer.write(81); // fn  
      writer.write(48); // m  

      writer.flush();  
      writer.write(0x1b);  
      writer.write(0x64);  
      writer.write(2); // 行数  
      writer.flush();  
      // 二维码打印——end  
      writer.flush();  
      // device = null; //这里关键  
      // bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误  
    },  
    startSearch() {  
      var that = this;  
      uni.openBluetoothAdapter({  
        success: function (res) {  
          uni.getBluetoothAdapterState({  
            success: function (res) {  
              console.log("openBluetoothAdapter success", res);  
              if (res.available) {  
                if (res.discovering) {  
                } else {  
                  that.getBluetoothDevices();  
                }  
              } else {  
                uni.showModal({  
                  title: "提示",  
                  content: "本机蓝牙不可用",  
                  showCancel: false,  
                });  
              }  
            },  
          });  
        },  
        fail: function (res) {  
          console.log(res);  
          uni.showModal({  
            title: "提示",  
            content: "蓝牙初始化失败,请到设置打开蓝牙",  
            showCancel: false,  
          });  
        },  
      });  
    },  
    getBluetoothDevices() {  
      var that = this;  
      uni.showLoading({  
        title: "正在搜索",  
        icon: "loading",  
      });  
      that.isScanning = true;  
      uni.startBluetoothDevicesDiscovery({  
        success: function (res) {  
          console.log(res);  
          setTimeout(function () {  
            // 不设置延迟获取的servers为空数组  
            uni.getBluetoothDevices({  
              success: function (res) {  
                var devices = [];  
                var num = 0;  
                for (var i = 0; i < res.devices.length; ++i) {  
                  if (  
                    res.devices[i].name != "未知设备"  
                  ) {  
                    devices[num] = res.devices[i];  
                    num++;  
                  }  
                }  
                that.list = devices;  
                that.isScanning = false;  
                uni.hideLoading();  
                uni.stopPullDownRefresh();  
                uni.stopBluetoothDevicesDiscovery({  
                  success: function (res) {  
                    console.log("停止搜索蓝牙");  
                    that.isScanning = false;  
                    uni.hideLoading();  
                  },  
                });  
              },  
            });  
          }, 5000);  
        },  
      });  
    },  
    bindViewTap(item) {  
      var that = this;  
      uni.showLoading({  
        title: "正在连接",  
      });  

      var main = plus.android.runtimeMainActivity();  
      var BluetoothAdapter = plus.android.importClass(  
        "android.bluetooth.BluetoothAdapter"  
      );  
      var UUID = plus.android.importClass("java.util.UUID");  
      var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
      var BAdapter = BluetoothAdapter.getDefaultAdapter();  
      var device = BAdapter.getRemoteDevice(item.deviceId);  
      plus.android.importClass(device);  
      var bluetoothSocket =  
        device.createInsecureRfcommSocketToServiceRecord(uuid);  
      plus.android.importClass(bluetoothSocket);  
      bluetoothSocket.connect();  
      console.log("连接:", bluetoothSocket.isConnected());  
      if (bluetoothSocket.isConnected()) {  
        that.openControl();  
        that.BLEInformation.deviceId = item.deviceId;  
        that.BLEInformation.name = item.name;  
        that.$forceUpdate();  
        console.log("that.BLEInformation:", that.BLEInformation);  
      }  
    },  
    openControl() {  
      // 连接成功后打印  
      uni.hideLoading();  
      const that = this;  
      uni.showModal({  
        title: "提示",  
        content: "蓝牙设备连接成功,是否确认打印",  
        success(res) {  
          if (res.confirm) {  
            that.submitPrinte();  
          }  
        },  
      });  
    },  
  },  
};  
</script>  

<style scoped lang="scss">  
.btncss {  
  background-color: white;  
  padding-inline: 20rpx;  
  width: 100%;  
  padding-top: 30rpx;  
  padding-bottom: 50rpx;  
  box-shadow: 2px 2px 4px 4px rgba(223, 223, 223, 0.5);  
  z-index: 9999;  
}  

.linkcss {  
  border: 2px solid #54bec2;  
  padding: 10px;  
  margin: 10px;  
}  

.button {  
  margin-top: 20px;  
  margin-bottom: 20px;  
  width: 70%;  
  background-color: #54bec2;  
  color: white;  
  border-radius: 98rpx;  
  background: bg_red;  
}  

/* 按下变颜色 */  
.hover {  
  background: #dcdcdc;  
}  

.device_list {  
  height: auto;  
  margin-left: 20rpx;  
  margin-right: 20rpx;  
  margin-top: 10px;  
  margin-bottom: 20px;  
  /* border: 1px solid #EEE; */  
  width: auto;  
}  

.td {  
  display: flex;  
  align-items: center;  
  justify-content: center;  
  margin-top: 10px;  
}  
.item {  
  display: block;  
  background-color: white;  
  border-radius: 18rpx;  
  margin-bottom: 16rpx;  
  padding: 8px;  
}  

.item_hover {  
  background-color: rgba(0, 0, 0, 0.1);  
}  

.block {  
  display: block;  
  color: #ffffff;  
  padding: 5px;  
}  

.button::after {  
  border-width: 0px;  
}  

.sign_step > view::after {  
  // 对钩的三角行底色  
  position: absolute;  
  right: 0;  
  top: 0;  
  width: 0;  
  height: 0;  
  content: "";  
  border: 16px solid;  
  border-color: #70cad3 #70cad3 transparent transparent;  
  border-bottom-right-radius: 2px;  
}  

.sign_step {  
  position: relative;  
  border: 2px solid #54bec2;  
}  

.sign_step > view::before {  
  // 对钩样式  
  position: absolute;  
  right: 2px;  
  top: 4px;  
  z-index: 1;  
  width: 10px;  
  height: 5px;  
  content: "";  
  background: transparent;  
  border: 2px solid white;  
  border-top: none;  
  border-right: none;  
  -webkit-transform: rotate(-55deg);  
  -ms-transform: rotate(-55deg);  
  transform: rotate(-55deg);  
}  
</style>  
收起阅读 »

uni-app使用经典蓝牙串口通信方案



    data() {  
            return {  
                bluetooth: 1, //1:打开蓝牙  2:关闭蓝牙  
                turnOnBluetooth: "打开蓝牙", //打开蓝牙  
                turnOffBluetooth: "关闭蓝牙", //关闭蓝牙  
                backgroundColor: "#cecece", //搜索蓝牙按钮背景颜色  

                title: 'Hello',  
                searchLoadingTxt: '',  
                isBlueOk: false,  
                bluetimestoper: null,  
                startchecktimer: null,  
                timeoutOfBlueScanFailure30s: 300000,  
                baseList: [],  
                bluetoothIndex: [],  
                targetDeviceName: '',  
                _deviceId: '', //蓝牙deviceId  
                pairedList: [], //已配对蓝牙  
                pairedLists: [], //已配对蓝牙集合  
                pairedHeight: 0, //已配对蓝牙显示高度  
                unpairedList: [], //未配对蓝牙  
                unpairedHeight: 0, //未配对蓝牙显示高度  
                bluetoothSocket: {},  
            }  
        }  

            //删除已配对设备  
            removePaire(index) {  
                var that = this;  
                uni.showModal({  
                    title: "提示",  
                    content: "是否删除设备",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 确定删除设备  
                        if (res.confirm) {  
                            var address = uni.getStorageSync("printerSelected").address;  
                            console.log("已选中蓝牙地址:" + address + " 删除蓝牙地址:" + that.pairedList[index].address);  
                            if (that.pairedList[index].address == address) {  
                                // that.pairedList[0].isSelected=1;  
                                uni.setStorageSync("printerSelected", "");  
                            }  
                            for (var i = 0; i < that.pairedLists.length; i++) {  
                                if (that.pairedLists[i].getAddress() == that.pairedList[index].address) {  
                                    that.pairedLists[i].removeBond();  
                                }  
                            }  
                            that.pairedList.splice(index, 1);  
                            //存储打印机  
                            // uni.setStorageSync("pairedList",that.pairedList);  
                        } else {  
                            console.log("取消删除设备");  
                        }  
                    }  
                })  
                return false;  
            },  

            //设置已选中蓝牙  
            setSelectedPaired(paired) {  
                console.log('paired', paired)  
                var that = this;  
                for (var i = 0; i < that.pairedList.length; i++) {  
                    if (that.pairedList[i].address == paired.address) {  
                        that.pairedList[i].isSelected = 1;  
                    } else {  
                        that.pairedList[i].isSelected = 0;  
                    }  
                }  
                uni.showLoading({  
                    title:'正在建立连接'  
                })  
                uni.navigateTo({  
                    url:`detail?name=${paired.name}&address=${paired.address}`  
                })  

                paired.isSelected = 1;  
                //存储已选择打印机  
                uni.setStorageSync("printerSelected", paired);  
                //存储打印机  
                // uni.setStorageSync("pairedList",that.pairedList);  
            },  

            //判断蓝牙打开状态  
            bluetoothStatus() {  
                var that = this;  
                const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                const blueadapter = BluetoothAdapter.getDefaultAdapter(); //拿到默认蓝牙适配器方法  
                if (blueadapter) {  
                    // 判断蓝牙是否开启  
                    if (blueadapter.isEnabled()) {  
                        // 开启  
                        that.bluetooth = 0;  
                        that.backgroundColor = "red";  

                        var yilianjie = uni.getStorageSync("printerSelected");  
                        var selectAddress = "";  
                        if (yilianjie) {  
                            selectAddress = yilianjie.address;  
                        }  
                        // console.log("已选中地址:"+selectAddress);  

                        //获取手机已配对蓝牙  
                        var lists = blueadapter.getBondedDevices();  
                        plus.android.importClass(lists);  
                        var iterator = lists.iterator();  
                        plus.android.importClass(iterator);  
                        while (iterator.hasNext()) {  
                            var device = iterator.next();  
                            that.pairedLists.push(device);  

                            plus.android.importClass(device);  
                            that.pairedList.push({  
                                name: device.getName(),  
                                address: device.getAddress(),  
                                isSelected: selectAddress == device.getAddress() ? '1' : '0'  
                            })  
                            // console.log(device.getName()+" ###########  "+ device.getAddress());  
                        }  

                        //显示存储的已配对蓝牙  
                        // this.pairedList = uni.getStorageSync("pairedList");  
                    } else {  
                        // 关闭  
                        this.bluetooth = 1;  
                        this.backgroundColor = "#cecece";  
                        this.pairedList = [];  
                    }  
                    this.unpairedList = [];  
                }  
            },  

            //打开蓝牙  
            openBluetooth() {  
                var that = this;  
                // 弹出提示框  
                uni.showModal({  
                    title: "提示",  
                    content: "蓝牙尚未打开,是否打开蓝牙",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 点击确定后通过系统打开蓝牙  
                        if (res.confirm) {  
                            const BluetoothAdapter = plus.android.importClass(  
                            'android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                            const blueadapter = BluetoothAdapter.getDefaultAdapter();  
                            if (blueadapter != null) {  
                                that.bluetooth = 0;  
                                that.backgroundColor = "#8A2BCF";  
                                //显示存储的已配对蓝牙  
                                // that.pairedList = uni.getStorageSync("pairedList");  
                                blueadapter.enable();  

                                setTimeout(function() {  
                                    that.bluetoothStatus();  
                                }, 2000)  
                            }  
                        } else {  
                            // 点击取消什么也不做  
                            console.log("取消打开蓝牙");  
                        }  
                    }  
                })  
            },  

            //关闭蓝牙  
            closeBluetooth() {  
                var that = this;  
                // 弹出提示框  
                uni.showModal({  
                    title: "提示",  
                    content: "蓝牙已打开,是否关闭蓝牙",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 点击确定后通过系统打开蓝牙  
                        if (res.confirm) {  
                            const BluetoothAdapter = plus.android.importClass(  
                            'android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                            const blueadapter = BluetoothAdapter.getDefaultAdapter();  
                            if (blueadapter != null) {  
                                that.bluetooth = 1;  
                                that.backgroundColor = "#cecece";  
                                that.pairedList = [];  
                                that.unpairedList = [];  
                                uni.setStorageSync("printerSelected", "");  
                                return blueadapter.disable();  
                            }  
                        } else {  
                            // 点击取消什么也不做  
                            console.log("取消关闭蓝牙");  
                        }  
                    }  
                })  
            },  

            //点击打开/关闭蓝牙按钮  
            blueTooth() {  
                if (this.bluetooth == 1) {  
                    console.log("打开蓝牙");  
                    this.openBluetooth();  
                } else {  
                    console.log("关闭蓝牙");  
                    this.closeBluetooth();  
                }  
            },  

            //初始化蓝牙模块  
            openBluetoothAdapter() {  
                //未打开蓝牙点击搜索蓝牙提示弹窗  
                if (this.bluetooth == 1) {  
                    uni.showToast({  
                        title: "请先打开蓝牙",  
                        icon: "error"  
                    })  
                    return;  
                }  
                let system = uni.getSystemInfoSync(); // 获取系统信息  
                if (system.platform === 'android') { // 判断平台  
                    var that = this;  
                    var context = plus.android.importClass("android.content.Context");  
                    var locationManager = plus.android.importClass("android.location.LocationManager");  
                    var main = plus.android.runtimeMainActivity();  
                    var mainSvr = main.getSystemService(context.LOCATION_SERVICE);  
                    // 定位检测  
                    if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {  
                        uni.showModal({  
                            title: "提示",  
                            content: "请打开定位服务功能",  
                            showCancel: false, // 不显示取消按钮  
                            success() {  
                                if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {  
                                    var Intent = plus.android.importClass('android.content.Intent');  
                                    var Settings = plus.android.importClass('android.provider.Settings');  
                                    var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
                                    main.startActivity(intent); // 打开系统设置GPS服务页面  
                                } else {  
                                    console.log('GPS功能已开启');  
                                }  
                            }  
                        });  
                        return false  
                    } else {  
                        console.log('GPS功能已开启');  
                        that.searchDevices()  
                        return true  
                    }  
                }  
            },  

            //搜索蓝牙  
            searchDevices() {  
                var that = this;  
                that.unpairedList = []; //未配对  
                // that.pairedList = [];    //已配对  

                //取内存里面已配对的蓝牙  
                // that.pairedList = uni.getStorageSync("pairedList");  

                //打开蓝牙模块  
                uni.openBluetoothAdapter({  
                    success(res) {  
                        console.log("蓝牙模块:", res);  
                        //获取本机蓝牙适配器状态  
                        uni.getBluetoothAdapterState({  
                            success: function(res) {  
                                console.log("蓝牙适配器状态:", res);  
                                if (res.available) {  
                                    //开始搜寻附近的蓝牙外围设备  
                                    uni.startBluetoothDevicesDiscovery({  
                                        success(res) {  
                                            var main = plus.android.runtimeMainActivity();  
                                            var IntentFilter = plus.android.importClass(  
                                                'android.content.IntentFilter');  
                                            var BluetoothAdapter = plus.android.importClass(  
                                                "android.bluetooth.BluetoothAdapter");  
                                            var BluetoothDevice = plus.android.importClass(  
                                                "android.bluetooth.BluetoothDevice");  
                                            var BAdapter = BluetoothAdapter  
                                        .getDefaultAdapter();  

                                            if (BAdapter != null && !BAdapter.isEnabled()) {  
                                                let _intent = plus.android.importClass(  
                                                    'android.content.Intent');  
                                                let intent = new _intent(blue_client  
                                                    .ACTION_REQUEST_ENABLE);  
                                                main.startActivityForResult(intent, 200);  
                                            }  

                                            uni.showLoading({  
                                                title: "开始搜索设备",  
                                            })  

                                            //获取本机蓝牙信息  
                                            // var name = BAdapter.getName();  
                                            // var address = BAdapter.getAddress();  
                                            // console.log("本机蓝牙名称:"+name+" 本机蓝牙地址:"+address);  

                                            var filter = new IntentFilter();  
                                            var bdevice = new BluetoothDevice();  
                                            BAdapter.startDiscovery(); //开启搜索    
                                            var receiver;  
                                            receiver = plus.android.implements(  
                                                'io.dcloud.android.content.BroadcastReceiver', {  
                                                    onReceive: function(context,  
                                                    intent) { //实现onReceiver回调函数    
                                                        plus.android.importClass(  
                                                            intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                                                        if (intent.getAction() ==  
                                                            "android.bluetooth.adapter.action.DISCOVERY_FINISHED"  
                                                            ) {  
                                                            main.unregisterReceiver(  
                                                                receiver); //取消监听  

                                                            console.log("搜索结束");  
                                                            console.log(that  
                                                                .unpairedList);  
                                                            // console.log(that.pairedList);  
                                                            //把已配对的蓝牙存内存  
                                                            // uni.setStorageSync("pairedList",that.pairedList);  
                                                            uni.hideLoading();  
                                                        } else {  
                                                            if (intent  
                                                                .getParcelableExtra(  
                                                                    BluetoothDevice  
                                                                    .EXTRA_DEVICE)  
                                                                .getBondState() === 10  
                                                                ) {  
                                                                var y = 0;  
                                                                for (let x = 0; x <  
                                                                    that.unpairedList  
                                                                    .length; x++) {  
                                                                    if (that  
                                                                        .unpairedList[  
                                                                            x]  
                                                                        .address ==  
                                                                        intent  
                                                                        .getParcelableExtra(  
                                                                            BluetoothDevice  
                                                                            .EXTRA_DEVICE  
                                                                            )  
                                                                        .getAddress()  
                                                                        ) {  
                                                                        y++;  
                                                                    }  
                                                                }  
                                                                if (y > 0) {  
                                                                    y = 0;  
                                                                } else {  
                                                                    that.unpairedList  
                                                                        .push({  
                                                                            name: intent  
                                                                                .getParcelableExtra(  
                                                                                    BluetoothDevice  
                                                                                    .EXTRA_DEVICE  
                                                                                    )  
                                                                                .getName(),  
                                                                            address: intent  
                                                                                .getParcelableExtra(  
                                                                                    BluetoothDevice  
                                                                                    .EXTRA_DEVICE  
                                                                                    )  
                                                                                .getAddress()  
                                                                        })  
                                                                }  
                                                            }  

                                                        }  
                                                    }  
                                                });  
                                            filter.addAction(bdevice.ACTION_FOUND);  
                                            filter.addAction(BAdapter  
                                            .ACTION_DISCOVERY_STARTED);  
                                            filter.addAction(BAdapter  
                                                .ACTION_DISCOVERY_FINISHED);  
                                            filter.addAction(BAdapter.ACTION_STATE_CHANGED);  
                                            main.registerReceiver(receiver, filter); //注册监听  
                                        }  
                                    })  
                                }  
                            },  
                        })  
                    }  
                })  
            },  

            //建立连接  
            createBLEConnection(mac_address) {  
                // mac_address为获取到蓝牙数据中的address字段  
                var main = plus.android.runtimeMainActivity();  
                var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  
                var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");  
                var UUID = plus.android.importClass("java.util.UUID");  
                var uuid = UUID.fromString("00001101-0000-1000-8000-00805f9B34FB");  
                // this.bluetoothSocket = BluetoothDevice.createRfcommSocketToServiceRecord(uuid)  
                // console.log('bluetoothSocket',this.bluetoothSocket)  
                var BAdapter = BluetoothAdapter.getDefaultAdapter();  
                var device = BAdapter.getRemoteDevice(mac_address);  
                plus.android.importClass(device);  
                var bdevice = new BluetoothDevice();  
                var that = this;  
                //判断是否配对    
                if (device.getBondState() == bdevice.BOND_NONE) {  
                    console.log("未配对蓝牙设备:" + device.getName() + '    ' + device.getAddress());  
                    //参数如果跟取得的mac地址一样就配对    
                    if (mac_address == device.getAddress()) {  
                        // console.log("111")  
                        if (device.createBond()) { //配对命令.createBond()   
                            console.log("配对成功")  
                            var cha = setInterval(function() {  
                                if (device.getBondState() == bdevice.BOND_BONDED) {  
                                    clearInterval(cha);  
                                    //删除未配对蓝牙,添加到已配对  
                                    for (var i = 0; i < that.unpairedList.length; i++) {  
                                        if (that.unpairedList[i].address == mac_address) {  
                                            that.pairedList.push(that.unpairedList[i]);  
                                            that.unpairedList.splice(i, 1);  
                                            break;  
                                        }  
                                    }  
                                }  
                            }, 1000)  
                        }  
                    }  
                }  
            },  
        },  
继续阅读 »


    data() {  
            return {  
                bluetooth: 1, //1:打开蓝牙  2:关闭蓝牙  
                turnOnBluetooth: "打开蓝牙", //打开蓝牙  
                turnOffBluetooth: "关闭蓝牙", //关闭蓝牙  
                backgroundColor: "#cecece", //搜索蓝牙按钮背景颜色  

                title: 'Hello',  
                searchLoadingTxt: '',  
                isBlueOk: false,  
                bluetimestoper: null,  
                startchecktimer: null,  
                timeoutOfBlueScanFailure30s: 300000,  
                baseList: [],  
                bluetoothIndex: [],  
                targetDeviceName: '',  
                _deviceId: '', //蓝牙deviceId  
                pairedList: [], //已配对蓝牙  
                pairedLists: [], //已配对蓝牙集合  
                pairedHeight: 0, //已配对蓝牙显示高度  
                unpairedList: [], //未配对蓝牙  
                unpairedHeight: 0, //未配对蓝牙显示高度  
                bluetoothSocket: {},  
            }  
        }  

            //删除已配对设备  
            removePaire(index) {  
                var that = this;  
                uni.showModal({  
                    title: "提示",  
                    content: "是否删除设备",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 确定删除设备  
                        if (res.confirm) {  
                            var address = uni.getStorageSync("printerSelected").address;  
                            console.log("已选中蓝牙地址:" + address + " 删除蓝牙地址:" + that.pairedList[index].address);  
                            if (that.pairedList[index].address == address) {  
                                // that.pairedList[0].isSelected=1;  
                                uni.setStorageSync("printerSelected", "");  
                            }  
                            for (var i = 0; i < that.pairedLists.length; i++) {  
                                if (that.pairedLists[i].getAddress() == that.pairedList[index].address) {  
                                    that.pairedLists[i].removeBond();  
                                }  
                            }  
                            that.pairedList.splice(index, 1);  
                            //存储打印机  
                            // uni.setStorageSync("pairedList",that.pairedList);  
                        } else {  
                            console.log("取消删除设备");  
                        }  
                    }  
                })  
                return false;  
            },  

            //设置已选中蓝牙  
            setSelectedPaired(paired) {  
                console.log('paired', paired)  
                var that = this;  
                for (var i = 0; i < that.pairedList.length; i++) {  
                    if (that.pairedList[i].address == paired.address) {  
                        that.pairedList[i].isSelected = 1;  
                    } else {  
                        that.pairedList[i].isSelected = 0;  
                    }  
                }  
                uni.showLoading({  
                    title:'正在建立连接'  
                })  
                uni.navigateTo({  
                    url:`detail?name=${paired.name}&address=${paired.address}`  
                })  

                paired.isSelected = 1;  
                //存储已选择打印机  
                uni.setStorageSync("printerSelected", paired);  
                //存储打印机  
                // uni.setStorageSync("pairedList",that.pairedList);  
            },  

            //判断蓝牙打开状态  
            bluetoothStatus() {  
                var that = this;  
                const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                const blueadapter = BluetoothAdapter.getDefaultAdapter(); //拿到默认蓝牙适配器方法  
                if (blueadapter) {  
                    // 判断蓝牙是否开启  
                    if (blueadapter.isEnabled()) {  
                        // 开启  
                        that.bluetooth = 0;  
                        that.backgroundColor = "red";  

                        var yilianjie = uni.getStorageSync("printerSelected");  
                        var selectAddress = "";  
                        if (yilianjie) {  
                            selectAddress = yilianjie.address;  
                        }  
                        // console.log("已选中地址:"+selectAddress);  

                        //获取手机已配对蓝牙  
                        var lists = blueadapter.getBondedDevices();  
                        plus.android.importClass(lists);  
                        var iterator = lists.iterator();  
                        plus.android.importClass(iterator);  
                        while (iterator.hasNext()) {  
                            var device = iterator.next();  
                            that.pairedLists.push(device);  

                            plus.android.importClass(device);  
                            that.pairedList.push({  
                                name: device.getName(),  
                                address: device.getAddress(),  
                                isSelected: selectAddress == device.getAddress() ? '1' : '0'  
                            })  
                            // console.log(device.getName()+" ###########  "+ device.getAddress());  
                        }  

                        //显示存储的已配对蓝牙  
                        // this.pairedList = uni.getStorageSync("pairedList");  
                    } else {  
                        // 关闭  
                        this.bluetooth = 1;  
                        this.backgroundColor = "#cecece";  
                        this.pairedList = [];  
                    }  
                    this.unpairedList = [];  
                }  
            },  

            //打开蓝牙  
            openBluetooth() {  
                var that = this;  
                // 弹出提示框  
                uni.showModal({  
                    title: "提示",  
                    content: "蓝牙尚未打开,是否打开蓝牙",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 点击确定后通过系统打开蓝牙  
                        if (res.confirm) {  
                            const BluetoothAdapter = plus.android.importClass(  
                            'android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                            const blueadapter = BluetoothAdapter.getDefaultAdapter();  
                            if (blueadapter != null) {  
                                that.bluetooth = 0;  
                                that.backgroundColor = "#8A2BCF";  
                                //显示存储的已配对蓝牙  
                                // that.pairedList = uni.getStorageSync("pairedList");  
                                blueadapter.enable();  

                                setTimeout(function() {  
                                    that.bluetoothStatus();  
                                }, 2000)  
                            }  
                        } else {  
                            // 点击取消什么也不做  
                            console.log("取消打开蓝牙");  
                        }  
                    }  
                })  
            },  

            //关闭蓝牙  
            closeBluetooth() {  
                var that = this;  
                // 弹出提示框  
                uni.showModal({  
                    title: "提示",  
                    content: "蓝牙已打开,是否关闭蓝牙",  
                    showCancel: true,  
                    cancelText: "取消",  
                    confirmText: "确定",  
                    success(res) {  
                        // 点击确定后通过系统打开蓝牙  
                        if (res.confirm) {  
                            const BluetoothAdapter = plus.android.importClass(  
                            'android.bluetooth.BluetoothAdapter'); // 引入Java 蓝牙类  
                            const blueadapter = BluetoothAdapter.getDefaultAdapter();  
                            if (blueadapter != null) {  
                                that.bluetooth = 1;  
                                that.backgroundColor = "#cecece";  
                                that.pairedList = [];  
                                that.unpairedList = [];  
                                uni.setStorageSync("printerSelected", "");  
                                return blueadapter.disable();  
                            }  
                        } else {  
                            // 点击取消什么也不做  
                            console.log("取消关闭蓝牙");  
                        }  
                    }  
                })  
            },  

            //点击打开/关闭蓝牙按钮  
            blueTooth() {  
                if (this.bluetooth == 1) {  
                    console.log("打开蓝牙");  
                    this.openBluetooth();  
                } else {  
                    console.log("关闭蓝牙");  
                    this.closeBluetooth();  
                }  
            },  

            //初始化蓝牙模块  
            openBluetoothAdapter() {  
                //未打开蓝牙点击搜索蓝牙提示弹窗  
                if (this.bluetooth == 1) {  
                    uni.showToast({  
                        title: "请先打开蓝牙",  
                        icon: "error"  
                    })  
                    return;  
                }  
                let system = uni.getSystemInfoSync(); // 获取系统信息  
                if (system.platform === 'android') { // 判断平台  
                    var that = this;  
                    var context = plus.android.importClass("android.content.Context");  
                    var locationManager = plus.android.importClass("android.location.LocationManager");  
                    var main = plus.android.runtimeMainActivity();  
                    var mainSvr = main.getSystemService(context.LOCATION_SERVICE);  
                    // 定位检测  
                    if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {  
                        uni.showModal({  
                            title: "提示",  
                            content: "请打开定位服务功能",  
                            showCancel: false, // 不显示取消按钮  
                            success() {  
                                if (!mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)) {  
                                    var Intent = plus.android.importClass('android.content.Intent');  
                                    var Settings = plus.android.importClass('android.provider.Settings');  
                                    var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
                                    main.startActivity(intent); // 打开系统设置GPS服务页面  
                                } else {  
                                    console.log('GPS功能已开启');  
                                }  
                            }  
                        });  
                        return false  
                    } else {  
                        console.log('GPS功能已开启');  
                        that.searchDevices()  
                        return true  
                    }  
                }  
            },  

            //搜索蓝牙  
            searchDevices() {  
                var that = this;  
                that.unpairedList = []; //未配对  
                // that.pairedList = [];    //已配对  

                //取内存里面已配对的蓝牙  
                // that.pairedList = uni.getStorageSync("pairedList");  

                //打开蓝牙模块  
                uni.openBluetoothAdapter({  
                    success(res) {  
                        console.log("蓝牙模块:", res);  
                        //获取本机蓝牙适配器状态  
                        uni.getBluetoothAdapterState({  
                            success: function(res) {  
                                console.log("蓝牙适配器状态:", res);  
                                if (res.available) {  
                                    //开始搜寻附近的蓝牙外围设备  
                                    uni.startBluetoothDevicesDiscovery({  
                                        success(res) {  
                                            var main = plus.android.runtimeMainActivity();  
                                            var IntentFilter = plus.android.importClass(  
                                                'android.content.IntentFilter');  
                                            var BluetoothAdapter = plus.android.importClass(  
                                                "android.bluetooth.BluetoothAdapter");  
                                            var BluetoothDevice = plus.android.importClass(  
                                                "android.bluetooth.BluetoothDevice");  
                                            var BAdapter = BluetoothAdapter  
                                        .getDefaultAdapter();  

                                            if (BAdapter != null && !BAdapter.isEnabled()) {  
                                                let _intent = plus.android.importClass(  
                                                    'android.content.Intent');  
                                                let intent = new _intent(blue_client  
                                                    .ACTION_REQUEST_ENABLE);  
                                                main.startActivityForResult(intent, 200);  
                                            }  

                                            uni.showLoading({  
                                                title: "开始搜索设备",  
                                            })  

                                            //获取本机蓝牙信息  
                                            // var name = BAdapter.getName();  
                                            // var address = BAdapter.getAddress();  
                                            // console.log("本机蓝牙名称:"+name+" 本机蓝牙地址:"+address);  

                                            var filter = new IntentFilter();  
                                            var bdevice = new BluetoothDevice();  
                                            BAdapter.startDiscovery(); //开启搜索    
                                            var receiver;  
                                            receiver = plus.android.implements(  
                                                'io.dcloud.android.content.BroadcastReceiver', {  
                                                    onReceive: function(context,  
                                                    intent) { //实现onReceiver回调函数    
                                                        plus.android.importClass(  
                                                            intent); //通过intent实例引入intent类,方便以后的‘.’操作  
                                                        if (intent.getAction() ==  
                                                            "android.bluetooth.adapter.action.DISCOVERY_FINISHED"  
                                                            ) {  
                                                            main.unregisterReceiver(  
                                                                receiver); //取消监听  

                                                            console.log("搜索结束");  
                                                            console.log(that  
                                                                .unpairedList);  
                                                            // console.log(that.pairedList);  
                                                            //把已配对的蓝牙存内存  
                                                            // uni.setStorageSync("pairedList",that.pairedList);  
                                                            uni.hideLoading();  
                                                        } else {  
                                                            if (intent  
                                                                .getParcelableExtra(  
                                                                    BluetoothDevice  
                                                                    .EXTRA_DEVICE)  
                                                                .getBondState() === 10  
                                                                ) {  
                                                                var y = 0;  
                                                                for (let x = 0; x <  
                                                                    that.unpairedList  
                                                                    .length; x++) {  
                                                                    if (that  
                                                                        .unpairedList[  
                                                                            x]  
                                                                        .address ==  
                                                                        intent  
                                                                        .getParcelableExtra(  
                                                                            BluetoothDevice  
                                                                            .EXTRA_DEVICE  
                                                                            )  
                                                                        .getAddress()  
                                                                        ) {  
                                                                        y++;  
                                                                    }  
                                                                }  
                                                                if (y > 0) {  
                                                                    y = 0;  
                                                                } else {  
                                                                    that.unpairedList  
                                                                        .push({  
                                                                            name: intent  
                                                                                .getParcelableExtra(  
                                                                                    BluetoothDevice  
                                                                                    .EXTRA_DEVICE  
                                                                                    )  
                                                                                .getName(),  
                                                                            address: intent  
                                                                                .getParcelableExtra(  
                                                                                    BluetoothDevice  
                                                                                    .EXTRA_DEVICE  
                                                                                    )  
                                                                                .getAddress()  
                                                                        })  
                                                                }  
                                                            }  

                                                        }  
                                                    }  
                                                });  
                                            filter.addAction(bdevice.ACTION_FOUND);  
                                            filter.addAction(BAdapter  
                                            .ACTION_DISCOVERY_STARTED);  
                                            filter.addAction(BAdapter  
                                                .ACTION_DISCOVERY_FINISHED);  
                                            filter.addAction(BAdapter.ACTION_STATE_CHANGED);  
                                            main.registerReceiver(receiver, filter); //注册监听  
                                        }  
                                    })  
                                }  
                            },  
                        })  
                    }  
                })  
            },  

            //建立连接  
            createBLEConnection(mac_address) {  
                // mac_address为获取到蓝牙数据中的address字段  
                var main = plus.android.runtimeMainActivity();  
                var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  
                var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");  
                var UUID = plus.android.importClass("java.util.UUID");  
                var uuid = UUID.fromString("00001101-0000-1000-8000-00805f9B34FB");  
                // this.bluetoothSocket = BluetoothDevice.createRfcommSocketToServiceRecord(uuid)  
                // console.log('bluetoothSocket',this.bluetoothSocket)  
                var BAdapter = BluetoothAdapter.getDefaultAdapter();  
                var device = BAdapter.getRemoteDevice(mac_address);  
                plus.android.importClass(device);  
                var bdevice = new BluetoothDevice();  
                var that = this;  
                //判断是否配对    
                if (device.getBondState() == bdevice.BOND_NONE) {  
                    console.log("未配对蓝牙设备:" + device.getName() + '    ' + device.getAddress());  
                    //参数如果跟取得的mac地址一样就配对    
                    if (mac_address == device.getAddress()) {  
                        // console.log("111")  
                        if (device.createBond()) { //配对命令.createBond()   
                            console.log("配对成功")  
                            var cha = setInterval(function() {  
                                if (device.getBondState() == bdevice.BOND_BONDED) {  
                                    clearInterval(cha);  
                                    //删除未配对蓝牙,添加到已配对  
                                    for (var i = 0; i < that.unpairedList.length; i++) {  
                                        if (that.unpairedList[i].address == mac_address) {  
                                            that.pairedList.push(that.unpairedList[i]);  
                                            that.unpairedList.splice(i, 1);  
                                            break;  
                                        }  
                                    }  
                                }  
                            }, 1000)  
                        }  
                    }  
                }  
            },  
        },  
收起阅读 »

建议uni-file-picker组件文档里面建议加上单个文件大小限制(maxSize)的属性说明

picker

使用uni-file-picker组件上传文件时,文档里面没有对应文件大小限制的属性,但是看源码里是有一个maxSize属性的,默认值是1。这个属性可以限制文件上传时的大小,超过时组件会弹出对应错误提示。新手使用时,文档里面没有说明,需要看源码才能知道这个属性,所以就建议将这个属性加入到文档中,这样就能很清楚知道对应限制文件大小的方法。

继续阅读 »

使用uni-file-picker组件上传文件时,文档里面没有对应文件大小限制的属性,但是看源码里是有一个maxSize属性的,默认值是1。这个属性可以限制文件上传时的大小,超过时组件会弹出对应错误提示。新手使用时,文档里面没有说明,需要看源码才能知道这个属性,所以就建议将这个属性加入到文档中,这样就能很清楚知道对应限制文件大小的方法。

收起阅读 »

监听实时定位plus.geolocation.watchPosition方法无法关闭,调用 clearWatch()方法也没用

Geolocation
                                         var _this = this  
                     _this.watchId = plus.geolocation.watchPosition(function(position) {  
                        let coords = position.coords;  
                        let address = position.addresses  
                        console.log("获取经纬度信息:", coords.longitude, coords.latitude)  
                        console.log("获取地址信息:", address)  
                        // console.log("返回id" ,plus.geolocation.watchPosition());  
                        _this.checkAdress(coords.latitude, coords.longitude)  
                        _this.longitude = coords.longitude;  
                        _this.latitude = coords.latitude;  
                        _this.dataForm.punchSite = coords.longitude + ',' + coords.latitude  
                        //标记点赋值  
                        _this.markers[0].longitude = coords.longitude;  
                        _this.markers[0].latitude = coords.latitude;  
                        //获取当前当前位置的名称  
                        _this.locationcourier = address;  
                        _this.dataForm.punchSiteName = _this.locationcourier  
                    }, function(e) {  
                        console.log("监听位置变化信息失败:" + e.message);  
                    }, {  
                        'enableHighAccuracy': true,  
                        'geocode': true,  
                        'provider': 'amap',  
                        // 'maximumAge': 3000  
                    });

获取的watchId 不是number 而是个类似于'timer13213123'的字符串,无法,怎么关都关不掉,哪怕退出后台都还在获取地址,打印plus.geolocation.clearWatch() 发现是个undefined ,我人都傻了,这个h5+到底是啥意思,不能用的东西放上来干啥 ,全是bug,有没有大佬遇到过的,给点建议

继续阅读 »
                                         var _this = this  
                     _this.watchId = plus.geolocation.watchPosition(function(position) {  
                        let coords = position.coords;  
                        let address = position.addresses  
                        console.log("获取经纬度信息:", coords.longitude, coords.latitude)  
                        console.log("获取地址信息:", address)  
                        // console.log("返回id" ,plus.geolocation.watchPosition());  
                        _this.checkAdress(coords.latitude, coords.longitude)  
                        _this.longitude = coords.longitude;  
                        _this.latitude = coords.latitude;  
                        _this.dataForm.punchSite = coords.longitude + ',' + coords.latitude  
                        //标记点赋值  
                        _this.markers[0].longitude = coords.longitude;  
                        _this.markers[0].latitude = coords.latitude;  
                        //获取当前当前位置的名称  
                        _this.locationcourier = address;  
                        _this.dataForm.punchSiteName = _this.locationcourier  
                    }, function(e) {  
                        console.log("监听位置变化信息失败:" + e.message);  
                    }, {  
                        'enableHighAccuracy': true,  
                        'geocode': true,  
                        'provider': 'amap',  
                        // 'maximumAge': 3000  
                    });

获取的watchId 不是number 而是个类似于'timer13213123'的字符串,无法,怎么关都关不掉,哪怕退出后台都还在获取地址,打印plus.geolocation.clearWatch() 发现是个undefined ,我人都傻了,这个h5+到底是啥意思,不能用的东西放上来干啥 ,全是bug,有没有大佬遇到过的,给点建议

收起阅读 »

心理管理系统心理测评系统

https://gitee.com/hjq_w/Mental-management-system 出售基于springboot+vue心理管理系统,500

https://gitee.com/hjq_w/Mental-management-system 出售基于springboot+vue心理管理系统,500

【千分符正则】含有小数数值转成千分符

正则 js

1、兼容低于iOS16.4版本

val = "123456.123456";  
let num = val;      // 除小数部分  
let decimal = "";   // 小数部分  
if (val.includes(".")) {  
    num = val.split(".")[0];  
    decimal = `.${val.split(".")[1]}`;  
}  
num = num.replace(/\B(?=(\d{3})+(?!\d))/g, ",");  
val = `${num}${decimal}`;

结果:'123,456.123456'

2、纯正则,不兼容低于iOS16.4版本
来源:https://blog.csdn.net/qq_19309473/article/details/129877569

// iOS16.4+支持  
"123456.123456".replace(/(?<!.*\..*)(\d)(?=(\d{3})+($|\.))/g, '$1,')

结果:'123,456.123456'

↓↓↓ 各位大佬点点赞

继续阅读 »

1、兼容低于iOS16.4版本

val = "123456.123456";  
let num = val;      // 除小数部分  
let decimal = "";   // 小数部分  
if (val.includes(".")) {  
    num = val.split(".")[0];  
    decimal = `.${val.split(".")[1]}`;  
}  
num = num.replace(/\B(?=(\d{3})+(?!\d))/g, ",");  
val = `${num}${decimal}`;

结果:'123,456.123456'

2、纯正则,不兼容低于iOS16.4版本
来源:https://blog.csdn.net/qq_19309473/article/details/129877569

// iOS16.4+支持  
"123456.123456".replace(/(?<!.*\..*)(\d)(?=(\d{3})+($|\.))/g, '$1,')

结果:'123,456.123456'

↓↓↓ 各位大佬点点赞

收起阅读 »

camera 组件需求

Camera

需要相机直接在页面上呈现

需要相机直接在页面上呈现

记录:上架小米应用市场,APP以隐私政策弹窗的形式向用户明示收集使用规则,但未见清晰明示APP收集软件列表被驳回,上架华为应用市场,申请权限未弹框告知目的被驳回问题

隐私政策 华为应用市场 小米应用商店 应用上架

(一)上架小米应用市场被驳回,原因

场景3:APP以隐私政策弹窗的形式向用户明示收集使用规则,但未见清晰明示APP收集软件列表、设备MAC地址等的目的方式范围,用户同意隐私政策后,存在收集软件列表、设备MAC地址的行为。

检测结果: 存在问题

改进建议: APP收集使用个人信息的过程需与其所声明的隐私政策等收集使用规则保持一致。实际收集的个人信息类型、申请打开可收集使用个人信息的权限等与隐
私政策等收集使用规则中相关内容一致,不超出隐私政策等收集使用规则所述范围。

风险信息: APP以隐私政策弹窗的形式向用户明示收集使用规则,但未见清晰明示APP收集读取特定类型传感器列表等的目的方式范围,用户同意隐私政策后,存在收
集读取特定类型传感器列表的行为。

举证信息:
[测试动作] 启动史宾格隐私合规检测
[测试动作] 同意隐私政策
读取特定类型传感器列表

问题一:隐私政策弹窗内未清晰明示APP收集软件列表

解决方式:列举申请权限和目的,类似这样,一一列举

问题二:存在收集读取特定类型传感器列表的行为

原因:使用webview组件,webview组件会在用户进入隐私主页时调用矢量传感器

解决方法:在隐私政策正文内补充获取传感器列表的描述,传感器列表,特定传感器,矢量传感器都可以,只需要您补充关于传感器的描述即可

最后终于上架成功了!!!

(二)上架华为应用市场被驳回,原因

APP在申请敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的名称、服务的具体功能、用途;告知方式不限于弹窗、蒙层、浮窗、或者自定义操作系统权限弹框等,且权限申请使用目的说明不应自动消失。请排查应用内所有权限申请行为,确保均符合要求。

请参考《审核指南》第7.21相关审核要求:https://developer.huawei.com/consumer/cn/doc/app/50104-07#h3-1683701612940-2

解决方式

1、使用监听权限申请API自己处理,官方文档:https://uniapp.dcloud.net.cn/api/system/create-request-permission-listener.html#createrequestpermissionlistener

2、使用官方插件uni-registerRequestPermissionTips:支持android平台全局监听权限的申请。当申请权限时,会在页面顶部显示申请权限的目的。主要解决上架华为应用市场审核要求:APP在调用终端权限时,应同步告知用户申请该权限的目的。

插件地址:https://ext.dcloud.net.cn/plugin?name=uni-registerRequestPermissionTips

3、参考文章:https://ask.dcloud.net.cn/article/40875

继续阅读 »

(一)上架小米应用市场被驳回,原因

场景3:APP以隐私政策弹窗的形式向用户明示收集使用规则,但未见清晰明示APP收集软件列表、设备MAC地址等的目的方式范围,用户同意隐私政策后,存在收集软件列表、设备MAC地址的行为。

检测结果: 存在问题

改进建议: APP收集使用个人信息的过程需与其所声明的隐私政策等收集使用规则保持一致。实际收集的个人信息类型、申请打开可收集使用个人信息的权限等与隐
私政策等收集使用规则中相关内容一致,不超出隐私政策等收集使用规则所述范围。

风险信息: APP以隐私政策弹窗的形式向用户明示收集使用规则,但未见清晰明示APP收集读取特定类型传感器列表等的目的方式范围,用户同意隐私政策后,存在收
集读取特定类型传感器列表的行为。

举证信息:
[测试动作] 启动史宾格隐私合规检测
[测试动作] 同意隐私政策
读取特定类型传感器列表

问题一:隐私政策弹窗内未清晰明示APP收集软件列表

解决方式:列举申请权限和目的,类似这样,一一列举

问题二:存在收集读取特定类型传感器列表的行为

原因:使用webview组件,webview组件会在用户进入隐私主页时调用矢量传感器

解决方法:在隐私政策正文内补充获取传感器列表的描述,传感器列表,特定传感器,矢量传感器都可以,只需要您补充关于传感器的描述即可

最后终于上架成功了!!!

(二)上架华为应用市场被驳回,原因

APP在申请敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的名称、服务的具体功能、用途;告知方式不限于弹窗、蒙层、浮窗、或者自定义操作系统权限弹框等,且权限申请使用目的说明不应自动消失。请排查应用内所有权限申请行为,确保均符合要求。

请参考《审核指南》第7.21相关审核要求:https://developer.huawei.com/consumer/cn/doc/app/50104-07#h3-1683701612940-2

解决方式

1、使用监听权限申请API自己处理,官方文档:https://uniapp.dcloud.net.cn/api/system/create-request-permission-listener.html#createrequestpermissionlistener

2、使用官方插件uni-registerRequestPermissionTips:支持android平台全局监听权限的申请。当申请权限时,会在页面顶部显示申请权限的目的。主要解决上架华为应用市场审核要求:APP在调用终端权限时,应同步告知用户申请该权限的目的。

插件地址:https://ext.dcloud.net.cn/plugin?name=uni-registerRequestPermissionTips

3、参考文章:https://ask.dcloud.net.cn/article/40875

收起阅读 »

星河璀璨,uni-app 亮相华为 HDC2024 开发者大会

鸿蒙 uni-app-x uni-app

2024年6月21日-23日,第六届华为开发者大会(HDC.Together 2024)在东莞松山湖盛大举办,本次盛会重磅发布了万众关注的HarmonyOS NEXT。

作为鸿蒙生态的重要合作伙伴和深度参与者,DCloud CTO 崔红保受邀出席本次大会,并在鸿蒙生态伙伴SDK论坛中发表《uni-app助力开发者快速构建高性能鸿蒙原生应用》的技术演讲,现场反响热烈。

崔红保先从开源指标、插件生态等维度介绍了uni-app的发展现状,以uni-app的功能框架图为例,介绍了uni-app如何在跨平台的过程中,不牺牲平台特色,优雅的调用平台专有能力,真正做到海纳百川、各取所长。

接着,介绍了uni-app的两套鸿蒙化适配方案。

方案一,是对存量uni-app项目的开发者非常友好的webview方案,这套架构是业内主流的Hybrid App架构,即逻辑层、视图层分离架构。老版uni-app在App平台使用的是这套架构,微信等各家小程序使用的也是这套架构。使用本方案,可以帮助开发者快速将之前基于uni-app开发的App、小程序、H5等,快速发布成鸿蒙App,快速入驻鸿蒙生态,抢先接收鸿蒙的流量红利。

方案二,是能获取更高性能、更佳体验的纯原生方案,也就是uni-app x。

每个App跨平台框架诞生时,都曾梦想颠覆原生,但从未成功,原因何在?

uni-app团队有十多年的跨平台框架开发经验,经过漫长的测试和思辨,我们发现关键在于运行时。若想媲美原生,运行时只能且必须也是原生。抛开渲染引擎不谈,业内的rn/weex等框架引入的V8/JS Core等运行环境,导致了逻辑层、视图层在两个进程中的通讯阻塞问题,相比原生开发的逻辑、视图均在一个原生进程中,业内目前的跨平台框架,天生有难以逾越的性能缺陷。

想清楚了这个关键点,跨平台框架就有了新的思路,那就是uni-app x目前的方案:开发态基于Web技术栈进行,但运行时需转化为各平台原生语言。

具体来讲,在web平台和小程序平台,我们将uni-app x编译为JS,这和目前的uni-app基本是一致的。但到了App平台,我们会将JS和Vue代码,编译为对应平台的原生语言。比如iOS平台,我们会将TS编译为swift,在Android平台,我们会将TS编译为Kotlin,到了鸿蒙平台,我们会将TS和Vue编译为arkTS和arkUI。

以uni-app x的鸿蒙化为例,进一步解释:

  1. 开发者依然基于 TS+Vue 的 Web 技术栈来编写代码,编码完毕后,uni-app x 编译器通过 swc 将 TS 和 Vue 代码编译成 arkTS/arkUI;

  2. 编译到鸿蒙开发者工具中的项目,代码已经变成了arkTS/arkUI,那使用的就是arkUI原生渲染,相比webview的渲染,性能更高。同时业务代码转换成arkTS,逻辑和渲染都使用鸿蒙原生,就实现了纯血的鸿蒙App。

  3. 最后,因为开发者在开发态使用的是Vue,用到大量数据响应的机制,所以在运行时,需要实现 arkTS 版的 Vue runtime,从而让开发者的业务数据变化能触发 arkUI 的更新。

使用 uni-app 开发鸿蒙应用,和之前开发各家小程序体验接近。主要编码工作在 HBuilderX 中完成,HBuilderX 支持鸿蒙OS的各种语法提示;编码完成后,将项目运行到鸿蒙开发者工具DevEco Studio,通过 DevEco 完成模拟器测试及hap安装包制作。

鸿蒙时代即将来临,开发鸿蒙的最佳实践是什么?uni-app值得推荐!原因有四,如下图。

面向未来,uni-app团队会持续对鸿蒙开发进行优化,重点会在性能体验、生态支持、开发体验、元服务等维度进行迭代升级。

通过HDC2024华为开发者大会,我们看到华为这次不再是画大饼,鸿蒙真的来了!

uni-app 的鸿蒙版目前处于邀请试用状态,部分开发者的App鸿蒙化适配已接近尾声。下图是基于 uni-app 开发的华为莫塞尔商城的鸿蒙化运行截图,运行体验非常流畅。

支持鸿蒙平台的uni-app Alpha版本,将于7月初面向所有开发者发布,敬请期待。

星河璀璨,基于uni-app加入鸿蒙正当时!

继续阅读 »

2024年6月21日-23日,第六届华为开发者大会(HDC.Together 2024)在东莞松山湖盛大举办,本次盛会重磅发布了万众关注的HarmonyOS NEXT。

作为鸿蒙生态的重要合作伙伴和深度参与者,DCloud CTO 崔红保受邀出席本次大会,并在鸿蒙生态伙伴SDK论坛中发表《uni-app助力开发者快速构建高性能鸿蒙原生应用》的技术演讲,现场反响热烈。

崔红保先从开源指标、插件生态等维度介绍了uni-app的发展现状,以uni-app的功能框架图为例,介绍了uni-app如何在跨平台的过程中,不牺牲平台特色,优雅的调用平台专有能力,真正做到海纳百川、各取所长。

接着,介绍了uni-app的两套鸿蒙化适配方案。

方案一,是对存量uni-app项目的开发者非常友好的webview方案,这套架构是业内主流的Hybrid App架构,即逻辑层、视图层分离架构。老版uni-app在App平台使用的是这套架构,微信等各家小程序使用的也是这套架构。使用本方案,可以帮助开发者快速将之前基于uni-app开发的App、小程序、H5等,快速发布成鸿蒙App,快速入驻鸿蒙生态,抢先接收鸿蒙的流量红利。

方案二,是能获取更高性能、更佳体验的纯原生方案,也就是uni-app x。

每个App跨平台框架诞生时,都曾梦想颠覆原生,但从未成功,原因何在?

uni-app团队有十多年的跨平台框架开发经验,经过漫长的测试和思辨,我们发现关键在于运行时。若想媲美原生,运行时只能且必须也是原生。抛开渲染引擎不谈,业内的rn/weex等框架引入的V8/JS Core等运行环境,导致了逻辑层、视图层在两个进程中的通讯阻塞问题,相比原生开发的逻辑、视图均在一个原生进程中,业内目前的跨平台框架,天生有难以逾越的性能缺陷。

想清楚了这个关键点,跨平台框架就有了新的思路,那就是uni-app x目前的方案:开发态基于Web技术栈进行,但运行时需转化为各平台原生语言。

具体来讲,在web平台和小程序平台,我们将uni-app x编译为JS,这和目前的uni-app基本是一致的。但到了App平台,我们会将JS和Vue代码,编译为对应平台的原生语言。比如iOS平台,我们会将TS编译为swift,在Android平台,我们会将TS编译为Kotlin,到了鸿蒙平台,我们会将TS和Vue编译为arkTS和arkUI。

以uni-app x的鸿蒙化为例,进一步解释:

  1. 开发者依然基于 TS+Vue 的 Web 技术栈来编写代码,编码完毕后,uni-app x 编译器通过 swc 将 TS 和 Vue 代码编译成 arkTS/arkUI;

  2. 编译到鸿蒙开发者工具中的项目,代码已经变成了arkTS/arkUI,那使用的就是arkUI原生渲染,相比webview的渲染,性能更高。同时业务代码转换成arkTS,逻辑和渲染都使用鸿蒙原生,就实现了纯血的鸿蒙App。

  3. 最后,因为开发者在开发态使用的是Vue,用到大量数据响应的机制,所以在运行时,需要实现 arkTS 版的 Vue runtime,从而让开发者的业务数据变化能触发 arkUI 的更新。

使用 uni-app 开发鸿蒙应用,和之前开发各家小程序体验接近。主要编码工作在 HBuilderX 中完成,HBuilderX 支持鸿蒙OS的各种语法提示;编码完成后,将项目运行到鸿蒙开发者工具DevEco Studio,通过 DevEco 完成模拟器测试及hap安装包制作。

鸿蒙时代即将来临,开发鸿蒙的最佳实践是什么?uni-app值得推荐!原因有四,如下图。

面向未来,uni-app团队会持续对鸿蒙开发进行优化,重点会在性能体验、生态支持、开发体验、元服务等维度进行迭代升级。

通过HDC2024华为开发者大会,我们看到华为这次不再是画大饼,鸿蒙真的来了!

uni-app 的鸿蒙版目前处于邀请试用状态,部分开发者的App鸿蒙化适配已接近尾声。下图是基于 uni-app 开发的华为莫塞尔商城的鸿蒙化运行截图,运行体验非常流畅。

支持鸿蒙平台的uni-app Alpha版本,将于7月初面向所有开发者发布,敬请期待。

星河璀璨,基于uni-app加入鸿蒙正当时!

收起阅读 »