App端内测更新需自行实现:先用uni.getSystemInfoSync().platform判断Android/iOS环境,再通过plus.runtime.getProperty获取真实版本号;后端需返回version_code整数用于安全比对,并按平台提供APK直链或TestFlight链接。

App端内测更新提醒不能靠 uni.getUpdateManager——这个 API 只在微信小程序等平台有效,App 端必须自己查接口、比版本、走原生安装流程。
怎么判断当前是 App 环境并获取本地版本号
真机运行时,uni.getSystemInfoSync().platform 返回 "android" 或 "ios" 才算进入 App 环境;H5 和小程序里调用 plus.runtime 相关方法会直接报错或返回 undefined。
本地版本号必须从原生层读取,不能读 manifest.json 的打包时静态值(它可能没同步更新):
-
plus.runtime.getProperty(plus.runtime.appid, callback)是唯一可靠方式,回调中info.version对应 manifest 里的“版本名称”(如"1.2.3-beta"),info.versionCode对应“版本号”(整数,如10203) - Android 建议优先用
versionCode比较(整数安全),iOS 因无安装权限,只能跳转 TestFlight,此时用version字符串做展示即可 - 千万别在
onLaunch里直接读取——App 启动初期plus对象可能未就绪,建议放在首页onShow或加个setTimeout延迟 300ms 再调
后端接口怎么设计才不踩坑
接口返回字段必须包含可比对的版本标识、下载地址、是否强制更新。常见错误是后端只返回字符串 "1.10.0",前端用 > 直接比较导致 "1.2.0" > "1.10.0" 判为 false。
- 推荐后端同时返回
version(展示用字符串)和version_code(整数,如10200),前端统一比version_code - Android 下载地址必须是直链 APK(支持断点续传),且服务器需配置
Content-Type: application/vnd.android.package-archive - iOS 必须返回
testflight_url或企业签名页 URL,不能返回 .ipa 文件直链(iOS 不允许) - 接口要带缓存头(如
Cache-Control: max-age=3600),避免每次启动都请求
Android 安装失败的三个高频原因
调用 plus.runtime.install() 后黑屏、静默失败、提示“解析包错误”,大概率不是代码问题,而是环境或配置卡点:
- 缺权限:Android 8.0+ 必须在
manifest.json → Android 设置 → 权限配置中勾选android.permission.REQUEST_INSTALL_PACKAGES,否则安装直接被系统拦截 - APK 签名不一致:新包必须和旧包使用同一套签名证书,否则系统拒绝覆盖安装(错误信息常为
INSTALL_FAILED_UPDATE_INCOMPATIBLE) - 文件路径不对:
plus.downloader.createDownload()下载后,传给install()的必须是本地绝对路径(如/storage/emulated/0/Android/data/xxx/files/update.apk),不能是临时 URL 或相对路径
弹窗时机和交互细节容易被忽略
用户正在输入、播放视频、支付过程中弹升级框,轻则体验断裂,重则触发系统拦截或白屏。
- 弹窗必须在首页
onShow触发,且增加状态锁:if (this.isEditing || this.isPlaying) return - 用户点“稍后再说”,要记录时间戳到
uni.setStorageSync('last_update_cancel', Date.now()),12 小时内不再弹(避免骚扰) - 强制更新时,
showCancel: false并禁用返回键(plus.key.addEventListener('backbutton', () => {}, false)),但需留退出入口(比如长按 logo 3 秒)以防误锁 - iOS 弹窗内容别写“点击安装”,而要明确写“前往 TestFlight 更新”,否则用户完全不知道下一步做什么
最麻烦的其实是版本号语义一致性:开发、测试、打包、后端接口、用户看到的提示文案,五处的“1.2.3”必须指向同一个构建产物,否则比对逻辑再稳也没用。


















