更新记录

1.0.6(2026-06-23)

  1. 优化

1.0.5(2026-05-26)

  1. 优化Android目录结构

1.0.4(2026-05-26)

  1. 优化鸿蒙
查看更多

平台兼容性

uni-app(3.7.12)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - 5.0
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(3.7.12)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 -

其他

多语言 暗黑模式 宽屏模式

原生厂家消息推送,不依赖任何第三方支持对接各个手机厂家

功能介绍

  • 生成获取deviceToken
  • 点击推送消息获取消息报文,支持冷启动和热启动
  • 支持苹果、VIVO、OPPO、华为、荣耀、魅族、小米、鸿蒙,直接对接各个手机厂家,不依赖任何第三方

集成步骤

  1. 插件详细集成步骤可以参考https://www.jianshu.com/p/c1615a7880a7
  2. 拷贝demo里的nativeResources、AndroidManifest.xml文件到项目根目录
  3. 本页面右上角可以点击"使用HBuilderX导入示例项目"下载demo,导入demo的时候选vue3,插件支持vue2和vue3
  4. 如需定制或增加功能请点击插件标题下方的"进入交流群"私聊作者

iOS配置

  • 登陆苹果后台开发者系统,进入Identifiers,点击包名对应的应用进入应用详情,勾选Capabilities下的Access Wi-Fi Information和Push Notifications,然后重新下载打包的provision文件
  • nativeResources/ios/UniApp.entitlements文件里的aps-environment对应的值是development、production,一般开发阶段使用development,生产发布使用production,根据情况设置

鸿蒙next配置

配置Android各个平台的apiKey、appSecret等

  • 下面的配置信息的值如果是纯数字,请在前后都加上#号,避免系统当成数字处理(vivo和荣耀除外,vivo和荣耀不需要做添加#处理),例如: 小米的appKey是2252222222,全部都是数字,此时前后都添加#后变成#2252222222#
{
    "vivo_api_key": "be3091068f0171c789c85e54b068d540", // vivo apiKey
    "vivo_app_id": "106084672", // vivo appId
    "oppo_app_key": "1111", // oppo appKey
    "oppo_app_secret": "xxx",  // oppo appSecret
    "xiaomi_app_id": "#123456#", // 小米 appId
    "xiaomi_app_key": "#2252222222#", // 小秘密appKey
    "meizu_app_id": "xxx", // 魅族appId
    "meizu_app_key": "xxx", // 魅族appKey
    "meizu_app_pkg": "xxx", // 魅族app包名
    "huawei_app_id": "#117772375#", // 华为appId
    "honor_app_id": "104564391" // 荣耀appId
}

VIVO推送配置

  • 申请开通推送权限https://dev.vivo.com.cn/documentCenter/doc/281#
  • 如果app还没有上线成功的话,需要在vivo平台上添加测试设备,然后后端发送一条测试的消息,然后打开app的通知权限页面,页面往下滚动,点击"运营消息"类别,开启“允许通知”开关

OPPO推送配置

小米推送配置

魅族推送配置

华为推送配置

荣耀推送配置

消息推送自定义铃声

  1. Android先调用createNotificationChannel接口创建一个带有铃声的channel,后端接口往这个channel(传channelId)里推送消息
  2. ios在后端接口有个sound字段,填入nativeResources/ios/Resources文件夹里面的文件名称,如ring.wav

华为和荣耀生成配置文件方式

方式1
  • 点击插件标题下方的"进入交流群"私聊作者,联系作者生成
方式2:
  • 安装Android Studio,然后打开demo里的static/AndroidGenerateConfig原生工程(使用JDK17)

  • 华为配置:

    1. 从华为应用后台下载agconnect-services.json并替换app/agconnect-services.json
  • 荣耀配置

    1. 从荣耀应用后台下载mcs-services.json并替换mcs-services.json
  • 将项目下appKey.jks(appKey.keystore)签名文件替换成你的签名文件

  • 修改app/build.gradle文件,修改内容有:

    1. 将applicationId改为自己的包名
    2. 修改ReleaseSign下面签名文件的密码别名
    3. 开启华为开关关闭荣耀开关,或者开启荣耀开关开启华为开关

    id 'com.huawei.agconnect' // 开启华为开关, 生成华为配置文件时这行代码取消注释,下行荣耀代码注释掉
//    id 'com.hihonor.mcs.asplugin' // 荣耀开启荣耀开关,生成荣耀配置文件时这行代码取消注释,上行华为代码注释掉
  1. 修改完app/build.gradle文件后,点击上方的"Sync Now"按钮同步工程
  2. 点击顶部的右三角箭头运行一次项目
  3. 取出对应的华为或荣耀的配置文件,华为的配置文件位于app/build/generated/res/agc/release/values/values.xml,荣耀的配置文件位于app/build/generated/res/****/debug/values/values.xml,分别将其重命名为huawei_config.xml或honor_config.xml,然后替换到项目里对应的文件

使用服务端测试app

  • 方式1:采用各个平台官方的后端系统里可以测试app
  • 方式2:电脑搭建java 17环境,配置好环境变量,进入到demo/static文件夹下,使用命令启动服务:

java -jar manufacturepushplatform-0.0.1-SNAPSHOT.jar

浏览器打开链接http://127.0.0.1:8080/manufacturepushplatform/swagger-ui.html,使用上面的swagger接口可以测试推送

接口文档

    import {
    UTSManufacturePush
} from "@/uni_modules/wrs-uts-manpush"
  • 设置回调,最先设置回调,避免的token不回调
    // 最先设置回调,避免的token不回调
UTSManufacturePush.onCallback((resp) => {
    let opt = resp.opt
    switch (opt) {
    // 仅支持鸿蒙,当app未启动时,点击消息来启动app后,从这个回调来获取消息的业务参数
    case "onAppAbilityCreate": {
        // console.log(JSON.stringify(resp))
        this.showMsg("鸿蒙点击通知启动app:" + JSON.stringify(resp))
    }
    break;
    // 仅支持鸿蒙,当app已经启动时,点击消息来唤醒app后,从这个回调来获取消息的业务参数
    case "onAppAbilityNewWant": {
        // console.log(JSON.stringify(resp))
        this.showMsg("鸿蒙点击通知启动app:" + JSON.stringify(resp))
    }
    break;
    // 获取到token
    case "onToken":
        let token = resp.token
        if (token) {
            this.deviceToken = token
            this.showMsg("获取到token:" + token)
        }
        break;
        // 获取token失败
    case "onTokenFail":
    {
        this.showMsg("获取token失败:" + JSON.stringify(resp))
    }
        break;
        // onWillPresent仅支持iOS
    case "onWillPresent":
        break;
        // app运行中点击了消息会回调这里,仅支持iOS
    case "onClick":
    {
        // {
        //  "resp": {
        //      "request": {
        //          "identifier": "BE128925-265A-4481-9DE0-2701C3B55556",
        //          "content": {
        //              "summaryArgumentCount": 0,
        //              "body": "订单号NO22221xxx55sf1a",
        //              "userInfo": {
        //                  "aps": {
        //                      "badge": 0,
        //                      "alert": {
        //                          "title": "您好,支付成功",
        //                          "body": "订单号NO22221xxx55sf1a"
        //                      },
        //                      "mutable-content": 1
        //                  },
        //                  "age": 12,
        //                  "name": "wrs"
        //              },
        //              "categoryIdentifier": "",
        //              "title": "您好,支付成功",
        //              "summaryArgument": "",
        //              "launchImageName": "",
        //              "badge": 0,
        //              "subtitle": "",
        //              "threadIdentifier": ""
        //          }
        //      },
        //      "opt": "onClick",
        //      "actionIdentifier": "com.apple.UNNotificationDefaultActionIdentifier"
        //  }
        // }
        this.showMsg("ios点击了消息:" + JSON.stringify(resp))
    }
        break;
        //仅支持iOS, app没有启动时,点击消息启动,
    case "onLaunchOptioins":
        let remoteNotification = resp.remoteNotification
        if (remoteNotification) {
            // 点击通知启动的app
        }
        break;
    case "onMessageDelivered": {

    }
    break;
    // 仅支持Android,有些机型app在前台运行时,收到通知不会显示到通知栏,需要自己调用本地通知来显示通知
    // 测试发现vivo不会回调这里,vivo app在前台运行时也会在通知栏显示通知
    case "onMessageReceived":
        // {"message":{"originalPriority":1,"priority":1,"from":"1062023367861","sentTime":1728529512606,"messageId":"0:1728529526496732%8b5c45cc8b5c45cc","collapseKey":"com.wrs.project.jpush","data":{"age":"999","name":"wrs","address":"zh"},"senderId":"1062023367861","ttl":2419200,"notification":{"channelId":"channel01","title":"aaaa","body":"aaaaa"}},"opt":"onMessageReceived"}                       let message = resp.message
        let message = resp.message
        if (message) {
            let messageObj = JSON.parse(message)
            let msgId = messageObj.msgId
            let title = messageObj.title
            let content = messageObj.content
            let params = messageObj.params

            this.shownMessageNotification(title, content, params)
        }

        break;
    default:
        break;
    }

})
  • 初始化推送

let params = {}
params.agreePrivacy = true // vivo
params.isDebug = false // oppo
UTSManufacturePush.pushInit(params, (resp) => {
    let flag = resp.flag
    if (flag) {

        }
    }
)
  • 开启推送,开启推送后,token会在onCallback里回调

// 开启推送,开启推送后才会获取到token
UTSManufacturePush.turnOnPush((turnResp) => {
    let flag = resp.flag
    if (flag) {
        console.log("成功开启推送")
    } else {
        console.log("开启推送失败:" + JSON.stringify(turnResp))
    }
})
  • 请求通知权限
switch (uni.getSystemInfoSync().platform) {
    case 'harmonyos': {
        // 请求通知权限
        UTSManufacturePush.requestAuthorization({}, (resp) => {
            let flag = resp.flag
            if (flag) {
                console.log("获取消息通知权限")

            } else { // 请求权限失败
                console.log("requestAuthorization:" + JSON.stringify(resp))
            }
        })
    }
    break;
    case 'android': {
        // 请求通知权限
        let version = UTSManufacturePush.getBuildSDKVersion()
        if (version >= 33) {
            this.requestPermission([
                "android.permission.POST_NOTIFICATIONS"
            ])
        }
    }
    break;
    case 'ios': {
        // 请求通知权限
        UTSManufacturePush.requestAuthorization({
            types: ["badge", "sound", "alert"]
        }, (resp) => {
            let flag = resp.flag
            if (flag) { // 请求权限失败

            } else { // 请求权限失败
                console.log("requestAuthorization:" + JSON.stringify(resp))
            }
        })
    }
    break
    default:
        break;
}
  • 获取平台名称

let platform = ""
let manufacturer = UTSManufacturePush.getManufacturer()
if (manufacturer.includes("xiaomi")) {
    platform = "小米"
} else if (manufacturer.includes("huawei")) {
    platform = "小米"
} else if (manufacturer.includes("honor")) {
    platform = "荣耀"
} else if (
    manufacturer.includes("oppo")) {
    platform = "OPPO"
} else if (manufacturer.includes("vivo")) {
    platform = "VIVO"
} else if (manufacturer
    .includes("meizu")) {
    platform = "魅族"
} else if (manufacturer.includes("ios")) {
    platform = "苹果"
} else if (manufacturer.includes(
        "harmonyos")) {
    platform = "鸿蒙"
}
  • 监听点击推送消息,并获取消息数据

android

在app的onShow生命周期回调里调用UTSManufacturePush.getUTSIntentData接口,获取到的数据如果包含推送业务参数,说明是点击消息启动的

        onShow: function() {
    console.log('App Show')
    switch (uni.getSystemInfoSync().platform) {
        case 'harmonyos': {

        }
        break;
        case 'android': {
            // android通过调用UTSManufacturePush.getUTSIntentData()接口判断有没有获取到通知里的业务参数来判断是否点击通知启动的app
            let intentData = UTSManufacturePush.getUTSIntentData()
            console.log("Intent Data:" + JSON.stringify(intentData))
            if (intentData) {
                let extras = intentData.extras
                if (extras) {
                    // 后端或本地发送通知的时候,自己带上业务参数,点击通知时在app的生命周期里调用getUTSIntentData()可以获取到通知里的业务参数
                    //customParams里面的业务参数
                    let name = extras.name
                    if (name) {
                        // 删除当前的通知业务参数,不然的话当点击app图标启动时也会获取到上次缓存的通知参数
                        let key = "name"
                        UTSManufacturePush.removeUTSIntentDataExtra(key)

                    }
                }
                // vivo {"extras":{"age":"12","short_cut_class_name":"io.dcloud.PandoraEntry","time":"1779235233962","name":"wrs","__intetn_orientation__":2,"vivo_push_messageId":-1506567296147139000,"intent_userId":0}}

            }
        }
        break;
        case 'ios': {

        }
        break
        default:
            break;
    }

},

ios

  • 冷启动,在onCallback里如果有回调onLaunchOptioins的业务,说明是点击消息冷启动的
    case "onLaunchOptioins":
        let remoteNotification = resp.remoteNotification
        if (remoteNotification) {
            // 点击通知启动的app
        }
        break;
  • 热启动,在onCallback里如果有回调onClick的业务,说明是点击消息热启动的

case "onClick":

鸿蒙

  • 冷启动,在onCallback里如果有回调onAppAbilityCreate的业务,说明是点击消息冷启动的
    // 仅支持鸿蒙,当app未启动时,点击消息来启动app后,从这个回调来获取消息的业务参数
    case "onAppAbilityCreate": {
        // console.log(JSON.stringify(resp))
        this.showMsg("鸿蒙点击通知启动app:" + JSON.stringify(resp))
    }
    break;
  • 热启动,在onCallback里如果有回调onAppAbilityNewWant的业务,说明是点击消息热启动的

    // 仅支持鸿蒙,当app已经启动时,点击消息来唤醒app后,从这个回调来获取消息的业务参数
    case "onAppAbilityNewWant": {
        // console.log(JSON.stringify(resp))
        this.showMsg("鸿蒙点击通知启动app:" + JSON.stringify(resp))
    }
    break;
  • 创建通知频道channel,仅支持Android

// 第一种:云端url
let ringUrl = "http://192.168.2.24:8080/file/test.mp3"
// 第二种:static文件夹下的文件
// ringUrl = UTSPush.getResourcePath("/static/test.mp3")
//第三种(推荐): nativeResources/android/res/raw文件夹下的文件test.mp3,只需要文件名,不需要文件后缀
ringUrl = "test"
let channelId = "xxx"
let params = { // 如果已经channelId的channel则不创建,如果没有则会自动创建
    channelId: channelId,
    channelName: "自定义铃声",
    importance: 4, // 3: default 4: high 2: low 5: max 1: min 0: none
    lockscreenVisibility: 1, //1: public 0: private -1: secret
    description: "自定义铃声channel",
    vibration: { // 震动
        enable: true,
        pattern: [100, 200, 300, 400, 500, 400, 300, 200, 400]
    },
    sound: { // 铃声
        url: ringUrl
    },
    lightColor: "#ffffff"
}
// 创建频道,先删除再创建
UTSManufacturePush.createNotificationChannel(params)
  • 删除通知频道,仅支持Android

UTSManufacturePush.deleteNotificationChannel(channelId)
  • 删除通知缓存业务参数
// 删除当前的通知业务参数,不然的话当点击app图标启动时也会获取到上次缓存的通知参数
UTSManufacturePush.removeUTSIntentDataExtra("name")
UTSManufacturePush.removeUTSIntentDataExtra("age")

隐私、权限声明

1. 本插件需要申请的系统权限列表:

网络、消息推送

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: