和尚之前因业务需求,配合过推送平台的相关搭建,其中涉及过 友盟 UmengPush、极光 JPush、个推、公司自建 UPDPush、华为 HMS、小米 MiPush、OPPO Push 和 VIVO Push 等;今天借 腾讯云 活动,简单了解一下 腾讯移动通讯 TPNS;
和尚了解 腾讯移动通讯 TPNS 前身是腾讯信鸽,前期经过长期等技术沉淀积累了良好的口碑;现在由免费转为付费,相信会提供更优质的服务;而精准用户标签是 TPNS 的一个巨大优势;
1. TPNS 基本介绍
TPNS 为移动推送 Tencent Push Notification Service 首字母缩写,为 app 提供稳定、快速、高抵达的推送服务;具备多种推送形式和方式,支持小米、华为、魅族、vivo、OPPO 等国内主流厂商通道集成,Google 境外支持 FCM 通道,可以做到单推毫秒级抵达;其具备精准用户标签能力,有效助力 app 的精细化运营;
2. TPNS 集成
接下来和尚简单介绍一下 TPNS 的集成,据和尚了解,一般的 Push 接入方式主要是 Gradle 自动集成 和 jar 手动集成 两种;特殊的还有华为 Push 通过 config 方式导入配置方式等;而令和尚意外的是 TPNS 支持三种方式的接入;
和尚主要介绍 config 和 Gradle 自动集成两种方式;两种集成方式都非常简单,同时和尚不得不夸赞一下官网的接入文档,真的非常人性化;
2.1 config 导入配置项
- a. 在 TPNS【基本配置】中下载对应 app 的配置文件,并添加在 app 根目录下;
- b. 在项目级 build.gradle 中添加配置信息;
buildscript {
......
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "com.tencent.android.tpns:tpnsplugin:1.7.0"
}
}
allprojects {
repositories {
......
maven { url 'https://dl.bintray.com/umsdk/release' }
maven {url 'http://developer.huawei.com/repo/'}
}
}
- c. 在应用级 app build.gradle 中添加依赖;
- d. 配置混淆文件;
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep class com.tencent.android.tpush.** {*;}
-keep class com.tencent.tpns.baseapi.** {*;}
-keep class com.tencent.tpns.mqttchannel.** {*;}
-keep class com.tencent.tpns.dataacquisition.** {*;}
2.2 Gradle 自动集成
- a. 在 TPNS【基本配置】中获取对应 app 的 ID 和 KEY;
- b. 在 app build.gradle 文件下配置 ID 和 KEY 以及 SDK 版本;
android {
......
defaultConfig {
applicationId "com.ace.demo01"
......
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
manifestPlaceholders = [
XG_ACCESS_ID : "1500018288",
XG_ACCESS_KEY : "AYFMNKBGT92Z",
]
multiDexEnabled true
}
......
}
dependencies {
......
//添加以下依赖
implementation 'com.tencent.jg:jg:1.1'
implementation 'com.tencent.tpns:tpns:1.2.3.1-release'
}
- c. 配置混淆文件;
3. TPNS 应用
上述只是对 TPNS 的简单集成,对于应用还需要初始化以及接收推送等一系列业务操作;还可以进行一系列复杂操作,比如根据标签自定义定量定向发送 Push 等;和尚仅根据最基础需求进行学习测试;
3.1 初始化获取 Token
集成 TPNS 之后都需要初始化,其中 Token 作为唯一标识可以通过 registerPush 初始化获取,也可以通过继承 XGPushBaseReceiver 广播并在 onRegisterResult 回调中进行监听;
代码语言:javascript复制XGPushManager.registerPush(this, new XGIOperateCallback() {
@Override
public void onSuccess(Object data, int flag) {
//token在设备卸载重装的时候有可能会变
Log.d("TPush:", "注册成功,设备token为:" data);
}
@Override
public void onFail(Object data, int errCode, String msg) {
Log.d("TPush:", "注册失败,错误码:" errCode ",错误信息:" msg);
}
});
@Override
public void onRegisterResult(Context context, int errorCode, XGPushRegisterResult message) {
if (context == null || message == null) {
return;
}
String text = "";
if (errorCode == XGPushBaseReceiver.SUCCESS) {
// 在这里拿token
String token = message.getToken();
text = "注册成功1. token:" token;
} else {
text = message "注册失败,错误码:" errorCode;
}
Log.d(LogTag, text);
}
XGPushBaseReceiver 用于接收消息和结果反馈的 Receiver,需要开发者在 AndroidManifest.xml 自主完成静态注册;不管是通知类 Push 还是透传类 Push 均需通过 XGPushBaseReceiver 中的回调来处理;
3.2 通知类 Push
首先我们需要了解 通知类 Push 发布平台,里面涉及很多内容,其中有几点需要注意:
- 【通知标题】和【通知内容】对应推送消息中展示内容;
- 【高级设置】里面可以通过【附加参数】传递标题和内容之外的其他消息内容,供用户自定义;
- 【推送时间】可以设置立即或延迟推送;
- 【推送目标】可以发布全量 Push 或根据地理围栏定向推送以及根据 Token 固定设备推送;
- 【角标数字】在华为和小米手机开启角标通知权限之后,会自动增加一,而无需用户自己适配,减轻了开发者工作量;
- 【点击打开】TPNS 提供了四种点击 Push 后续操作方式,分别是仅打开应用 app;客户端自定义,此时需要在清单文件中设置 Intent 配置信息;URL 网络路径;应用内 Activity,但官方并不推荐使用,需要设置 Activity 的完整路径;
通知类 Push 收到和点击事件通过 XGPushBaseReceiver 回调进行监听;onNotificationShowedResult 为通知类 Push 展示回调,但和尚反复测试,通知类 Push 中标题和内容只能是 XGPushShowedResult.getTitle() 和 XGPushShowedResult.getContent() 对应内容,无法更改;onNotificationClickedResult 为通知类 Push 点击时回调,业务处理主要是在该回调方法中完成;
代码语言:javascript复制/**
* 通知展示
* @param notifiShowedRlt 包含通知的内容
*/
@Override
public void onNotificationShowedResult(Context context, XGPushShowedResult notifiShowedRlt) {
if (context == null || notifiShowedRlt == null) {
return;
}
Log.e("通知类 Push", "onNotificationShowedResultn"
notifiShowedRlt.getCustomContent()
"n"
notifiShowedRlt.getPushChannel()
"n"
notifiShowedRlt.getNotifactionId()
"n"
notifiShowedRlt.toString());
Log.d(LogTag, "您有1条新消息, 通知被展示;" notifiShowedRlt.toString() ", PushChannel:" notifiShowedRlt.getPushChannel());
}
/**
* 通知点击回调
* actionType=1为该消息被清除,actionType=0为该消息被点击
* @param message 包含被点击通知的内容
*/
@Override
public void onNotificationClickedResult(Context context, XGPushClickedResult message) {
if (context == null || message == null) {
return;
}
String text = "";
if (message.getActionType() == NotificationAction.clicked.getType()) {
// 通知在通知栏被点击
// APP自己处理点击的相关动作
text = "通知被打开 :" message;
} else if (message.getActionType() == NotificationAction.delete.getType()) {
// 通知被清除
// APP自己处理通知被清除后的相关动作
text = "通知被清除 :" message;
}
Toast.makeText(context, "广播接收到通知被点击:" message.toString(), Toast.LENGTH_SHORT).show();
// 获取自定义key-value
String customContent = message.getCustomContent();
if (customContent != null && customContent.length() != 0) {
try {
JSONObject obj = new JSONObject(customContent);
if (!obj.isNull("extras")) {
PushInfo pushInfo = new Gson().fromJson(obj.getString("extras"), PushInfo.class);
if (pushInfo != null) {
Log.e("PushInfo: ", pushInfo.title pushInfo.desc);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(context, PageActivity.class);
intent.putExtra("pushInfo", customContent);
intent.putExtra("from", "通知类消息");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(intent);
}
对于通知类 Push 点击的操作,TPNS 提供了四种默认的方式,但和尚为了适配其他的 Push 类型,调整了点击后的操作,默认为启动 app,之后的业务逻辑通过解析【附加参数】来进行不同的业务处理;例如根据某一个字段不同进行不同页面的跳转等;
3.3 透传类 Push
透传类消息后台相对于通知类型要简单,主要区分在【高级设置】中,透传类因厂商限制,不能通过厂商通道下发,仅通过 TPNS 通道下发;且透传类消息下发之后不会出现 Notification,需要自己根据业务来处理;
代码语言:javascript复制/**
* 消息透传处理
* @param message 解析自定义的 JSON
*/
@Override
public void onTextMessage(Context context, XGPushTextMessage message) {
String text = "收到消息:" message.toString();
// 获取自定义key-value
String customContent = message.getCustomContent();
PushInfo pushInfo = Utils.getPushInfo(customContent);
showNotification(context, getNotification(context, pushInfo, customContent));
}
public static Notification getNotification(Context context, PushInfo pushInfo, String msg) {
Notification notification = null;
try {
Intent intent = new Intent(context, PageActivity.class);
intent.putExtra("pushInfo", msg);
intent.putExtra("from", "透传类消息");
PendingIntent pendingIntent =
PendingIntent.getActivity(context, new java.util.Random().nextInt(1000), intent,
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "ace_push");
notificationBuilder.setContentIntent(pendingIntent);
notificationBuilder.setContentText(pushInfo.desc);
notificationBuilder.setContentTitle(pushInfo.title);
notificationBuilder.setSmallIcon(R.mipmap.icon_logo);
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_logo));
notificationBuilder.setAutoCancel(true);
notificationBuilder.setOngoing(false);
notificationBuilder.setWhen(System.currentTimeMillis());
notificationBuilder.setDefaults(Notification.DEFAULT_ALL);
notification = notificationBuilder.build();
} catch (Exception e) {
e.printStackTrace();
}
return notification;
}
public void showNotification(Context context, Notification notification) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.notify(new java.util.Random().nextInt(1000), notification);
}
}
和尚为了适配多种类型推送消息,通过解析【高级设置】中的【附加参数】中的 Json 来展示通知栏消息;
- Notification 展示在 Android8.0 之后需要设置 NotificationChannel 通道;
- app kill 状态下不会收到透传类消息,需要启动应用之后才会收到消息,包括历史消息;
4. TPNS 小对比
和尚尝试了多家推送模块,简单分析如下:
优势:
- TPNS 集成方式最为丰富和简单;
- TPNS 中的定向标签丰富,推送精准,方便进行更精细化的运营;
- TPNS 统计后台做的最为丰富全面;可以实时统计推送的抵达、展示、点击效果等数据口径,并将以上数据在管理台可视化地展现出来;
不足:
- TPNS 付费模式可能会损失一些中小型 app 用户;
- TPNS 通知类消息未提供消息送达的回调方法,对于 app 自身维度的统计略有不便;
- TPNS 未提及类似【极光轻推送】之类的辅助激活唤醒老用户的功能;
5. TPNS 小建议
TPNS 已经积累了足够的技术沉淀,使用也非常简单,官方文档介绍的非常详细;和尚作为最底层的码农,仅就集成使用过程中提出一点点小小的个人见解,如有错误,请多多指导!
- XGPushBaseReceiver 中是否可以减少抽象方法,对于用户不需要的业务模块,每次实现所有的抽象方法是否略微有些冗余;
public abstract void onRegisterResult(Context var1, int var2, XGPushRegisterResult var3);
public abstract void onUnregisterResult(Context var1, int var2);
public abstract void onSetTagResult(Context var1, int var2, String var3);
public abstract void onDeleteTagResult(Context var1, int var2, String var3);
public abstract void onSetAccountResult(Context var1, int var2, String var3);
public abstract void onDeleteAccountResult(Context var1, int var2, String var3);
public abstract void onSetAttributeResult(Context var1, int var2, String var3);
public abstract void onDeleteAttributeResult(Context var1, int var2, String var3);
public abstract void onTextMessage(Context var1, XGPushTextMessage var2);
public abstract void onNotificationClickedResult(Context var1, XGPushClickedResult var2);
public abstract void onNotificationShowedResult(Context var1, XGPushShowedResult var2);
- 通知类消息在通知栏中的标题和内容无法通过【高级设置】中的【附加参数】来更改;如果用户可以自由的定义设置就更方便了;
- 服务后台中的【推送任务】在历史任务列表中,如果有【复用】的功能的话,会大大减轻开发测试和运营同学的工作量;这个功能在友盟和极光等推送平台都有,真的很方便;
- 希望 TPNS 可以提供类似【极光轻推送】辅助激活唤醒老用户的功能;
和尚仅尝试了 TPNS 最基础的推送功能,对于高级的用户标签暂未涉及,同时对【实时推送效果分析】后台观察不足;同时涉及到其他厂商的推送模块,和尚仅以基础程序员角度学习和了解,并未涉及任何商业优劣区分;如有错误,请多多指导!
来源:阿策小和尚