一、这台“设备”到底是什么?

先上结论:
这不是手机,是一台 Android 11 + RK3568 方案的工业平板

uni.getSystemInfo() 里藏了什么?

摘几个关键字段:

{
  "deviceBrand": "qingzheng",
  "deviceModel": "F68V1_0",
  "deviceType": "pad",
  "platform": "android",
  "osVersion": "11",
  "system": "Android 11",
  "browserName": "chrome",
  "browserVersion": "83.0.4103.120"
}

几个有意思的点

1️⃣ deviceType = pad,不是 phone

uni-app 在工控设备上通常会识别为 pad,这意味着:

  • rpx 换算会按平板逻辑走
  • 一些手机端的 UI 适配(底部安全区、刘海)可能根本不生效

2️⃣ WebView 是 Chrome 83

Chrome/83.0.4103.120

这是 Android 11 自带的 WebView 版本,偏老,但够用:

  • ✅ 支持 BlobMediaSource
  • ❌ 不支持较新的 Web API(如 VideoEncoder、部分 WebCodecs)

如果你要做前端音视频处理,这里要提前评估。

3️⃣ UA 暴露了“沉浸状态栏”

uni-app (Immersed/24.0)

说明 App 是 沉浸式状态栏,状态栏高度 24px,和 statusBarHeight: 24 完全对得上。


二、getSystemInfo vs getDeviceInfo,到底用哪个?

官方提供了两个 API,很多人会混用,其实它们定位不一样。

uni.getSystemInfo()

👉 应用 + 系统 + 屏幕 + 运行环境

包含:

  • 应用信息:appNameappVersionappWgtVersion
  • uni 编译信息:uniCompileVersionuniRuntimeVersion
  • 屏幕:screenWidthscreenHeightsafeArea
  • 设备:brandplatformsystem

适合用来:

  • 版本灰度控制
  • 屏幕适配
  • 运行时环境诊断

uni.getDeviceInfo()

👉 只关心“设备本身”

{
  "brand": "qingzheng",
  "deviceModel": "F68V1_0",
  "deviceType": "pad",
  "platform": "android"
}

特点:

  • 字段更少
  • 更稳定
  • 不随 App 升级变化

建议:

  • 做设备指纹 / 设备绑定 → 用 getDeviceInfo
  • 做 UI 适配 / 版本判断 → 用 getSystemInfo

三、屏幕参数:533 × 805 是个什么分辨率?

{
  "screenWidth": 533,
  "screenHeight": 805,
  "pixelRatio": 1.5,
  "safeArea": {
    "width": 533,
    "height": 781,
    "top": 24
  }
}

换算成物理分辨率

物理宽 = 533 × 1.5 ≈ 800
物理高 = 805 × 1.5 ≈ 1207

这是典型的 800×1200 类工控屏,竖屏使用。

没有底部安全区

"safeAreaInsets": {
  "top": 24,
  "bottom": 0
}
  • 有状态栏
  • 没有 iPhone 那种 Home Indicator
  • 底部可以直接贴底布局

四、真实问题:大 Blob 怎么往后台传?

设备端经常要上传:

  • 拍照原图
  • 录像片段
  • 日志文件

直接传 Blob:

  • FormData 在某些老 Android WebView 有大小限制
  • 内网环境带宽有限

我们最后选的方案是:

Blob → gzip → Base64 → JSON 接口


五、uni-app 可用的 Blob gzip 工具函数

依赖:pako(gzip 压缩库)

import pako from 'pako'

Blob 转 gzip + Base64

async function blobToGzippedBase64(blob) {
  // 1. Blob → ArrayBuffer
  const arrayBuffer = await blob.arrayBuffer()

  // 2. gzip 压缩
  const compressed = pako.gzip(new Uint8Array(arrayBuffer))

  // 3. ArrayBuffer → Base64
  return arrayBufferToBase64(compressed)
}

ArrayBuffer 转 Base64(兼容老环境)

function arrayBufferToBase64(buffer) {
  let binary = ''
  const bytes = new Uint8Array(buffer)
  for (let i = 0; i < bytes.byteLength; i++) {
    binary += String.fromCharCode(bytes[i])
  }
  return btoa(binary)
}

后端返回后解压回 Blob

function gzippedBase64ToBlob(base64) {
  const binaryString = atob(base64)
  const bytes = new Uint8Array(binaryString.length)
  for (let i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i)
  }

  const decompressed = pako.ungzip(bytes)
  return new Blob([decompressed])
}

实际效果

  • 图片:压缩率 ~60–70%
  • 文本/日志:压缩率 80%+
  • JSON 接口不再担心文件过大

六、几个踩坑提醒

1. deviceId 不能当唯一设备号

"deviceId": "073D949BC69926493E40FF95EC8FC935"

实测:

  • 重装 App → deviceId 会变
  • 工控板子没有 OAID

✅ 正式设备绑定,建议:

  • 序列号 + 型号
  • 或原生插件读 Android ID / MAC(需权限)

2. uni-app X 还没开

"isUniAppX": false

说明当前还是 Vue2 / VUE3 + App 模式,不是 uts 原生。

3. 工控屏别用 rpx 死值

533px 宽,750rpx 会被换算成约 267px 基准
👉 复杂表单建议用 px + flex,避免小数点抖动。


七、总结

这次验机,核心收获是三点:

  1. 工控平板 ≠ 手机

    • pad 模式
    • 老 Chrome 内核
    • 竖屏 + 固定分辨率
  2. API 各司其职

    • 设备识别 → getDeviceInfo
    • 运行环境 → getSystemInfo
  3. 流数据走 gzip

    • Blob + pako + Base64
    • 在老 WebView + 内网环境非常稳
posted on 2026-08-13 15:33  羽丫头不乖  阅读(6)  评论(0)    收藏  举报