一、UNIPUSH 简介

UNIPUSH 是 DCloud 联合个推公司推出的集成型统一推送服务,它整合了苹果、华为、小米、OPPO、VIVO、魅族、谷歌 FCM 等手机厂商的系统级推送以及个推等第三方推送 。在国内 Android 的消息推送领域,由于 Google 的 Push 服务 FCM 被墙,各手机厂商各自为政,导致推送市场较为混乱。如果仅依赖第三方推送,在很多国产手机上会因节电设置无法保活推送进程,使得消息无法送达;而要是集成每个安卓手机厂商的官方 Push SDK,不仅工作量巨大,管理和维护也极为麻烦。

UNIPUSH 很好地解决了这些问题,开发者只需进行一次开发,系统就能在不同手机上自动选择最可靠的推送通道来发送消息,极大地保障了送达率。同时,它还降低了开发成本,并且完全免费,是当前消息推送的理想解决方案。接下来,我们就详细介绍如何在安卓端实现 UNIPUSH 的对接。

二、前期准备

(一)注册与账号认证

首先,我们需要注册 Dcloud 开发者账号。访问 Dcloud 开发者中心官网(

https://dev.dcloud.net.cn/

 ),点击注册按钮,按照提示填写邮箱、密码等信息完成注册。注册成功后,登录账号,系统会提示进行实名认证,这是使用 UNIPUSH 的必要步骤,根据系统提示上传身份证照片等相关信息完成实名认证。

(二)环境搭建

后端

安装 JDK

从 Oracle 官网(

https://www.oracle.com/java/technologies/javase-downloads.html

 )下载适合你操作系统的 JDK 安装包。下载完成后,双击安装包进行安装,安装过程中可以选择默认安装路径,也可以自定义路径,但要注意路径不要包含中文和特殊字符。

配置环境变量

以 Windows 系统为例,右键点击 “此电脑”,选择 “属性”,在弹出的窗口中点击 “高级系统设置”,然后点击 “环境变量” 按钮。在 “系统变量” 中,新建一个变量名为 “JAVA_HOME”,变量值为 JDK 的安装路径,例如 “C:\Program Files\Java\jdk1.8.0_311”(根据你实际安装路径填写)。接着找到 “Path” 变量,点击编辑,在变量值的末尾添加 “;% JAVA_HOME%\bin;% JAVA_HOME%\jre\bin”(注意前面的分号)。最后新建一个变量名为 “CLASSPATH”,变量值为 “.;% JAVA_HOME%\lib;% JAVA_HOME%\lib\dt.jar;% JAVA_HOME%\lib\tools.jar”(开头的点表示当前目录)。配置完成后,打开命令提示符,输入 “java -version”,如果显示 JDK 的版本信息,则说明环境变量配置成功。

创建 Java 项目

可以使用 IntelliJ IDEA、Eclipse 等 Java 开发工具。以 IntelliJ IDEA 为例,打开 IDEA,点击 “Create New Project”,在弹出的窗口中选择 “Maven” 项目,然后点击 “Next”,填写项目的 GroupId 和 ArtifactId 等信息,点击 “Finish” 即可创建一个新的 Java 项目。

前端

安装 HBuilderX

访问 HBuilderX 官网(

https://www.dcloud.io/hbuilderx.html

 ),下载适合你操作系统的安装包。下载完成后,解压安装包,找到 “HBuilderX.exe” 文件,双击运行即可。

创建 UNIAPP 项目

打开 HBuilderX,点击菜单栏中的 “文件”->“新建”->“项目”,在弹出的窗口中选择 “uni-app”,然后填写项目名称和项目路径,选择一个模板(如默认模板),点击 “创建” 按钮即可创建一个新的 UNIAPP 项目。

三、后端接口定义(JAVA 语言)

(一)引入依赖

如果使用 Maven 项目,在项目的pom.xml文件中添加 UNIPUSH 相关依赖。在标签内添加如下代码:

com.dcloud

unipush-java-sdk

具体版本号

这里的具体版本号需要根据实际情况填写,你可以前往 Maven 仓库(

https://mvnrepository.com/

 )搜索unipush-java-sdk获取最新版本号。

如果使用 Gradle 构建项目,在build.gradle文件中添加依赖:

implementation 'com.dcloud:unipush-java-sdk:具体版本号'

同样,将具体版本号替换为实际的版本。添加依赖后,Maven 或 Gradle 会自动下载相关的库文件及其依赖。

(二)接口代码实现

定义接口方法

在 Java 项目中,我们可以创建一个控制器类(例如PushController)来定义发送推送消息的接口方法。以下是一个简单的示例:

import org.springframework.web.bind.annotation.*;

@RestController

@RequestMapping("/push")

public class PushController {

@PostMapping("/send")

public String sendPushMessage(@RequestBody PushRequest request) {

// 这里开始处理推送逻辑,返回值暂时为String类型,用于返回推送结果相关信息

return "待实现推送逻辑";

}

}

class PushRequest {

private String title;

private String content;

// 可以根据需要添加更多参数,如目标用户ID、设备ID等

// 此处省略Getter和Setter方法

}

在上述代码中,@RestController注解表示这是一个 RESTful 风格的控制器,@RequestMapping("/push")定义了该控制器的基础路径。sendPushMessage方法使用@PostMapping("/send")注解,表示处理/push/send路径的 POST 请求,@RequestBody用于接收前端传递的 JSON 格式数据,并将其映射到PushRequest对象中。

调用 UNIPUSH 服务

在sendPushMessage方法中,我们需要调用 UNIPUSH 的服务来实现消息推送逻辑。首先,需要初始化 UNIPUSH 客户端,并设置相关的配置信息,如 AppKey 和 AppSecret。假设我们已经在配置文件中配置了这些信息,通过 Spring 的@Value注解来获取:

import com.dcloud.unipush.sdk.UnipushClient;

import com.dcloud.unipush.sdk.PushPayload;

import com.dcloud.unipush.sdk.response.PushResponse;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.web.bind.annotation.*;

@RestController

@RequestMapping("/push")

public class PushController {

@Value("${unipush.appKey}")

private String appKey;

@Value("${unipush.appSecret}")

private String appSecret;

@PostMapping("/send")

public String sendPushMessage(@RequestBody PushRequest request) {

UnipushClient client = new UnipushClient(appKey, appSecret);

PushPayload payload = new PushPayload();

payload.setTitle(request.getTitle());

payload.setContent(request.getContent());

// 根据需要设置更多的推送参数,如设置目标用户ID、设备ID等

// payload.setUserId("user123");

// payload.setPushClientId("device123");

try {

PushResponse response = client.push(payload);

if (response.isSuccess()) {

return "推送成功";

} else {

return "推送失败,错误信息:" + response.getErrorMsg();

}

} catch (Exception e) {

e.printStackTrace();

return "推送过程中出现异常:" + e.getMessage();

}

}

}

class PushRequest {

private String title;

private String content;

// 省略Getter和Setter方法

}

在上述代码中,首先通过@Value注解从配置文件中获取unipush.appKey和unipush.appSecret。然后创建UnipushClient客户端实例,接着创建PushPayload对象并设置推送的标题和内容等信息 。最后调用client.push(payload)方法发送推送请求,并根据返回的PushResponse对象判断推送是否成功。如果成功,返回 “推送成功”;如果失败,返回失败原因;如果在推送过程中出现异常,捕获异常并返回异常信息。

四、前端开发(Hbuilder 创建 UNIAPP)

(一)manifest.json 配置

打开 HBuilderX,在项目中找到manifest.json文件,双击打开。在App模块配置中,找到Push(消息推送)选项并勾选 ,然后点击uniPush下的 “配置” 链接。这将跳转到 Dcloud 开发者中心的 UniPush 配置页面。在该页面,按照提示填写相关信息,如应用名称、包名等。需要注意的是,包名要与你在云打包时设置的 Android 包名一致。同时,关联你的服务空间,这一步是为了将你的应用与 UniPush 的推送服务进行关联。如果是初次开通 uni - push,还需要按照提示向个推同步手机号信息。完成所有信息填写后,点击保存。 回到manifest.json文件,确保uniPush配置项中已正确显示你在开发者中心配置的信息,例如:

"uniPush": {

"appId": "你的AppId",

"appKey": "你的AppKey",

"channel": "你的渠道",

"production": false

}

这里的appId、appKey、channel等信息是在开发者中心配置后自动生成或获取的,production表示是否为生产环境,false表示开发环境。 配置完成后,manifest.json文件会保存这些配置信息,在后续打包和运行应用时,这些配置将用于初始化 UniPush 推送功能。

(二)获取设备标识

在App.vue文件中,我们使用plus.push.getClientInfoAsync方法来获取设备唯一推送标识(cid)。在onLaunch生命周期函数中添加如下代码:

export default {

onLaunch: function() {

plus.push.getClientInfoAsync(function(info) {

if (info.clientid) {

// 将cid存储到本地缓存中,方便后续使用

uni.setStorageSync('cid', info.clientid);

console.log('clientid', info.clientid);

// 这里可以将cid传递给后端,假设我们有一个方法sendCidToServer来处理传递逻辑

this.sendCidToServer(info.clientid);

} else {

console.log('获取cid失败');

}

}, function(e) {

console.log('获取cid出错', JSON.stringify(e));

});

},

methods: {

sendCidToServer(cid) {

// 这里可以使用uni.request等方法将cid发送给后端接口

uni.request({

url: '你的后端接收cid的接口地址',

method: 'POST',

data: {

cid: cid

},

success: function(res) {

console.log('cid发送成功', res.data);

},

fail: function(err) {

console.log('cid发送失败', err);

}

});

}

}

}

在上述代码中,plus.push.getClientInfoAsync方法是一个异步方法,第一个参数是成功回调函数,当成功获取到设备标识info.clientid时,将其存储到本地缓存中,并调用sendCidToServer方法将其传递给后端;第二个参数是失败回调函数,当获取 cid 失败时,会在控制台打印错误信息。sendCidToServer方法使用uni.request向指定的后端接口发送 POST 请求,将 cid 作为数据传递给后端。

(三)监听推送消息

在线消息监听

当应用处于前台运行时,我们可以监听在线推送消息。在App.vue的onLaunch生命周期函数中添加如下代码:

export default {

onLaunch: function() {

// 监听在线消息

plus.push.addEventListener('receive', function(msg) {

console.log('receive在线消息', msg);

// 这里可以根据接收到的消息内容进行相应的处理,比如显示通知

let payload = msg.payload;

// 假设消息体中包含title和content字段,用于显示通知

if (payload.title && payload.content) {

// 使用plus.push.createMessage方法创建通知栏消息

plus.push.createMessage(payload.content, payload, {

title: payload.title,

sound:'system' // 使用系统默认声音

});

}

}, false);

}

}

在上述代码中,plus.push.addEventListener('receive', callback, false)用于监听在线消息,当接收到在线推送消息时,会触发回调函数callback。在回调函数中,msg参数包含了接收到的消息内容,我们可以从msg.payload中获取消息的具体数据。这里假设消息体中包含title和content字段,然后使用plus.push.createMessage方法创建一个通知栏消息,将消息内容显示在通知栏中。

离线消息处理

当应用处于后台或关闭状态时,用户点击离线推送消息时,我们可以监听点击事件并进行相应的操作。同样在App.vue的onLaunch生命周期函数中添加如下代码:

export default {

onLaunch: function() {

// 监听离线消息点击事件

plus.push.addEventListener('click', function(msg) {

console.log('click离线消息点击', msg);

let payload = msg.payload;

// 根据消息携带的信息进行页面跳转等操作

if (payload && payload.page) {

// 假设消息体中包含page字段,用于指定跳转的页面路径

uni.navigateTo({

url: payload.page

});

} else {

// 如果没有指定页面,则跳转到默认页面

uni.switchTab({

url: '/pages/home/home' // 假设默认页面路径为/pages/home/home

});

}

}, false);

}

}

在上述代码中,plus.push.addEventListener('click', callback, false)用于监听离线消息的点击事件,当用户点击离线推送消息时,会触发回调函数callback。在回调函数中,从msg.payload中获取消息携带的数据,这里假设消息体中包含page字段,用于指定需要跳转的页面路径,然后使用uni.navigateTo方法进行页面跳转;如果消息体中没有page字段,则使用uni.switchTab方法跳转到默认页面。

五、安卓端对接整合

(一)开通 UNIPUSH 服务

登录 Dcloud 开发者中心(

https://dev.dcloud.net.cn/

 ),进入 “我的应用” 页面,找到你要开通 UNIPUSH 服务的应用,点击进入应用详情页。

在应用详情页中,找到 “Unipush” 选项卡并点击进入。

首先填写安卓应用信息,包括应用名称(确保与你的应用实际名称一致)。

配置安卓包名:安卓包名是应用在安卓系统中的唯一标识,需要确保其唯一性。通常使用反域名命名规则,例如如果你的公司域名为

example.com

,包名可以设置为com.example.yourappname。在 HBuilderX 中,你可以在manifest.json文件的 “App 常用其他设置” 中找到 “Android 包名” 进行设置,也可以在云打包时进行配置。

配置安卓签名:如果在云打包时使用 DCloud 公用证书,可输入BA:AD:09:3A:82:82:9F:B4:32:A7:B2:8C:B4:CC:F0:E9:F3:7D:AE:58 。若使用自有证书,需使用 JDK 中自带的keytool工具查看证书信息。具体步骤如下:

打开命令提示符(Windows)或终端(Mac/Linux)。

进入keytool所在目录,一般在 JDK 的bin目录下,例如C:\Program Files\Java\jdk1.8.0_311\bin(根据你实际的 JDK 安装路径)。

执行命令keytool -list -v -keystore {your_app}.keystore,其中{your_app}.keystore是你的证书文件名称,执行命令后输入证书密码,即可查看证书的详细信息,包括签名。将签名信息填写到 Dcloud 开发者中心的对应位置。

完成上述信息填写后,点击 “开通” 按钮,即可成功开通 UNIPUSH 服务。

(二)云函数配置(若有需要)

如果你的项目使用了 uniCloud,可以通过云函数来实现消息推送功能。

创建云函数

在 HBuilderX 中,右键点击项目中的uniCloud目录,选择 “新建云函数 / 云对象”,输入云函数名称,例如 “pushFunction”,然后点击 “创建”。

添加依赖

在创建好的云函数目录下,右键点击package.json文件,选择 “添加公共模块或扩展库依赖”,在弹出的窗口中搜索并勾选 “uni-cloud-push”,然后点击 “确定”。这将在package.json文件中添加uni-cloud-push依赖,如下所示:

{

"name": "pushFunction",

"version": "1.0.0",

"description": "",

"main": "index.js",

"extensions": {

"uni-cloud-push": {}

},

"author": ""

}

配置云函数实现消息推送

在云函数的index.js文件中编写代码,实现消息推送逻辑。以下是一个示例代码:

'use strict';

const uniPush = uniCloud.getPushManager({

appId: '__UNI__你的AppId' // 替换为你的应用AppId

});

exports.main = async (event, context) => {

let obj = JSON.parse(event.body);

const res = await uniPush.sendMessage({

"push_clientid": obj.cids, // 设备id,支持多个以数组的形式指定多个设备,如["cid-1","cid-2"],数组长度不大于1000

"title": obj.title, // 标题

"content": obj.content, // 内容

"payload": obj.data, // 数据

"force_notification": true, // 服务端推送需要加这一句

"request_id": obj.request_id //请求唯一标识号,10 - 32位之间;如果request_id重复,会导致消息丢失

});

return res;

};

在上述代码中,首先通过uniCloud.getPushManager获取uniPush实例,并传入应用的AppId。然后在main函数中,解析前端传递过来的参数event.body,并调用uniPush.sendMessage方法发送推送消息。其中,push_clientid是设备的唯一标识(即之前在前端获取的 cid),title是推送消息的标题,content是内容,payload是携带的数据,force_notification表示这是服务端推送,request_id是请求唯一标识号,用于保证消息的唯一性。

上传部署云函数

编写完云函数代码后,右键点击云函数目录,选择 “上传并运行”,将云函数部署到 uniCloud 服务器上。部署成功后,在 uniCloud 控制台的 “云函数列表” 中可以看到该云函数。

(三)打包与测试

打包成安卓应用

在 HBuilderX 中,点击菜单栏中的 “发行”->“原生 App 云打包”。

在弹出的 “云打包” 窗口中,首先选择 “使用自有证书”(如果之前在 Dcloud 开发者中心配置了云端证书,也可以选择 “使用云端证书”)。

填写安卓包名,确保与之前在 Dcloud 开发者中心和manifest.json文件中配置的包名一致。

输入证书别名、证书私钥密码(这些信息在你生成安卓证书时会记录下来),并选择证书文件(.keystore 文件)。

点击 “打包” 按钮,HBuilderX 会将你的 UNIAPP 项目上传到云端进行打包,打包过程可能需要几分钟时间,你可以在 “发行”->“查看云打包状态” 中查看打包进度。

打包完成后,会在 HBuilderX 的控制台中显示下载链接,点击链接即可下载生成的安卓应用安装包(.apk 文件)。

测试消息推送

将生成的安卓应用安装包(.apk 文件)通过数据线传输到安卓设备上,或者使用一些应用管理工具(如应用宝、360 手机助手等)进行安装。

安装完成后,打开应用,应用会在启动时获取设备的唯一推送标识(cid),并将其存储到本地缓存或发送给后端(根据之前前端代码的逻辑)。

发送测试消息:如果是通过后端接口发送推送消息,使用 Postman 等工具,向之前定义的后端推送接口(如/push/send)发送 POST 请求,请求体中包含推送的标题、内容等信息,例如:

{

"title": "测试推送标题",

"content": "测试推送内容"

}

如果是通过云函数发送推送消息,可以在 uniCloud 控制台中,找到之前部署的云函数,点击 “测试” 按钮,在弹出的测试窗口中输入参数,例如:

{

"cids": ["你的设备cid"],

"title": "测试推送标题",

"content": "测试推送内容",

"data": {},

"request_id": "12345678901234567890"

}

其中,cids是设备的 cid,request_id是唯一标识号。

检查设备是否能正确接收和处理消息:在安卓设备上,观察通知栏是否收到推送消息。如果应用处于前台运行,在线消息会通过之前在App.vue中设置的监听函数进行处理,例如显示通知等;如果应用处于后台或关闭状态,离线消息会在用户点击通知时,通过相应的点击事件监听函数进行处理,例如跳转到指定页面等。同时,在设备的日志中(可以通过 USB 连接设备到电脑,使用 Android Studio 等工具查看日志),也可以查看消息推送的相关日志,以便排查问题。

六、常见问题与解决方法

在使用 UNIPUSH 进行安卓端消息推送对接过程中,可能会遇到以下一些常见问题及相应的解决方法:

(一)消息接收不到

原因

设备标识(cid)获取或传递错误。在前端获取 cid 时出现异常,或者获取后没有正确传递给后端,导致后端推送时无法指定目标设备。

解决方法

在前端App.vue中,检查plus.push.getClientInfoAsync方法的回调函数,确保成功获取 cid 后正确存储和传递。可以在获取 cid 的代码处添加更多的日志输出,例如:

plus.push.getClientInfoAsync(function(info) {

if (info.clientid) {

console.log('成功获取cid:', info.clientid);

uni.setStorageSync('cid', info.clientid);

this.sendCidToServer(info.clientid);

} else {

console.log('获取cid失败');

}

}, function(e) {

console.log('获取cid出错', JSON.stringify(e));

});

在后端接收 cid 的接口处,也添加日志记录,确认是否正确接收到 cid。

原因

推送配置信息错误,如 AppKey、AppSecret 等。如果在后端配置文件中配置的 AppKey 和 AppSecret 与 Dcloud 开发者中心的不一致,会导致推送请求无法通过认证。

解决方法

仔细核对 Dcloud 开发者中心的应用配置信息,确保在后端代码中通过@Value注解获取的unipush.appKey和unipush.appSecret与开发者中心的一致。可以在获取这些值的代码处添加打印输出,例如:

@Value("${unipush.appKey}")

private String appKey;

@Value("${unipush.appSecret}")

private String appSecret;

@PostMapping("/send")

public String sendPushMessage(@RequestBody PushRequest request) {

System.out.println("当前使用的appKey: " + appKey);

System.out.println("当前使用的appSecret: " + appSecret);

// 后续推送逻辑代码

}

原因

手机系统设置限制了应用接收推送消息。一些安卓手机的系统设置中,会默认限制某些应用的消息推送,例如禁止应用在后台运行时接收推送。

解决方法

在应用首次启动时,引导用户前往手机系统设置,开启应用的消息推送权限。可以在App.vue的onLaunch生命周期函数中添加提示代码,例如:

export default {

onLaunch: function() {

// 检查是否已经开启推送权限,这里假设我们有一个方法checkPushPermission来检查权限

if (!this.checkPushPermission()) {

uni.showModal({

title: '提示',

content: '为了正常接收推送消息,请前往系统设置开启本应用的消息推送权限',

showCancel: false,

success: function(res) {

if (res.confirm) {

// 这里可以根据不同的安卓系统版本,引导用户前往对应的设置页面

// 例如对于华为手机,可以使用uni.openSetting({url: 'package:com.huawei.android.settings'});

}

}

});

}

},

methods: {

checkPushPermission() {

// 这里实现检查推送权限的逻辑,返回true或false

return false;

}

}

}

(二)配置错误

原因

manifest.json文件中uniPush配置项错误。例如,appId、appKey、channel等信息填写错误,或者遗漏了某些必要的配置项。

解决方法

再次核对 Dcloud 开发者中心的配置信息,确保manifest.json文件中的uniPush配置项与之一致。可以在 HBuilderX 中,右键点击manifest.json文件,选择 “可视化编辑”,在图形化界面中检查和修改配置项,确保没有拼写错误或遗漏。

原因

云函数配置错误,如依赖添加不正确、函数代码逻辑错误等。如果在云函数中添加uni-cloud-push依赖时出现问题,或者云函数代码中调用推送接口的参数错误,会导致推送失败。

解决方法

在云函数的package.json文件中,检查uni-cloud-push依赖的版本是否正确,并且确保依赖已经成功安装。可以在云函数目录下,打开命令行,执行npm install命令,重新安装依赖。在云函数的index.js文件中,仔细检查代码逻辑,特别是调用uniPush.sendMessage方法时的参数设置,确保与文档要求一致。可以在代码中添加更多的日志输出,以便调试,例如:

exports.main = async (event, context) => {

console.log('接收到的参数:', event.body);

let obj = JSON.parse(event.body);

const res = await uniPush.sendMessage({

"push_clientid": obj.cids,

"title": obj.title,

"content": obj.content,

"payload": obj.data,

"force_notification": true,

"request_id": obj.request_id

});

console.log('推送结果:', res);

return res;

};

通过上述常见问题的排查与解决方法,希望能帮助大家顺利完成 UNIPUSH 在安卓端的消息推送对接工作。如果在实际操作中遇到其他问题,还可以查阅 Dcloud 官方文档、社区论坛等获取更多的帮助。

七、总结

通过以上步骤,我们详细介绍了如何使用 UNIPUSH 实现安卓端的消息推送功能。从前期的注册认证、环境搭建,到后端接口的定义和前端代码的编写,再到安卓端的对接整合以及常见问题的解决,整个过程虽然涉及多个环节,但只要按照步骤逐步操作,就能顺利完成。

在实际操作中,要特别注意配置信息的准确性,如 AppKey、AppSecret、包名、签名等,这些信息一旦错误,可能导致消息推送失败。同时,在获取设备标识和监听推送消息时,要确保代码逻辑正确,以便及时、准确地处理推送消息。