更新记录
1.0.3(2026-08-06)
优化
1.0.1(2026-08-04)
● ## Sh-NoticeMgmt v1.0.0 发布日志
通知监听
- 修复漏监听问题
1.0.0(2026-08-02)
● ## sh_NotificationManagement v1.0.0 发布日志
平台:Android(最低 API 21)
权限管理
- 检查/跳转通知监听权限
-
检查/跳转悬浮窗权限
通知监听
- 开启/停止监听 Android 通知栏新消息
- 实时回调:包名、标题、内容
-
查询监听状态
清除通知
- 按包名清除指定应用所有通知
- 按关键词清除匹配通知(忽略大小写)
-
清除通知栏全部通知
悬浮窗胶囊(灵动岛风格)
- 显示/隐藏悬浮窗胶囊,淡入淡出动画
- 点击胶囊展开面板,点击外部或 5 秒自动收起
- 自由拖动胶囊,不会超出屏幕
- 拖到屏幕边缘 3 秒自动缩成圆点
- 短按圆点恢复胶囊,长按圆点展开面板
- 胶囊宽度随内容自适应,始终保持居中
- 面板内置"开启/停止监听"开关按钮
- 面板内置"打开应用"按钮
-
更新胶囊状态文本和通知数量
回调
-
面板开关按钮回调(全局共享,跨页面可用)
自定义
- 自定义面板标题/副标题,支持恢复默认
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(5.15)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | × | × | × |
Sh-NoticeMgmt 插件使用
Android通知管理插件,支持通知栏消息监听、清除通知、悬浮窗胶囊、开机自启动。
平台支持:仅 Android(最低 API 21)
版本:v2.1(基于 sh-NotificationManagement.aar 原生封装)
一、功能概述
| 模块 | 说明 |
|---|---|
| 权限管理 | 检查通知监听权限、悬浮窗权限,跳转系统设置页 |
| 通知监听 | 监听 Android 通知栏新消息,实时回调包名、标题、内容,不漏监听 |
| 心跳检测 | 5分钟一次检查监听状态,失效自动恢复,长时间后台运行不失效 |
| WorkManager 转发 | 通知到达持久化入队,进程被杀也不丢(可选) |
| 清除通知 | 按包名、关键词清除指定通知,或一键清除全部通知 |
| 悬浮窗胶囊 | 桌面悬浮窗,支持展开面板、拖动、边缘吸附、监听开关 |
| 开机自启动 | 开机后自动启动 App 恢复通知监听,支持开关和厂商适配 |
| 多页面共享 | A/B/C 多页面各自监听互不覆盖,支持一键清除全部回调 |
二、架构特点
1. 不漏监听
通知到达(系统保证每条都回调)
↓
onNotificationPosted
├─→ WorkManager.enqueue() ← 持久化入队(SQLite),进程被杀也能恢复
│ ↓
│ NotifSendWorker → setForwardCallback(App 层转发,可选)
│
└─→ 实时回调 startListening ← 直接回调,零延迟,进程存活时 100% 不漏
- 进程存活时:实时回调,100% 不遗漏,无轮询、无竞态
- 标题/内容提取:
getCharSequence+EXTRA_BIG_TEXT+tickerText多级兜底,兼容各厂商 ROM
2. 多页面共享
通知回调走全局列表,各页面各自注册、各自移除:
A 页面 startListening(cbA) → 列表 [cbA]
B 页面 startListening(cbB) → 列表 [cbA, cbB]
通知到达 → 遍历列表 → cbA ✅ cbB ✅ 都收到
B stopListening → 只移除 cbB → A 不受影响
removeAllListeners → 一键清除全部
3. 长时间后台运行不失效
心跳检测(5分钟一次)+ 断连自动重连(requestRebind):
监听被系统/ROM 静默断开
↓
心跳检测发现 → 权限在 + Service 断开 → 自动重启/重连
↓
监听恢复,无需用户干预
三、使用方法
import { NotificationManager } from '@/uni_modules/Sh-NoticeMgmt'
const sh_Not = new NotificationManager()
所有 API 通过 sh_Not 实例调用,多个实例共享同一底层 Service 和回调列表。
四、使用示例
完整示例 uniappx
// #ifdef APP-ANDROID
import { NotificationManager } from '@/uni_modules/Sh-NoticeMgmt'
const sh_Notif = new NotificationManager()
// 开启监听(实时回调)
sh_Notif.startListening((pkg: string, title: string, msg: string) => {
console.log(`新通知: [${pkg}] ${title} - ${msg}`)
})
// 开启心跳检测(5分钟一次,防长时间后台失效)
sh_Notif.startHeartBeat()
// 可选:设置 WorkManager 转发回调(持久化,进程被杀也不丢)
sh_Notif.setForwardCallback((msgInfo: any) => {
// msgInfo 包含完整通知数据
uni.request({
url: 'https://你的服务器',
data: { pkg: msgInfo.from, title: msgInfo.title, msg: msgInfo.content }
})
})
// 页面销毁时停止
onUnmounted(() => {
sh_Notif.stopListening()
sh_Notif.stopHeartBeat()
})
// #endif
清除通知示例
// 清除微信所有通知
sh_Not.cancelPackageNotifications('com.tencent.mm')
// 清除所有含"到账"的通知
sh_Not.cancelByKeyword('到账')
// 只清除微信中含"收款"的通知
sh_Not.cancelByKeyword('收款', 'com.tencent.mm')
// 清除所有通知
sh_Not.cancelAllNotifications()
多页面监听示例
// ===== A 页面 =====
const nmA = new NotificationManager()
nmA.startListening((pkg, title, msg) => {
console.log(`A 页面收到: ${title}`)
})
onUnmounted(() => nmA.stopListening())
// ===== B 页面 =====
const nmB = new NotificationManager()
nmB.startListening((pkg, title, msg) => {
console.log(`B 页面收到: ${title}`)
})
onUnmounted(() => nmB.stopListening())
// ===== 任意页面一键清除全部回调(应用退出时) =====
const nmG = new NotificationManager()
nmG.removeAllListeners()
心跳检测示例
// 建议 App 启动后开启
sh_Not.startHeartBeat() // 5分钟一次,自动恢复失效的监听
// 需要时关闭
sh_Not.stopHeartBeat()
跨页面回调示例
// ===== app.uvue 中显示悬浮窗 =====
const nmA = new NotificationManager()
nmA.showFloatingWindow(true, 0)
// ===== index.uvue 中设置回调,全局生效 =====
const nmB = new NotificationManager()
nmB.setFloatingToggleCallback((enabled: boolean) => {
if (enabled) {
nmB.startListening((pkg, title, msg) => {
console.log(`[${pkg}] ${title}: ${msg}`)
})
} else {
nmB.stopListening()
}
})
五、API 参考
权限检查与申请
| 方法名 | 说明 | 返回值 |
|---|---|---|
isNotificationPermissionEnabled() |
检查通知监听权限是否已开启(使用 NotificationManagerCompat,对齐 SmsForwarder) | boolean |
openNotificationPermissionSettings() |
跳转系统通知使用权限设置页 | void |
isOverlayPermissionEnabled() |
检查悬浮窗权限是否已开启 | boolean |
requestOverlayPermission() |
跳转系统悬浮窗权限设置页 | void |
openAppSettings() |
跳转应用详情页(分身环境下通知使用权页空白时的降级方案) | void |
isLikelyDualApp() |
检测当前是否可能处于应用分身环境 | boolean |
应用分身说明:在小米双开、华为应用分身等环境下,通知使用权设置页可能显示空白(因为分身的包名未注册 NotificationListenerService)。此时可调用
openAppSettings()降级跳转应用详情页,或通过isLikelyDualApp()检测后引导用户使用主体应用。
通知监听
| 方法名 | 说明 | 返回值 |
|---|---|---|
startListening(callback) |
开启通知监听,新通知到达时实时回调 | void |
stopListening() |
关闭本页面的通知监听(不影响其他页面) | void |
getListeningStatus() |
获取当前实例监听状态 | boolean |
removeAllListeners() |
一键移除全部页面的监听回调,停止 Service | void |
sh_Not.startListening((pkg: string, title: string, msg: string) => {
console.log(`包名: ${pkg}`)
console.log(`标题: ${title}`)
console.log(`内容: ${msg}`)
})
心跳检测
| 方法名 | 说明 | 返回值 |
|---|---|---|
startHeartBeat() |
开启心跳检测(5分钟一次,全局唯一),监听失效自动恢复 | void |
stopHeartBeat() |
关闭心跳检测 | void |
sh_Not.startHeartBeat() // 长时间后台运行不失效
sh_Not.stopHeartBeat() // 关闭
WorkManager 转发
| 方法名 | 说明 | 返回值 |
|---|---|---|
setForwardCallback(callback) |
设置转发回调(全局唯一),WorkManager 持久化保障 | void |
sh_Not.setForwardCallback((msgInfo) => {
// 后台/进程被杀也不丢,恢复后补发
console.log(`转发: [${msgInfo.from}] ${msgInfo.title}: ${msgInfo.content}`)
})
清除通知
| 方法名 | 说明 | 返回值 |
|---|---|---|
cancelPackageNotifications(pkg) |
清除指定包名的所有通知 | void |
cancelByKeyword(keyword, pkg?) |
清除标题或内容含关键词的通知 | void |
cancelAllNotifications() |
清除通知栏所有通知 | void |
悬浮窗胶囊
| 方法名 | 说明 | 返回值 |
|---|---|---|
showFloatingWindow(isListening, count) |
显示悬浮窗胶囊 | void |
hideFloatingWindow() |
关闭悬浮窗胶囊 | void |
updateFloatingWindow(isListening, count) |
更新胶囊状态文本和数量 | void |
isFloatingWindowShowing() |
悬浮窗是否正在显示 | boolean |
setFloatingToggleCallback(callback) |
设置悬浮窗面板开关按钮回调(全局共享) | void |
自定义面板文本
| 方法名 | 说明 | 返回值 |
|---|---|---|
setPanelTexts(title?, subtitle?) |
自定义面板标题/副标题,传 null 恢复默认 |
void |
开机自启动
| 方法名 | 说明 | 返回值 |
|---|---|---|
isBootReceiverEnabled() |
检查开机自启动是否已开启 | boolean |
setBootReceiverEnabled(enabled) |
开关开机自启动,开启时自动跳转系统自启动管理页 | void |
openAutoStartSettings() |
跳转系统自启动管理页(覆盖小米/华为/OPPO/vivo等主流厂商) | void |
// 检查开机自启状态
if (!sh_Not.isBootReceiverEnabled()) {
// 开启开机自启(会自动跳转厂商自启动管理页)
sh_Not.setBootReceiverEnabled(true)
}
// 单独跳转自启动管理页
sh_Not.openAutoStartSettings()
// 关闭开机自启
sh_Not.setBootReceiverEnabled(false)
注意:开机自启动依赖
RECEIVE_BOOT_COMPLETED权限(无需动态申请)。部分厂商 ROM 需要用户在系统自启动管理中手动放行,setBootReceiverEnabled(true)会自动跳转对应页面。建议同时开启悬浮窗权限,部分 ROM 会将其作为允许自启动的信任凭证。
六、悬浮窗交互说明
| 操作 | 效果 |
|---|---|
| 点击胶囊 | 顶部展开面板(全屏遮罩,面板居中) |
| 点击面板外空白区域 | 收起面板 |
| 面板展开后 5 秒无操作 | 自动收起 |
| 拖动胶囊 | 自由移动,不会超出屏幕边界 |
| 拖到屏幕边缘停留 3 秒 | 缩成圆点吸附边缘 |
| 短按圆点 | 在当前位置恢复胶囊 |
| 长按圆点(≥ 0.5 秒) | 展开面板 |
| 面板"开启/停止监听"按钮 | 切换监听状态,触发回调 |
| 面板"打开应用"按钮 | 返回 App 主页面 |
| 胶囊内容变化 | 宽度自动适配,向两边均匀扩展保持居中 |
七、权限声明
[
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" />",
"<uses-permission android:name=\"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE\" tools:ignore=\"ProtectedPermissions\" />",
"<uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>"
]
八、注意事项
- 通知监听权限需要用户在系统设置中手动授权,无法通过代码自动开启
- 悬浮窗权限同样需要用户手动授权
- 悬浮窗使用
TYPE_APPLICATION_OVERLAY,显示在状态栏下方 - 监听仅获取新到达的通知,不会推送历史通知
- 长时间后台运行:建议开启
startHeartBeat(),系统/ROM 静默断开监听时自动恢复 - 部分厂商 ROM(小米、OPPO、vivo)后台限制激进,建议引导用户加入系统白名单/自启动/电池优化白名单
- 多页面监听:各页面
startListening互不覆盖,stopListening只影响本页面;removeAllListeners()一键清除全部 - 页面销毁:请在
onUnmounted中调用stopListening(),避免回调残留 - 心跳全局唯一:
startHeartBeat()重复调用不会叠加定时器,stopHeartBeat()由任意实例调用即全局关闭 - 转发回调全局唯一:
setForwardCallback后设置的覆盖之前的,建议 App 层全局只设置一次 - 开机自启默认启用:插件安装后
BootCompletedReceiver默认启用,可通过setBootReceiverEnabled(false)关闭 - 厂商 ROM 限制:小米/华为/OPPO/vivo 等系统可能阻止自启,
setBootReceiverEnabled(true)会自动跳转自启动管理页引导用户放行;建议同时开启悬浮窗权限提高系统信任等级

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 20
赞赏 0
下载 12608024
赞赏 1949
赞赏
京公网安备:11010802035340号