uni.downloadFile无法直接更新通知栏进度条,因其onProgressUpdate仅提供JS层百分比数值,不支持原生通知控制;Android需通过plus.notification.createNotification创建后持续调setOptions更新,iOS则不支持该功能。

Android 端能实现,iOS 不支持;必须用 plus.notification.createNotification + setOptions 动态更新,不能靠 uni.downloadFile 直接驱动。
为什么 uni.downloadFile 无法直接更新通知栏进度条
uni.downloadFile 在 App 端返回的 task 实例虽支持 onProgressUpdate,但它只提供百分比数值(res.progress),且该回调是 JS 层事件,不带原生通知控制能力。通知栏进度条属于 Android 系统级 UI,必须通过 plus.android 或 plus.notification 调用原生 API 才能写入。
- 常见错误:在
onProgressUpdate里直接调uni.showToast或更新页面progress组件——这完全不进通知栏 - 真正生效的只有
plus.notification.createNotification创建后,再反复调notification.setOptions({ progress: x }) - iOS 下连
progress字段都会被忽略,所以必须条件编译隔离逻辑
创建并更新通知栏进度条的正确流程
关键不是“一次创建”,而是“首次创建 + 持续覆盖”。Android 要求通知 ID 固定、ongoing: true、且每次更新都需调 setOptions 替换整条通知。
- 首次调用
plus.notification.createNotification时必须传id(如"download-progress"),后续靠它匹配 -
options中必须含progress: 0(整数,0–100),且ongoing: true(否则用户滑动清除后无法再更新) - 每次进度变化时,先用
plus.notification.getNotification(id)获取实例,再调.setOptions({ progress: Math.round(percent) }) - 下载完成时,再次
setOptions改为progress: 100,并可选加contentText: "下载完成",最后.clear()或留着等用户手动清除
进度监听与节流的实操要点
plus.downloader.createDownload 的 statechanged 事件比 uni.downloadFile.onProgressUpdate 更稳定可靠,且能拿到 downloadedSize 和 totalSize,避免依赖可能不准的百分比估算。
- 不要在
statechanged回调里直接计算并更新通知——触发太频繁(毫秒级),容易卡顿 - 建议用时间戳节流:记录上次更新时间,间隔 ≥ 300ms 再更新;或只在进度变化 ≥ 1% 时才调
setOptions -
progress必须是整数,Math.round((downloadedSize / totalSize) * 100)是安全写法,避免小数或字符串导致失败 - Android 8.0+ 需确保已申请
android.permission.POST_NOTIFICATIONS,HBuilderX 3.7.0+ 会自动注入,旧版需手动加到android/app/src/main/AndroidManifest.xml
容易被忽略的兼容性细节
看似简单的进度条,实际跨版本、跨渠道行为差异很大:HBuilderX 版本、5+ Runtime 基座版本、targetSdkVersion 都会影响是否渲染成功。
- 必须使用 HBuilderX 3.1.0+,且运行基座版本 ≥ 2.6.0;低于此版本
progress字段无效 - 通知渠道(Channel)在 Android 8.0+ 是强制的,但
plus.notification内部已封装处理,无需手建;若自定义渠道 ID,需确保与 manifest 中一致 - 部分厂商(如华为、小米)对
ongoing通知有额外限制,测试时务必真机验证,模拟器常显示异常 - 不要复用同一
id用于不同下载任务——旧通知未 clear 前新任务会覆盖,但进度值可能错乱


















