目录

chen 的个人博客

VX:ZzzChChen
Phone:13403656751
Email:zxydczzs@gmail.com

X

UniPush + Java实现个推。

一、uni-app 端设置

1、打开 HBuilder X,在项目的 manifest.json 中找到 APP 模块配置,右侧将 Push(消息推送)勾选,会自动勾选 uniPush 服务。

image.png

2、点击 uniPush 下方的配置按钮(登录),点击 Uni Push 下的修改应用信息,将右侧内容填好,如果安卓使用的是公共测试证书的话,直接填 B0:1D:06:18:0D:00:3E:79:C7:B9:08:89:93:B8:E5:AE:7A:19:B0:DA:11:61:AA:09:7C:7F:39:8A:6F:51:4F:A7 即可。如果是自有证书,可以去搜查看证书的 sha256,将自己证书的 sha256 填入即可(一定要是 sha256,不要用 sha1)

image.png

输入完成后在 Uni Push 下的 Uni Push,右侧选择配置管理,应用配置,就可以看到所需的一些东西。

image.png

注:ios 需要去重新创建一个推送证书,太繁琐了,后续会发出发布 iosAPP 的教程。

到了这一基本就可以不用靠 Java 来进行简单的推送了,前提是 APP 必须是自定义基座或者云打包的 APP。不能使用公共基座的 APP。

3、点击 Uni Push 右侧“创建推送”下的“通知消息”,平台选择安卓(IOS 需要使用透传消息),输入通知标题和通知内容,目标用户选择 CID 用户,输入 CID 后点击预览。

image.png

CID 获取方式为:在 uni-app 端,使用自定义调试基座获取手机 CID。

1// #ifdef APP-PLUS
2let clientId = plus.push.getClientInfo().clientId;
3console.log(clientId);
4// #endif

获取到 cid 后输入上方图片 CID 的位置,然后点击预览,在测试预览中使用刚刚拿到的 cid 进行测试,点击预览,先不用点击确定。

image.png

查看手机状态栏是否出现通知消息。

4、收到消息通知后在 uniapp 项目的 app.vue 中需要监听消息通知。

 1onLaunch: function() {
 2			// #ifdef APP-PLUS
 3			let _this = this;
 4			let clientInfo = plus.push.getClientInfo();
 5			plus.push.addEventListener("click", function(msg) {
 6				uni.getStorage({
 7					key: 'ttoken',
 8					success() {
 9
10						if (msg.hasOwnProperty("aps")) {
11							if (msg.aps == null) {
12								let payloadJSON = JSON.parse(msg.payload);
13								if (payloadJSON.id != 0) {
14									uni.navigateTo({
15										url: '/subPackage/pages/houses/newDetails?id=' + payloadJSON.id +
16											'&houseName=' + encodeURI(payloadJSON.houseName) +
17											'&planId=' + payloadJSON.planId
18									})
19								} else {
20									uni.switchTab({
21										url: '/pages/floor/index'
22									})
23								}
24							} else {
25								if (msg.payload.id != 0) {
26									uni.navigateTo({
27										url: '/subPackage/pages/houses/newDetails?id=' + msg.payload.id +
28											'&houseName=' + encodeURI(msg.payload.houseName) +
29											'&planId=' + msg.payload.planId
30									})
31								}
32							}
33						} else {
34							if (msg.payload.hasOwnProperty("id")) {
35								if (msg.payload.id != 0) {
36									uni.navigateTo({
37										url: '/subPackage/pages/houses/newDetails?id=' + msg.payload.id +
38											'&houseName=' + encodeURI(msg.payload.houseName) +
39											'&planId=' + msg.payload.planId,
40									})
41								} else {
42									uni.switchTab({
43										url: '/pages/floor/index'
44									})
45								}
46							}
47						}
48					},
49					fail() {
50						uni.showToast({
51							title: '请先登录',
52							icon: 'none',
53							duration: 800
54						})
55					}
56				})
57			}, false);
58
59			plus.push.addEventListener("receive", function(msg) {
60				if (msg.hasOwnProperty("type") && msg.payload != null) {
61					var options = {
62						cover: false
63					};
64					plus.push.createMessage(msg.content, JSON.stringify(msg.payload), options);
65				}
66			}, false);

二、Java 端设置

1、pom.xml

添加

1<repositories>
2        <repository>
3            <id>getui-nexus</id>
4            <url>http://mvn.gt.getui.com/nexus/content/repositories/releases/</url>
5        </repository>
6    </repositories>
1<dependency>
2            <groupId>com.gexin.platform</groupId>
3            <artifactId>gexin-rp-sdk-http</artifactId>
4            <version>4.1.2.0</version>
5        </dependency>

懒得解释直接贴代码

  1package com.fuyoust.base.utils.AppPush;
  2
  3import com.alibaba.fastjson.JSON;
  4import com.alibaba.fastjson.JSONObject;
  5import com.fuyoust.base.model.TbAppClientInfo;
  6import com.fuyoust.base.model.TbOfShanheHostBox.TbPlan;
  7import com.gexin.rp.sdk.base.IPushResult;
  8import com.gexin.rp.sdk.base.impl.ListMessage;
  9import com.gexin.rp.sdk.base.impl.Target;
 10import com.gexin.rp.sdk.base.notify.Notify;
 11import com.gexin.rp.sdk.base.payload.APNPayload;
 12import com.gexin.rp.sdk.dto.GtReq;
 13import com.gexin.rp.sdk.http.IGtPush;
 14import com.gexin.rp.sdk.template.StartActivityTemplate;
 15import com.gexin.rp.sdk.template.TransmissionTemplate;
 16import com.gexin.rp.sdk.template.style.Style0;
 17
 18import java.util.ArrayList;
 19import java.util.HashMap;
 20import java.util.List;
 21import java.util.Map;
 22
 23/**
 24 * @author ZhangXiaoYu
 25 * @date 2021/4/1 10:47
 26 */
 27public class SensorPush {
 28    private final String appId = "";
 29    private final String appKey = "";
 30    private final String masterSecret = "";
 31    private final String url = "http://sdk.open.api.igexin.com/apiex.htm";
 32    private final String appName = "";
 33    private final String packageName = "";
 34
 35    private List<TbAppClientInfo> clientInfos;
 36    private String message;
 37    private TbPlan tbPlan;
 38    private String deviceName;
 39
 40    public SensorPush(List<TbAppClientInfo> clientInfos, String message, TbPlan tbPlan, String deviceName) {
 41        this.clientInfos = clientInfos;
 42        this.message = message;
 43        this.tbPlan = tbPlan;
 44        this.deviceName = deviceName;
 45    }
 46
 47    /**
 48     * 善禾传感器触发推送手机状态栏通知
 49     *
 50     * @param:  clientInfos:发送人群
 51     *          message:推送的消息
 52     *          tbPlan:设备所在房间
 53     *          deviceName:设备名称
 54     *
 55     * @return  contentId:消息唯一ID
 56     *          pushType:推送的类型,toSingle为单推,toList为批量推,toApp为给全部用户推送
 57     *          expireTime:消息到期时间
 58     */
 59    public Map<String, Object> sensorMsgPushApp() {
 60        IGtPush push = new IGtPush(url, appKey, masterSecret);
 61        //1、设置消息主内容
 62        String content = deviceName + ":" + message + "! 点此查看 >";
 63        //2、获取模板
 64        TransmissionTemplate template = getTemplate(tbPlan, content, getAPNPayload(tbPlan, content));
 65        //3、创建消息
 66        ListMessage message = getMessage(template);
 67        //4、筛选发送人群
 68        List<Target> targets = getTargets(clientInfos);
 69        //5、发送
 70        String contentId = push.getContentId(message);
 71        IPushResult iPushResult = push.pushMessageToList(contentId, targets);
 72
 73        String resultStr = iPushResult.getResponse().toString();
 74        Map<String, Object> resultMap = new HashMap<>();
 75        resultMap.put("contentId", contentId);
 76        resultMap.put("pushType", "toList");
 77        resultMap.put("expireTime", message.getOfflineExpireTime());
 78        resultMap.put("result",resultStr);
 79        return resultMap;
 80
 81    }
 82
 83    /**
 84     *
 85     * @param clientInfos 发送人群
 86     * @return  Target列表
 87     */
 88    public List<Target> getTargets(List<TbAppClientInfo> clientInfos){
 89        List<Target> targets = new ArrayList<>();
 90        for (TbAppClientInfo client : clientInfos) {
 91            Target target = new Target();
 92            target.setAppId(appId);
 93            target.setClientId(client.getClientId());
 94            targets.add(target);
 95        }
 96        return targets;
 97    }
 98
 99    /**
100     * 创建消息
101     *
102     * @param template 透传模板
103     * @return  消息
104     */
105    public ListMessage getMessage(TransmissionTemplate template){
106        ListMessage message = new ListMessage();
107        message.setData(template);
108        message.setOffline(true);//消息是否离线
109        message.setOfflineExpireTime(3600000 * 24);//消息到期时间一天
110        return message;
111    }
112
113    /**
114     * 创建模板
115     *
116     * @param tbPlan    房间信息
117     * @param content   消息主体内容
118     * @param payload   ios离线通知
119     * @return 透传模板
120     */
121    public TransmissionTemplate getTemplate(TbPlan tbPlan, String content, APNPayload payload) {
122        TransmissionTemplate template = new TransmissionTemplate();
123        template.setAppkey(appKey);
124        template.setAppId(appId);
125        template.setTransmissionType(2);
126
127        Map<String, Object> payloadMap = new HashMap<>();
128        Map<String, Object> contentMap = new HashMap<>();
129
130        if (tbPlan == null) {
131            payloadMap.put("id", "0");
132        } else {
133            payloadMap.put("id", tbPlan.getIdx());
134            payloadMap.put("houseName", tbPlan.getName());
135            payloadMap.put("planId", tbPlan.getId());
136        }
137
138        String title = "";
139        contentMap.put("title", title);
140        contentMap.put("content", content);
141        contentMap.put("payload", payloadMap);
142        JSONObject contentStr = new JSONObject(contentMap);
143
144        template.setTransmissionContent(contentStr.toString());
145        template.setAPNInfo(payload);
146
147        Notify notify = new Notify();
148        notify.setTitle("");
149        notify.setContent(content);
150
151        String payloadStr = new JSONObject(payloadMap).toString();
152
153        notify.setPayload(payloadStr);
154        notify.setType(GtReq.NotifyInfo.Type._intent);
155
156        String intent = "intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=" + packageName + "/io.dcloud.PandoraEntry;" +
157                "S.UP-OL-SU=true;S.title=" + appName + ";S.content=" + message + ";S.payload=" + payloadStr + ";end";
158
159        notify.setIntent(intent);
160        template.set3rdNotifyInfo(notify);
161
162        return template;
163    }
164
165    /**
166     * 创建ios离线APN通知
167     *
168     * @param tbPlan    房间信息
169     * @param content   消息主体内容
170     * @return  APNPayload
171     */
172    public APNPayload getAPNPayload(TbPlan tbPlan, String content) {
173        APNPayload payload = new APNPayload();
174        if (tbPlan == null) {
175            payload.addCustomMsg("id", "0");
176        } else {
177            payload.addCustomMsg("id", tbPlan.getIdx());
178            payload.addCustomMsg("houseName", tbPlan.getName());
179            payload.addCustomMsg("planId", tbPlan.getId());
180        }
181        payload.setContentAvailable(0);
182        payload.setSound("default");
183        payload.setAutoBadge("0");
184
185        payload.setAlertMsg(getAlertMsg(content));
186
187        return payload;
188    }
189
190    public APNPayload.DictionaryAlertMsg getAlertMsg(String content) {
191        APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
192        alertMsg.setTitle("");
193        alertMsg.setBody(content);
194        return alertMsg;
195    }
196}

注:

1、模板选择

安卓和 ios 统一使用一个模板“TransmissionTemplate”,上方的 appid、appKey、masterSecret,在 UniPush 中获取。

image.png

2、APNPayload 是 ios 专用离线推送。

3、Notify 是配置安卓离线推送的,

三、厂家配置

依此申请各个平台的开发者账号,这里使用华为和 oppo 来举例。注意,需要 APP 上线在华为应用市场中。

image.png

1、华为

打开华为推送后台

https://developer.huawei.com/consumer/cn/devunion/openPlatform/html/memberCenter.html#/serviceCards/

选择“开发服务下的 PUSH”,进去后选择自己的 APP 项目,点击左上角的项目设置。框选中的就是华为推送需要的必须项。

image.png

image.png

注意将 agconnect-services.json 文件从华为推送那里下载出来,appId、appSecret 拿到。SHA256 证书指纹就是上面用到的 SHA256 证书指纹。

2、OPPO

https://open.oppomobile.com/newservice/capability?pagename=push

点击申请接入,一样需要自己的 APP 已经上线,这里说一下 OPPO 这边,如果你在华为应用商城上线的话,即使没有在 oppo 中上线,也是可以在 oppo 应用市场搜索到你的 APP 的,然后可以在 OPPO 开发者平台中使用包名和证书啥的将 APP 认领在自己的开发者账户下。

认领流程:https://open.oppomobile.com/wiki/doc#id=10182

image.png

点击消息推送,然后点击自己的 APP,将所需要的的秘钥拿到。

image.png

这边说的需要申请开通消息推送权限,跟着 oppo 的文档走就行,审核速度很快。


标题:UniPush + Java实现个推。
作者:zzzzchen
地址:https://www.dczzs.com/articles/2021/04/22/1619094941854.html