Skip to content

使用方法

安卓串口操作UTS原生插件,支持设置串口,波特率,停止位,数据位,校验位,流控以及延迟,支持粘包处理解决分包问题,支持多串口操作,支持无root操作,插件支持uniapp和uniapp x

插件使用注意事项

  • 当前插件为【安卓串口操作原生插件】的2.*版本,支持uniappx
  • 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您只用插件
  • 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例

    https://pan.baidu.com/s/1JTnxZPtxKRNzNx_1uRe_tg?pwd=6imt

联系作者

关注微信公众号可联系作者

多串口使用

插件方法params参数提供了index参数,该参数为串口索引,目前支持1~5,默认为:1,即可同时操作5个串口,如果只操作一个串口index参数可以不传

插件地址

https://ext.dcloud.net.cn/plugin?id=27669

用法

在需要使用插件的页面加载以下代码

js
import * as module from "@/uni_modules/leven-uts-serial"
js
import * as module from "@/uni_modules/leven-uts-serial"

页面内容

vue
<template>
  <view>
    <uni-card title="参数设置">
      <view>
        <button type="primary" @click="selectSerial">选择串口</button>
        <uni-section title="波特率">
          <uni-easyinput v-model="serialParams.baudRate" type="number" placeholder="请输入波特率"></uni-easyinput>
        </uni-section>
        <uni-section title="停止位">
          <uni-easyinput v-model="serialParams.stopBits" type="number" placeholder="请输入停止位"></uni-easyinput>
        </uni-section>
        <uni-section title="数据位">
          <uni-easyinput v-model="serialParams.dataBits" type="number" placeholder="请输入数据位"></uni-easyinput>
        </uni-section>
        <uni-section title="校验位">
          <uni-easyinput v-model="serialParams.parity" type="number" placeholder="请输入校验位"></uni-easyinput>
        </uni-section>
        <uni-section title="流控">
          <uni-easyinput v-model="serialParams.flowCon" type="number" placeholder="请输入流控"></uni-easyinput>
        </uni-section>
        <uni-section title="延迟">
          <uni-easyinput v-model="serialParams.delay" type="number" placeholder="请输入延迟"></uni-easyinput>
        </uni-section>
        <uni-section title="发送内容">
          <uni-easyinput v-model="sendTextContent" placeholder="请输入发送内容"></uni-easyinput>
        </uni-section>
        <uni-section title="发送类别">
          <uni-data-checkbox v-model="sendTextType" :localdata="sendTextTypeList"
            @change="changeSendTextType"></uni-data-checkbox>
        </uni-section>
      </view>
      <view style="flex-direction: row; flex-wrap: wrap;">
        <button type="primary" @click="open">开启串口</button>
        <button type="primary" @click="close">关闭串口</button>
        <button type="primary" @click="sendData">发送数据</button>
      </view>
    </uni-card>

    <!-- 弹窗 -->
    <uni-popup ref="refSelectSerialPop">
      <view style="width: 300px;">
        <uni-card title="请选择串口">
          <button v-for="(item, index) in serialList" :key="index" type="primary"
            @click="selectSerialItem(item)">{{item}}</button>
        </uni-card>
      </view>
    </uni-popup>
  </view>
</template>

<script>
  import * as module from "@/uni_modules/leven-uts-serial"
  export default {
    data() {
      return {
        // 串口参数
        serialParams: {
          // 串口号
          port: "",
          // 波特率
          baudRate: 9600,
          // 停止位
          stopBits: 1,
          // 数据位
          dataBits: 8,
          // 校验位
          parity: 0,
          // 流控
          flowCon: 0,
          //延迟
          delay: 500
        },
        // 串口列表
        serialList: [],
        // 发送的内容
        sendTextContent: "",
        // 当前发送数据的类别
        sendTextType: 0,
        // 发送类别
        sendTextTypeList: [{
          value: 0,
          text: "十六进制"
        }, {
          value: 1,
          text: "ASCII"
        }, {
          value: 2,
          text: "字节"
        }]
      }
    },
    mounted() {
      // 动态开启应用权限
      // this.openAndroidPermission();
      this.$nextTick(() => {
        this.onListener();
      })
    },
    methods: {
      // 发送数据
      sendData() {
        if (this.sendTextContent == "") {
          uni.showToast({
            title: "请输入发送的内容",
            icon: "none"
          })
          return false;
        }

        module.isOpen({
          complete: (res) => {
            if (!res.data.isOpen) {
              uni.showToast({
                title: "请开启串口",
                icon: "none"
              })
              return false;
            }
            this.startSendData();
          }
        })
      },
      // 开始发送数据
      startSendData() {
        let that = this;
        if (this.sendTextType == 0) {
          module.sendHex({
            params: {
              content: this.sendTextContent
            },
            complete: (res) => {
              console.log("发送十六进制数据:" + JSON.stringify(res))
            }
          })
        } else if (this.sendTextType == 1) {
          module.sendText({
            params: {
              content: this.sendTextContent
            },
            complete: (res) => {
              console.log("发送文本数据:" + JSON.stringify(res))
            }
          })
        } else {
          module.sendBytes({
            params: {
              content: this.sendTextContent
            },
            complete: (res) => {
              console.log("发送字节数据:" + JSON.stringify(res))
            }
          })
        }
      },
      //开启串口
      open() {
        let that = this;
        if (this.serialParams.port == "") {
          uni.showToast({
            title: "请选择串口",
            icon: "none"
          })
          return false;
        }
        module.open({
          params: this.serialParams,
          complete: (res) => {
            console.log("开启串口:" + JSON.stringify(res))
          }
        })
      },
      // 关闭串口
      close() {
        let that = this;
        module.close({
          params: {},
          complete: (res) => {
            console.log("关闭串口:" + JSON.stringify(res))
          }
        })
      },
      // 选择串口
      selectSerial() {
        module.getAllDevicesPath({
          complete: (res) => {
            this.serialList = res.data.path;
            if (this.$refs.refSelectSerialPop) {
              this.$refs.refSelectSerialPop.open();
            }
          }
        })
      },
      // 选择结果
      selectSerialItem(port) {
        this.serialParams.port = port;
        if (this.$refs.refSelectSerialPop) {
          this.$refs.refSelectSerialPop.close();
        }
      },
      // 发送类别改变事件
      changeSendTextType(e) {
        this.onListener();
      },
      // 监听数据
      onListener() {
        if (this.sendTextType == 0) {
          //监听十六进制
          this.onListenerHex();
        } else if (this.sendTextType == 1) {
          // 监听ascii
          this.onListenerText();
        } else {
          this.onListenerBytes();
        }
      },
      // 监听十六进制串口消息
      onListenerHex() {
        module.onListenerHex({
          complete: (res) => {
            console.log("十六进制监听:" + JSON.stringify(res))
          }
        })
      },
      // 监听ASCII消息串口消息
      onListenerText() {
        module.onListenerText({
          complete: (res) => {
            console.log("ASCII监听:" + JSON.stringify(res));
          }
        })
      },
      // 监听字节串口消息
      onListenerBytes() {
        module.onListenerBytes({
          complete: (res) => {
            console.log("字节监听:" + JSON.stringify(res));
          }
        })
      },
    }
  }
</script>

<style>
  .content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .logo {
    height: 200rpx;
    width: 200rpx;
    margin-top: 200rpx;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 50rpx;
  }

  .text-area {
    display: flex;
    justify-content: center;
  }

  .title {
    font-size: 36rpx;
    color: #8f8f94;
  }
</style>
vue
<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex:1">
  <!-- #endif -->
    <lux-card title="参数设置">
      <view>
        <button type="primary" @click="selectSerial">选择串口</button>
      </view>
      <lux-section text="波特率" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.baudRate" placeholder="请输入波特率"></rice-input>
      </lux-section>
      <lux-section text="停止位" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.stopBits" placeholder="请输入停止位"></rice-input>
      </lux-section>
      <lux-section text="数据位" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.dataBits" placeholder="请输入数据位"></rice-input>
      </lux-section>
      <lux-section text="校验位" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.parity" placeholder="请输入校验位"></rice-input>
      </lux-section>
      <lux-section text="流控" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.flowCon" placeholder="请输入流控"></rice-input>
      </lux-section>
      <lux-section text="延迟" :padding="'16px 0 0 0'">
        <rice-input v-model="serialParams.delay" placeholder="请输入延迟"></rice-input>
      </lux-section>
      <lux-section text="发送内容" :padding="'16px 0 0 0'">
        <rice-input v-model="sendTextContent" placeholder="请输入发送内容"></rice-input>
      </lux-section>
      <lux-section text="发送类别" :padding="'16px 0 0 0'">
        <rice-radio-group v-model="sendTextType" direction="row" @change="changeSendTextType">
          <rice-radio :value="0" label="十六进制"></rice-radio>
          <rice-radio :value="1" label="ASCII"></rice-radio>
          <rice-radio :value="2" label="字节"></rice-radio>
        </rice-radio-group>
      </lux-section>
      <view style="flex-direction: row; flex-wrap: wrap; margin-top: 10px;">
        <button type="primary" @click="open">开启串口</button>
        <button type="primary" @click="close">关闭串口</button>
        <button type="primary" @click="sendData">发送数据</button>
      </view>
    </lux-card>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
  <!-- 串口选择 -->
  <rice-popup v-model:show="popShow" radius="10">
    <view class="pop-show">
      <view
        style="flex-direction: row; justify-content: center; align-items: center; height: 50px; border-bottom: 1px solid #F2F2F2;">
        <text style="font-size: 16px;">选择串口</text>
      </view>
      <view style="padding: 16px;">
        <rice-radio-group v-model="serialParams.port" icon-position="right" space-between @change="popShow = false">
          <rice-radio style="margin-bottom: 10px;" v-for="(item, index) in serialList" :key="index" :value="item"
            :label="item"></rice-radio>
        </rice-radio-group>
      </view>
    </view>
  </rice-popup>
</template>

<script setup>
  import * as module from "@/uni_modules/leven-uts-serial"

  type serialParamsOptions = {
    // 串口号
    port : string,
    // 波特率
    baudRate : string,
    // 停止位
    stopBits : string,
    // 数据位
    dataBits : string,
    // 校验位
    parity : string,
    // 流控
    flowCon : string,
    //延迟
    delay : string
  }

  //自定义参数
  const serialParams = reactive<serialParamsOptions>({
    port: "",
    baudRate: '9600',
    stopBits: '1',
    dataBits: '8',
    parity: '0',
    flowCon: '0',
    delay: '500'
  })

  //发送内容
  const sendTextContent = ref("")

  //发送类别
  const sendTextType = ref(0)
  //串口列表
  const serialList = ref<string[]>([])
  //选择串口弹窗状态
  const popShow = ref(false)

  //打开串口
  function open() {
    if (serialParams.port == "") {
      uni.showToast({
        title: "请选择串口",
        icon: "none"
      })
      return;
    }

    module.open({
      params: {
        port: serialParams.port,
        baudRate: parseInt(serialParams.baudRate),
        stopBits: parseInt(serialParams.stopBits),
        dataBits: parseInt(serialParams.dataBits),
        parity: parseInt(serialParams.parity),
        flowCon: parseInt(serialParams.flowCon),
        delay: parseInt(serialParams.delay)
      },
      complete: (res) => {
        console.log("开启串口:" + JSON.stringify(res))
      }
    })
  }

  //关闭串口
  function close() {
    module.close({
      params: {},
      complete: (res) => {
        console.log("关闭串口:" + JSON.stringify(res))
      }
    })
  }

  //发送数据
  function sendData() {
    if (sendTextType.value == 0) {
      module.sendHex({
        params: {
          content: sendTextContent.value
        },
        complete: (res) => {
          console.log("发送十六进制数据:" + JSON.stringify(res))
        }
      })
    } else if (sendTextType.value == 1) {
      module.sendText({
        params: {
          content: sendTextContent.value
        },
        complete: (res) => {
          console.log("发送文本数据:" + JSON.stringify(res))
        }
      })
    } else if (sendTextType.value == 2) {
      module.sendBytes({
        params: {
          content: sendTextContent.value
        },
        complete: (res) => {
          console.log("发送字节数据:" + JSON.stringify(res))
        }
      })
    }
  }

  //选择串口
  function selectSerial() {
    module.getAllDevicesPath({
      complete: (res) => {
        let data = res.data;
        let path = data.getArray("path") as string[]
        serialList.value = path;

        //弹出选择串口弹窗
        popShow.value = true
      }
    })
  }

  //监听十六进制数据
  function onListenerHex() {
    module.onListenerHex({
      complete: (res) => {
        console.log("十六进制监听:" + JSON.stringify(res))
      }
    })
  }

  // 监听ASCII消息串口消息
  function onListenerText() {
    module.onListenerText({
      complete: (res) => {
        console.log("ASCII监听:" + JSON.stringify(res));
      }
    })
  }

  // 监听字节串口消息
  function onListenerBytes() {
    module.onListenerBytes({
      complete: (res) => {
        console.log("字节监听:" + JSON.stringify(res));
      }
    })
  }

  //监听数据
  function onListener() {
    if (sendTextType.value == 0) {
      onListenerHex();
    } else if (sendTextType.value == 1) {
      onListenerText();
    } else if (sendTextType.value == 2) {
      onListenerBytes();
    }
  }

  //发送类别的改变事件
  function changeSendTextType() {
    onListener();
  }

  onMounted(() => {
    nextTick(() => {
      onListener();
    })
  })
</script>

<style>
  .pop-show {
    height: 300px;
  }
</style>