浅谈unipush
UniPush 是 DCloud 联合个推公司推出的集成型统一推送服务,是所有uni-app开发者首选的推送服务。
有两个版本:
2.0版新版文档地址:https://uniapp.dcloud.net.cn/unipush-v2.html
1.0版老版文档地址:https://uniapp.dcloud.net.cn/unipush-v1.html
主要用于使用uniapp开发的app的消息推送功能,2.0与1.0的区别主要是新增了云函数可用于非app以外的小程序等场景的消息推送服务
unipush实现消息推送逻辑:通过使用设备的唯一标识判断向那个设备推送信息,这里的唯一标识就是unipush所讲的cid,可以使用api获取到当前设备的cid,这个cid相当于app在此设备的唯一标识永久不会变可以将这个cid绑定到用户信息表中,以用于消息推送逻辑的开发
使用场景demo
demo是使用uniapp套壳H5,在uniapp中使用web-view组件实现的消息推送服务,其中不仅涉及到unipush的集成同时还有web-view中的组件通讯
1.在uniapp中勾选unipush服务,这里使用的为1.0(不涉及除app以外的业务逻辑1.0够用,不然2.0还要多一个云函数空间服务费用),然后在配置页面进行相关配置
这个配置页面就相当于后台集成的消息推送的sdk,里面涉及到手机厂商通道按照各自需求进行配置,在透传消息中可以进行消息推送的测试
2.在uniapp中获取cid 并监听后台推送的消息,然后通过web-view传送给嵌套的H5页面实现业务逻辑
<template>
<view>
<web-view :src="url"></web-view>
</view>
</template>
mounted() {
uni.getPushClientId({
success: res => {
// 获取设备cid
console.log(res.cid);
}
})
uni.onPushMessage(res => {
if (res.type == "receive") {
// 生成消息推送弹窗,这里通过类型为receive判断主要是为了防止重复弹出弹窗
uni.createPushMessage({
title: "你有一条未读信息",
content: res.data.payload.name,
})
} else if (res.type == "click") {
// 用于处理点击推送消息弹窗的逻辑
console.log('点击事件', res)
// 传送监听到的消息给H5页面
this.onSend()
}
})
// #ifdef APP-PLUS
// 这快主要处理webview页面的样式,兼容刘海屏,水滴屏等稀奇古怪手机屏幕
let statusBarHeight = 0; // 获取顶部状态栏高度
let windowBottom = 0; // 可使用窗口的底部位置
// 获取状态栏高度并设置web-view组件顶部高度
uni.getSystemInfo({
success: (res) => {
statusBarHeight = res.statusBarHeight;
windowBottom = res.windowBottom;
console.log(statusBarHeight,windowBottom)
const currentWebview = this.$scope.$getAppWebview();
const wv = currentWebview.children()[0];
wv.setStyle({ top: statusBarHeight});
wv.setStyle({bottom: windowBottom});
}
});
// #endif
},
methods: {
/**
* 父传子
* 父界面:先获取当前web-view(this.$scope.$getAppWebview().children()[0]),通过 evalJS("xxx({msg: '你好,子页面'})")
* 子界面:window.xxx = (res) => {}
*/
onSend() {
var dataMsg ={
type:"dataMsg",
cid:this.cid,
// 传给子页面的参数
}
console.log('父传子')
const vw = this.$scope.$getAppWebview().children()[0]
const jsCode = `sendParentData(${JSON.stringify(dataMsg)})`;
vw.evalJS(jsCode);
}
}
2.子页面(h5)需要引入uni官网提供的sdk – uni.web-view.js
window.sendParentData = (res) => {
// 接收到的父传子页面的消息
console.log(res)
};
3.当app打包测试可能还会遇到app并没有开启横幅通知以及手机app角标等通知所需要的权限,这就需要在uniapp 中调用以下方法引导用户开启通知权限
/**
* 设置手机通知权限
*/
function setPermissions() {
// #ifdef APP-PLUS
if (plus.os.name == 'Android') {
console.log(11222222111)// 判断是Android
var main = plus.android.runtimeMainActivity();
var pkName = main.getPackageName();
var uid = main.getApplicationInfo().plusGetAttribute("uid");
var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
//android.support.v4升级为androidx
if (NotificationManagerCompat == null) {
NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
}
var areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
// 未开通‘允许通知’权限,则弹窗提醒开通,并点击确认后,跳转到系统设置页面进行设置
if (!areNotificationsEnabled) {
uni.showModal({
title: '通知权限开启提醒',
content: '您还没有开启通知权限,无法接受到消息通知,请前往设置并把所有关于消息推送的权限都设置为开启状态!',
showCancel: false,
confirmText: '去设置',
success: function(res) {
if (res.confirm) {
var Intent = plus.android.importClass('android.content.Intent');
var Build = plus.android.importClass("android.os.Build");
//android 8.0引导
if (Build.VERSION.SDK_INT >= 26) {
console.log(1)
var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');
intent.putExtra('android.provider.extra.APP_PACKAGE', pkName);
} else if (Build.VERSION.SDK_INT >= 21) { //android 5.0-7.0
console.log(2)
var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');
intent.putExtra("app_package", pkName);
intent.putExtra("app_uid", uid);
} else { //(<21)其他--跳转到该应用管理的详情页
console.log(3)
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
}
// 跳转到该应用的系统通知设置页
main.startActivity(intent);
}
}
});
}
} else if (plus.os.name == 'iOS') { // 判断是ISO
var isOn = undefined;
var types = 0;
var app = plus.ios.invoke('UIApplication', 'sharedApplication');
var settings = plus.ios.invoke(app, 'currentUserNotificationSettings');
if (settings) {
types = settings.plusGetAttribute('types');
plus.ios.deleteObject(settings);
} else {
types = plus.ios.invoke(app, 'enabledRemoteNotificationTypes');
}
plus.ios.deleteObject(app);
isOn = (0 != types);
if (isOn == false) {
uni.showModal({
title: '通知权限开启提醒',
content: '您还没有开启通知权限,无法接受到消息通知,请前往设置!',
showCancel: false,
confirmText: '去设置',
success: function(res) {
if (res.confirm) {
var app = plus.ios.invoke('UIApplication', 'sharedApplication');
var setting = plus.ios.invoke('NSURL', 'URLWithString:', 'app-settings:');
plus.ios.invoke(app, 'openURL:', setting);
plus.ios.deleteObject(setting);
plus.ios.deleteObject(app);
}
}
});
}
}
// #endif
}
3.通知信息图标设置
在manifest.json 源码视图文件中
sdkConfigs节点 --> push节点 --> igexin节点(或者unipush节点) --> icons节点 --> small节点下配置 官网参考文档
"sdkConfigs": {
"push": {
"unipush": {
"icons": { // 推送图片配置
"push": { // push图标,规格与应用图片一致,不配置则默认使用push图标
"ldpi": "可选,48x48",
"mdpi": "可选,64x64",
"hdpi": "可选,96x96",
"xhdpi": "可选,128x128",
"xxhdpi": "可选,192x192",
},
"small": { // 小图标,png格式图片,仅使用alpha图层
"ldpi": "可选,18*18",
"mdpi": "可选,24*24",
"hdpi": "可选,36*36",
"xhdpi": "可选,48*48",
"xxhdpi": "可选,72*72",
"xxxhdpi": "可选,96*96"
},
"description": "推送图标"
},
}
}
}