小菜之前因業務需求,配合過推送平臺的相關搭建,其中涉及過 友盟 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 回調中進行監聽;
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 點擊時回調,業務處理主要是在該回調方法中完成;
/**
* 通知展示
* @param notifiShowedRlt 包含通知的內容
*/
@Override
public void onNotificationShowedResult(Context context, XGPushShowedResult notifiShowedRlt) {
if (context == null || notifiShowedRlt == null) {
return;
}
Log.e("通知類 Push", "onNotificationShowedResult\n"
+ 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,需要自己根據業務來處理;
/**
* 消息透傳處理
* @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 最基礎的推送功能,對於高級的用戶標籤暫未涉及,同時對【實時推送效果分析】後臺觀察不足;同時涉及到其他廠商的推送模塊,小菜僅以基礎程序員角度學習和了解,並未涉及任何商業優劣區分;如有錯誤,請多多指導!
來源: 阿策小和尚