視頻版講解

Android 推送整合

極光推送

上報 「推送 ID」

在極光提供的onRegister 介面中調用 SensorsDataAPI.sharedInstance().profilePushId("jiguang_id",s)。

推送 ID 的處理 public class MyJPushMessageReceiver extends JPushMessageReceiver { @Override public void onRegister(Context context, String s) { super.onRegister(context, s); -上報極光 "推送 ID"SensorsDataAPI.sharedInstance().profilePushId("jiguang_id",s); }}

在調用神策SDK login 介面之後調用 SensorsDataAPI.sharedInstance().profilePushId("jiguang_id",JPushInterface.getRegistrationID(this))

SensorsDataAPI.sharedInstance().login(userId); - 在調用神策 SDK login 介面後,也需要調用 profilePushId 介面上報極光 "推送 ID"SensorsDataAPI.sharedInstance(). profilePushId("jiguang_id",JPushInterface.getRegistrationID(this))


採集推送點擊事件

神策 Android SDK 可以自動採集來自極光推送的推送點擊事件,請參考此文件開啟採集。

處理推送消息

非廠商通道可以在 onNotifyMessageOpened 介面中處理推送消息

public class MyJPushMessageReceiver extends JPushMessageReceiver { @Override public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) { super.onNotifyMessageOpened(context, notificationMessage); if (notificationMessage == null) return; - 處理神策Sensors Focus 推送的 「開啟 App」、"開啟 URL 消息"、"自定義消息" 的動作handleSensorsFocusPushMessage(notificationMessage.notificationExtras); }}

使用廠商通道的情況下,需要在廠商通道ActivityonCreateonNewIntent 中拿到 intent,解析出相應的參數再處理推送消息

/** * 如果使用了極光 VIP的廠商通道(uri_activity/uri_action),需要在廠商消息打開的 Activity 中處理廠商通道消息。 * 處理廠商通道訊息的點擊事件的 Activity。 */ public class OpenClickActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - 處理廠商通道消息的點擊handlePushOpen(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - 處理廠商通道消息的點擊handlePushOpen(); } /** * 處理廠商通道消息的點擊。 * <p>* 華為通道消息數據:通過 getIntent().getData().toString(); 獲取。 *小米、vivo、OPPO、FCM 通道消息數據 :通過 getIntent().getExtras(). getString("JMessageExtra") 獲取。 * 魅族通道消息數據:通過 onNotifyMessageOpened 獲取。 */ private void handlePushOpen() { try {Intent intent = getIntent(); if (intent == null) { return; }String pushData = null; - 華為通道消息數據 if (getIntent().getData() != null){pushData = getIntent().getData().toString(); } / 小米、vivo、OPPO、FCM 通道訊息資料(魅族會回調 onNotifyMessageOpened ) if (TextUtils.isEmpty(pushData) && getIntent().getExtras() != null) { pushData = getIntent().getExtras().getString("JMessageExtra"); } if (TextUtils.isEmpty(pushData)) { return; }JSONObject jsonObject = new JSONObject(pushData); - 推送消息附加字段String extras = jsonObject.optString("n_extras"); -處理神策智慧運營推送的 「開啟 App」、"開啟 URL " 、"自定義消息" 動作handleSensorsFocusPushMessage(extras); } catch (Exception e) {e.printStackTrace(); }}}


友盟推送

上報 「推送 ID」

IUmengRegisterCallbackonSuccess 介面中調用 SensorsDataAPI.sharedInstance().profilePushId("umeng_id", token)

推送 ID 的處理PushAgent.getInstance(context).register(new IUmengRegisterCallback() { @Override public void onSuccess(String token) {su 上報友盟 "推送 ID"SensorsDataAPI.sharedInstance().profilePush Id("umeng_id", token); } @Override public void onFailure(String s, String s1) {}});

Code Block 1代碼示例 在調用神策 SDK login 介面之後調用 SensorsDataAPI.sharedInstance().profilePushId("umeng_id",PushAgent.getInstance(this) .getRegistrationId())。

SensorsDataAPI.sharedInstance().login(userId); -在調用神策SDK login 介面後,也需要調用 profilePushId 介面上報友盟 "推送 ID" SensorsDataAPI.sharedInstance().profilePushId("umeng_id",PushAgent.getInstance(this).getRegistrationId());


記錄 「推送點擊」事件並處理平臺推送的消息

需要在launchAppopenUrlopenActivitydealWithCustomAction 這 4 個介面中調用 trackAppOpenNotification(uMessage.extra, uMessage.title, uMessage.text) handleSensorsFocusPushMessage(notificationExtras)。

PushAgent.getInstance(context).setNotificationClickHandler(new UmengNotificationClickHandler() { @Override public void launchApp(Context context, UMessage uMessage) { super.launchApp(context, uMessage); - 觸發 App 打開推送消息事件trackAppOpenNotification(uMessage.extra, uMessage.title, uMessage.text); - 處理神策智慧運營推送消息的動作(神策智慧運營的推送消息必須在 launchApp 介面中處理)handleSensorsFocusPushMessage(uMessage.extra); } @Override public void openUrl(Context context, UMessage uMessage) { super.openUrl(context, uMessage); - 觸發 App 打開推送消息事件trackAppOpenNotification(uMessage.extra, uMessage.title, uMessage.text); } @Override public void dealWithCustomAction(Context context, UMessage uMessage) { super .dealWithCustomAction(context, uMessage); - 觸發 App 打開推送消息事件trackAppOpenNotification(uMessage.extra, uMessage.title, uMessage.text); } @Override public void openActivity(Context context, UMessage uMessage) { super.openActivity( context, uMessage); - 觸發 App 打開推送消息事件trackAppOpenNotification(uMessage.extra, uMessage.title, uMessage.text); }});


廠商通道使用說明

需要在處理廠商通道的ActivityonMessage介面中處理消息,調用 trackAppOpenNotification(extraStr, title, content)handleSensorsFocusPushMessage(notificationExtras)。

/** * 友盟廠商通道消息的 Activity * <p>* 該 Activity 需繼承自 UmengNotifyClickActivity,同時實現父類的 onMessage 方法, * 對該方法的 intent 參數進一步解析即可,該方法異步調用,不阻塞主線程。 *並設置 launchMode="singleTask" 和 exported="true" */ public class HandlePushActivity extends UmengNotifyClickActivity { /** * 處理友盟廠商通道消息 */ @Override public void onMessage(Intent intent) { super.onMessage(intent); if (intent != null){ / 如果你們使用了友盟的廠商通道消息,需要在 onMessage 處理廠商通道消息!!! String messageBody = intent.getStringExtra(AgooConstants.MESSAGE_BODY); Log.e("TODO""廠商通道消息:" + messageBody); if (! TextUtils.isEmpty(messageBody)) { try {JSONObject push = new JSONObject(messageBody); JSONObject extra = push.optJSONObject("extra"); String extraStr = null; if (extra != null) {extraStr = extra.toString(); - 處理神策智慧運營推送消息的動作handleSensorsFocusPushMessage(extraStr); } / 推送標題String title = push.optJSONObject("body").optString("title"); -推送內容 String content = push.optJSONObject("body").optString("text"); - 觸發 App 打開推送消息事件trackAppOpenNotification(extraStr, title, content); Log.e("TODO",String.format("title: %s。 content:%s。 extraStr: %s。 ", title, content, extraStr)); } catch (Exception e) {e.printStackTrace(); }}}}}


個推推送

上報 「推送 ID」

GTIntentServiceonReceiveClientId 介面中調用 SensorsDataAPI.sharedInstance().profilePushId("getui_id",clientId)。

推送 ID的處理 public class GeTuiService extends GTIntentService { @Override public void onReceiveClientId(Context context, String clientId) {/ ...上報個推 "推送 ID" SensorsDataAPI.sharedInstance(context).profilePushId("getui_id", clientId); }}

在調用神策SDK login 介面之後調用 SensorsDataAPI.sharedInstance().profilePushId("getui_id", PushManager.getInstance().getClientid(context))。

SensorsDataAPI.sharedInstance().login(userId); -在調用神策 SDK login 介面後,也需要調用 profilePushId 介面上報個推 "推送 ID"SensorsDataAPI.sharedInstance(). profilePushId("getui_id", PushManager.getInstance().getClientid(context));


記錄 「推送點擊」事件並處理平臺推送的消息

需要在onNotificationMessageClicked 記錄通知消息被點擊的通知標題和通知內容,在 onReceiveMessageData 介面中記錄事件並處理平臺推送的消息。

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="4d206119-8d01-40d1-9520-5693f5446eb2"><ac:plain-text-body><![CDATA[

public class GeTuiService extends GTIntentService { private boolean isNotificationClick = false ; private String title; private String content; /** * 點擊通知消息。 *上報「推送點擊」事件需要在 onReceiveMessageData 介面獲取 Sensors Focus 的消息內容,因此此處先將通知的標題和內容保存到成員變數中 */ @Override public void onNotificationMessageClicked(Context context, GTNotificationMessage gtNotificationMessage) {title = gtNotificationMessage.getTitle(); content = gtNotificationMessage.getContent(); isNotificationClick = true; } /** * 處理透傳消息到達或通知消息的點擊 */ @Override public void onReceiveMessageData(Context context, GTTransmitMessage gtTransmitMessage) { if(context ==null

gtTransmitMessage ==null)return; /* * 透傳消息的處理,此處僅僅演示了 sf_data 推送的相關欄位,注意,如果你有原有的邏輯也有相關處理 * 的邏輯,需要做一定的相容處理。 */<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="64ef3534-8133-44fc-8a94-7aac3a908e28"> <ac:plain-text-body><! [CDATA[ byte[] payload = gtTransmitMessage.getPayload(); ]]></ac:plain-text-body></ac:structured-macro>String sfData = new String(payload); /* * onReceiveMessageData 在透傳消息的到達與通知消息的點擊時都會被回調,但只有通知消息的點擊 時需要上報「推送到達」事件。 * 因此通過isNotificationClick變數來判斷本次onReceiveMessageData 被調用是由於透傳消息到達還是 通知消息的點擊 */ if (isNotificationClick) {isNotificationClick = false; trackAppOpenNotification(sfData, title, content); handleSensorsFocusConfig(sfData); }else{ /* * 透傳消息到達需要自定義處理。 例如從sfData 獲取出標題和內容來手動觸發一個 notification * 透傳消息有點擊的話,也需要調用 trackAppOpenNotification */ }}}

]]></ac:plain-text-body></ac:structured-macro>


廠商通道使用說明

首先需要在在推送設置的的intent 範本設定 intent,以下為配置範例,開發者可根據自己的專案進行配置。

intent://www.test.com/path? custom=aaa#Intent; scheme=yang; launchFlags=0x10000000; component=com.sensorsdata.android.push/. HandlePushActivity; S.sf_key={sf_data:{sf_data},title:{sf_customized.title},content:{sf_customized.content}}; end

Code Block 2示例代碼 需要在處理廠商通道的 ActivityonCreate 中處理 intent,解析出相應的參數,調用 trackAppOpenNotification( extras, title, content)

public class HandlePushActivity extends AppCompatActivity { private static final String TAG = " HandlePushActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); handlePushIntent(); } /** * 處理推送消息的 Intent */ private void handlePushIntent() {Intent intent = getIntent(); if (intent != null){ - 拿到自定義透傳字段的值String sf_key = intent.getStringExtra(" sf_key"); Log.i(TAG, sf_key); if (TextUtils.isEmpty(sf_key)) { return; } try {JSONObject jsonObject = new JSONObject(sf_key); String title = jsonObject.optString("title"); String content = jsonObject.optString("content"); String extras = jsonObject.optString("sf_data"); trackAppOpenNotification(extras, title, content); } catch (JSONException e) {e.printStackTrace(); }}}  }


測試推送

  1. 首先發送推送 ID 到神策后,選擇上報推送 ID 的 key(這裡以 jiguang_id 為例),點擊測試推送。
  2. 填入測試機的推送ID、推送標題、內容,如下圖所示。
  3. 確認推送,可查看手機是否收到推送,以及查看埋點上報字段是否正確。

附錄

trackAppOpenNotification方法詳情

因各個推送不同,開發者可根據實際的欄位及業務需求進行欄位的解析。

/** * 埋點 App 打開推送消息* <p>* 事件名:$AppPushClick ** @param extras 推送消息的 extras(參數類型只能傳String 或 Map<String,String>)* @param notificationTitle 推送消息的標題 * @param notificationContent 推送消息的內容 */ public static void trackAppOpenNotification(String extras, String notificationTitle, String notificationContent) { try {JSONObject jsonObject = null; if (! TextUtils.isEmpty(extras)) {jsonObject = new JSONObject(extras); }JSONObject properties = new JSONObject(); -獲取消息標題,並保存在事件屬性 msg_title 中properties.put("$sf_msg_title",notificationTitle); -獲取消息 ID,並保存在事件屬性 msg_id 中properties.put("$sf_msg_content", notificationContent); if (jsonObject != null) \{properties.put("$sf_msg_id", jsonObject.opt("sf_msg_id" )); properties. put("$sf_plan_id", jsonObject.opt("sf_plan_id")); if (! "null".equals(jsonObject.opt("sf_audience_id"))) {properties.put("$sf_audience_id", jsonObject.opt("sf_audience_id")); }properties.put("$sf_link_url", jsonObject.opt("sf_link_url")); properties.put("$sf_plan_strategy_id", jsonObject.opt("sf_plan_strategy_id")); properties.put("$sf_plan_type", jsonObject.opt("sf_plan_type")); properties.put("$sf_strategy_unit_id", jsonObject.opt("sf_strategy_unit_id")); properties.put("$sf_enter_plan_time", jsonObject. opt("sf_enter_plan_time")); properties.put("$sf_channel_id", jsonObject.opt("sf_channel_id")); properties.put("$sf_channel_category", jsonObject.opt("sf_channel_category")); properties.put("$sf_channel_service_name", jsonObject.opt("sf_channel_service_name")); } - 使用神策分析追蹤「App 訊息推送成功」 事件SensorsDataAPI.sharedInstance().track( "$AppPushClick", properties); } catch (Exception e) {e.printStackTrace(); }}


handleSensorsFocusPushMessage方法詳情

/** * 處理神策智能運營推送消息。 * TODO 此方法只是解析了神策智慧運營的推送消息,具體的業務跳轉邏輯需要開發者加上!!! * * @param notificationExtras 推送消息的 extra */ public static void handleSensorsFocusPushMessage(Object notificationExtras) { try {String sfData = null; if (notificationExtras != null) \{ if (notificationExtras instanceof String) \{sfData = new JSONObject((String) notificationExtras).optString("sf_data"); \} else if (notificationExtras instanceof Map) \{sfData = new JSONObject((Map) notificationExtras).optString("sf_data"); \}\} if (! TextUtils.isEmpty(sfData)) {JSONObject sfJson = new JSONObject(sfData); if"OPEN_APP".equals(sfJson.optString("sf_landing_type"))) {/ TODO 處理打開 App消息,--> 請啟動 AppLog.e("TODO""-- 請啟動 App --" ); } else if ("LINK".equals(sfJson.optString("sf_landing_type"))) {String url = sfJson.optString("sf_link_url"); if (! TextUtils.isEmpty(url)) { – TODO處理打開 URL 消息,--> 請處理 URLLog.e("TODO""-- 請處理打開 URL --: " + url); }} else if ("CUSTOMIZED".equals(sfJson.optString("sf_landing_type" ))) {JSONObject custom = sfJson.optJSONObject("customized"); if (custom != null){-- TODO 處理自訂消息,--> 請處理自定義消息 Log.e("TODO""-- 請處理自定義消息--: " + custom); }}}} catch (Exception e) {e.printStackTrace(); }}


handleSensorsFocusConfig 方法詳情

/** * 處理神策智能運營推送消息。 * TODO 此方法只是解析了神策智慧運營的推送消息,具體的業務跳轉邏輯需要開發者加上!!! * * @param sfData 配置 */ public static void handleSensorsFocusConfig(String sfData) { try { if (! TextUtils.isEmpty(sfData)) {JSONObject sfJson = new JSONObject(sfData); if ("OPEN_APP".equals(sfJson.optString("sf_landing_type"))) { // TODO 處理開啟 App消息,--> 請啟動 AppLog.e("TODO""-- 請啟動 App - -"); } else if ("LINK".equals(sfJson.optString("sf_landing_type"))) {String url = sfJson.optString("sf_link_url"); if (! TextUtils.isEmpty(url)) { – TODO 處理打開 URL 消息,--> 請處理 URLLog.e( "TODO""-- 請處理打開 URL --: " + url); }} else if ("CUSTOMIZED".equals(sfJson.optString("sf_landing_type"))) { JSONObject custom = sfJson.optJSONObject("customized"); if (custom != null){-- TODO 處理自訂消息,--> 請處理自定義消息Log.e("TODO ""-- 請處理自定義消息--: " + custom); }}}} catch (Exception e) {e.printStackTrace(); }}


附錄方法的封裝類

如果不想把附錄中的示例方法一個個複製到專案中,可以使用封裝好的工具類SensorsFocusHelper 來調用示例方法。 使用步驟如下:

  1. 下載SensorsFocusHelper 類,解壓後複製到專案中
  2. SensorsFocusHelper 類新增 package 聲明
  3. 呼叫SensorsFocusHelper 類別中的同名方法

附錄中的handleSensorsFocusPushMessage 方法與 handleSensorsFocusConfig 方法需要開發者在 TODO 註釋的位置添加上具體的業務跳轉邏輯, SensorsFocusHelper 類將具體的業務跳轉邏輯封裝成介面 SensorsFocusHandler,具體的使用方式請參考以下示例:

SensorsFocusHelper.handleSensorsFocusPushMessage(notificationExtras, new SensorsFocusHelper.SensorsFocusHandler() { @Override public void handleOpenApp() {-- TODO 處理開啟 App 消息,--> 請啟動 App}  @Override public void handleLink(String url) {-- TODO 處理打開 URL 消息,--> 請處理 URL} @Override public void handleCustomized(JSONObject customProperties) { // TODO 處理自定義消息,--> 請處理自定義消息}});