Android 推送集成
|
收藏
视频版讲解
极光推送
上报 "推送 ID"
在极光提供的 onRegister 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("jiguang_id",s)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("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 可以自动采集来自极光、个推、友盟推送的推送点击事件,请参考此文档开启采集。
处理推送消息
/**
* 配置的通知跳转目标地址处理推送消息。
*/
public class OpenClickActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 处理推送消息的点击
handlePushOpen(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 处理推送消息的点击
handlePushOpen(intent);
}
/**
* 处理推送消息的点击。
*
* 华为通道消息数据:通过 intent.getData().toString(); 获取。
* 小米、vivo、OPPO、FCM、魅族、极光通道消息数据 :通过 intent.getExtras().getString("JMessageExtra") 获取。
*/
private void handlePushOpen(Intent intent) {
try {
if (intent == null) {
return;
}
String pushData = null;
// 华为通道消息数据
if (intent.getData() != null) {
pushData = intent.getData().toString();
}
// 小米、vivo、OPPO、FCM、魅族、极光通道消息数据
if (TextUtils.isEmpty(pushData) && intent.getExtras() != null) {
pushData = intent.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();
}
}
}
若未配置通知跳转目标地址时在 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);
}
}
非厂商通道可以在 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);
}
}
使用厂商通道的情况下,需要在厂商通道 Activity 的 onCreate,onNewIntent 中拿到 intent,解析出相应的参数再处理推送消息。
/**
* 如果使用了极光 VIP 的厂商通道(uri_activity/uri_action),需要在厂商消息打开的 Activity 中处理厂商通道消息。
* 处理厂商通道消息的点击事件的 Activity。
*/
public class OpenClickActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 处理厂商通道消息的点击
handlePushOpen(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 处理厂商通道消息的点击
handlePushOpen(intent);
}
/**
* 处理厂商通道消息的点击。
*
* 华为通道消息数据:通过 intent.getData().toString(); 获取。
* 小米、vivo、OPPO、FCM 通道消息数据 :通过 intent.getExtras().getString("JMessageExtra") 获取。
* 魅族通道消息数据:通过 onNotifyMessageOpened 获取。
*/
private void handlePushOpen(Intent intent) {
try {
if (intent == null) {
return;
}
String pushData = null;
// 华为通道消息数据
if (intent.getData() != null) {
pushData = intent.getData().toString();
}
// 小米、vivo、OPPO、FCM 通道消息数据(魅族会回调 onNotifyMessageOpened )
if (TextUtils.isEmpty(pushData) && intent.getExtras() != null) {
pushData = intent.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"
在 IUmengRegisterCallback 的 onSuccess 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("umeng_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("umeng_id",token)。
代码示例
// 推送 ID 的处理
PushAgent.getInstance(context).register(new IUmengRegisterCallback() {
@Override
public void onSuccess(String token) {
//上报友盟 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("umeng_id", token);
}
@Override
public void onFailure(String s, String s1) {}
});
在调用神策 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());
记录 「推送点击」事件并处理平台推送的消息
需要在 launchApp、openUrl、openActivity、dealWithCustomAction 这 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);
}
});
厂商通道使用说明
需要在处理厂商通道的 Activity 的 onMessage 接口中处理消息,调用 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"
在 GTIntentService 的 onReceiveClientId 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("getui_id",clientId)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("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 接口中记录事件并处理平台推送的消息。
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 推送的相关字段,注意,如果你有原有的逻辑也有相关处理
* 的逻辑,需要做一定的兼容处理。
*/
byte[] payload = gtTransmitMessage.getPayload();
String sfData = new String(payload);
/*
* onReceiveMessageData 在 透传消息的到达 与 通知消息的点击 时都会被回调,但只有 通知消息的点击 时需要上报「推送到达」事件。
* 因此通过 isNotificationClick 变量来判断本次 onReceiveMessageData 被调用是由于 透传消息到达 还是 通知消息的点击
*/
if (isNotificationClick) {
isNotificationClick = false;
trackAppOpenNotification(sfData, title, content);
handleSensorsFocusConfig(sfData);
}else{
/*
* 透传消息到达需要自定义处理。例如从 sfData 获取出标题和内容来手动触发一个 notification
* 透传消息有点击的话,也需要调用 trackAppOpenNotification
*/
}
}
}
厂商通道使用说明
首先需要在在推送设置的的 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
需要在处理厂商通道的 Activity 的 onCreate 中处理 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();
}
}
}
}
阿里云推送
上报 "推送 ID"
在 CommonCallback 的 onSuccess 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("aliyun_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("aliyun_id",token)。
代码示例
// 推送 ID 的处理
pushService.register(context, new CommonCallback() {
@Override
public void onSuccess(String response) {
//上报阿里云 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("aliyun_id", "android_" + pushService.getDeviceId());
}
@Override
public void onFailed(String errorCode, String errorMessage) {
}
});
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("aliyun_id",PushServiceFactory.getCloudPushService().getDeviceId())。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报阿里云 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("aliyun_id","android_" + PushServiceFactory.getCloudPushService().getDeviceId());
记录 「推送点击」事件并处理平台推送的消息
需要在 onNotification、onNotificationOpened、onNotificationClickedWithNoAction、onNotificationReceivedInApp 这 4 个接口中调用 trackAppOpenNotification(extraMap,title,summary) 和 handleSensorsFocusPushMessage(extraMap)。
public class AliyunmessageReceiver extends MessageReceiver {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
//处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(extraMap);
}
@Override
public void onMessage(Context context, CPushMessage cPushMessage) {
//处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(extraMap);
}
@Override
public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
// 触发 App 打开推送消息 事件
trackAppOpenNotification(extraMap,title,summary);
}
@Override
protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
// 触发 App 打开推送消息 事件
trackAppOpenNotification(extraMap,title,summary);
}
@Override
protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
//处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(extraMap);
}
......
}
厂商通道使用说明
需要在处理厂商通道的 Activity 的 onSysNoticeOpened 接口中处理消息,调用 trackAppOpenNotification(extMap, title, summary) 和 handleSensorsFocusPushMessage(extMap)。
public class PopupPushActivity extends AndroidPopupActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* 实现通知打开回调方法,获取通知相关信息
* @param title 标题
* @param summary 内容
* @param extMap 额外参数
*/
@Override
protected void onSysNoticeOpened(String title, String summary, Map<String, String> extMap) {
// 处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(extMap);
// 触发 App 打开推送消息 事件
trackAppOpenNotification(extMap, title, summary);
}
}
腾讯云推送
上报 "推送 ID"
在 XGIOperateCallback 的 onSuccess 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("tencent_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("tencent_id",token)。
代码示例
// 推送 ID 的处理
XGPushManager.registerPush(context, new XGIOperateCallback() {
@Override
public void onSuccess(Object data, int flag) {
//上报腾讯云 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("tencent_id", "android_" + data.toString());
}
@Override
public void onFail(Object data, int errCode, String msg) {
}
});
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("tencent_id",XGPushConfig.getToken(context))。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报腾讯云 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("tencent_id","android_" + XGPushConfig.getToken(context));
记录 「推送点击」事件并处理平台推送的消息
需要在 onTextMessage、onNotificationClickedResult、onNotificationShowedResult 这 2 个接口中调用 handleSensorsFocusPushMessage(xgPushTextMessage.getCustomContent()) 和 trackAppOpenNotification(xgPushClickedResult.getCustomContent(), xgPushClickedResult.getTitle(), xgPushClickedResult.getContent())。
public class TencentMessageReceiver extends XGPushBaseReceiver {
@Override
public void onTextMessage(Context context, XGPushTextMessage xgPushTextMessage) {
//处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(xgPushTextMessage.getCustomContent());
}
@Override
public void onNotificationClickedResult(Context context, XGPushClickedResult xgPushClickedResult) {
//触发 App 打开推送消息 事件
trackAppOpenNotification(xgPushClickedResult.getCustomContent(), xgPushClickedResult.getTitle(), xgPushClickedResult.getContent());
}
@Override
public void onNotificationShowedResult(Context context, XGPushShowedResult xgPushShowedResult) {
//处理神策智能运营推送消息的动作
handleSensorsFocusPushMessage(xgPushTextMessage.getCustomContent());
}
@Override
public void onRegisterResult(Context context, int i, XGPushRegisterResult xgPushRegisterResult) {
}
......
}
厂商通道使用说明
厂商通道也是通过 onNotificationShowedResult 和 onNotificationClickedResult 处理到达和点击,因此不需要额外配置。
华为推送
上报 "推送 ID"
在自定义的继承 HmsMessageService 的类中 onNewToken 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("huawei_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("huawei_id",token)。
代码示例
public class SensorsHuaweiMessageService extends HmsMessageService {
@Override
public void onNewToken(String token) {
//上报华为 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("huawei_id", "android_" + token);
}
.......
}
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("tencent_id",HmsInstanceId.getInstance(context).getToken(appId, tokenScope))。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报华为 "推送 ID"
String appId = "your APP_ID";
String tokenScope = "HCM";
SensorsDataAPI.sharedInstance().profilePushId("huawei_id","android_" + HmsInstanceId.getInstance(context).getToken(appId, tokenScope));
记录 「推送点击」事件并处理平台推送的消息
需要在 onMessageReceived 这个接口中调用 handleSensorsFocusConfig(remoteMessage.getData()) 和 trackAppOpenNotification(remoteMessage.getData(),remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody())。
public class SensorsHuaweiMessageService extends HmsMessageService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
////处理神策智能运营推送消息的动作
handleSensorsFocusConfig(remoteMessage.getData());
//触发 App 打开推送消息 事件
trackAppOpenNotification(remoteMessage.getData(),remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
.......
}
OPPO 推送
上报 "推送 ID"
在 ICallBackResultService 的 onRegister 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("oppo_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("oppo_id",token)。
代码示例
HeytapPushManager.register(context, appKey, appSecret, new ICallBackResultService() {
@Override
public void onRegister(int i, String s) {
//上报OPPO "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("oppo_id", s);
}
......
});
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("oppo_id",HeytapPushManager.getRegisterID())。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报OPPO "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("oppo_id",HeytapPushManager.getRegisterID());
记录 「推送点击」事件并处理平台推送的消息
需要在 processMessage 这 1 个接口中调用 handleSensorsFocusConfig(message.getDataExtra()) 和 trackAppOpenNotification(message.getDataExtra(), message.getTitle(), message.getContent())。
public class PushMessageService extends CompatibleDataMessageCallbackService {
@Override
public void processMessage(Context context, DataMessage message) {
super.processMessage(context.getApplicationContext(), message);
//处理神策智能运营推送消息的动作
handleSensorsFocusConfig(message.getDataExtra());
//触发 App 打开推送消息 事件
trackAppOpenNotification(message.getDataExtra(), message.getTitle(), message.getContent());
}
}
VIVO 推送
上报 "推送 ID"
在自定义的继承 OpenClientPushMessageReceiver 的类中 onReceiveRegId 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("vivo_id",s)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("vivo_id",s)。
代码示例
public class PushMessageReceiverImpl extends OpenClientPushMessageReceiver {
@Override
public void onReceiveRegId(Context context, String s) {
//上报VIVO "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("vivo_id", s);
}
......
}
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("vivo_id",PushClient.getInstance(PushApplication.this).getRegId())。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报VIVO "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("vivo_id",PushClient.getInstance(PushApplication.this).getRegId());
记录 「推送点击」事件并处理平台推送的消息
需要在 onTransmissionMessage、onNotificationMessageClicked 这 2 个接口中调用 handleSensorsFocusConfig(unvarnishedMessage.getParams()) 和 trackAppOpenNotification(unvarnishedMessage.getParams(), unvarnishedMessage.getTitle(), unvarnishedMessage.getContent())。
public class PushMessageReceiverImpl extends OpenClientPushMessageReceiver {
......
@Override
public void onTransmissionMessage(Context context, UnvarnishedMessage unvarnishedMessage) {
super.onTransmissionMessage(context, unvarnishedMessage);
//处理神策智能运营推送消息的动作
handleSensorsFocusConfig(unvarnishedMessage.getParams());
}
@Override
public void onNotificationMessageClicked(Context context, UPSNotificationMessage unvarnishedMessage) {
super.onNotificationMessageClicked(context, unvarnishedMessage);
//触发 App 打开推送消息 事件
trackAppOpenNotification(unvarnishedMessage.getParams(), unvarnishedMessage.getTitle(), unvarnishedMessage.getContent());
}
}
小米推送
上报 "推送 ID"
在自定义的继承 PushMessageReceiver 的类中 onCommandResult 和 onReceiveRegisterResult 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("xiaomi_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("xiaomi_id",token)。
代码示例
public class DemoMessageReceiver extends PushMessageReceiver {
@Override
public void onCommandResult(Context context, MiPushCommandMessage message) {
String command = message.getCommand();
List<String> arguments = message.getCommandArguments();
String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);
if (MiPushClient.COMMAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
//上报小米 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("xiaomi_id", "android_" + cmdArg1);
}
}
}
@Override
public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
String command = message.getCommand();
List<String> arguments = message.getCommandArguments();
String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);
if (MiPushClient.COMMAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
//上报小米 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("xiaomi_id", "android_" + cmdArg1);
}
}
}
}
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("xiaomi_id",MiPushClient.getRegId(context))。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报小米 "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("xiaomi_id","android_" + MiPushClient.getRegId(context));
记录 「推送点击」事件并处理平台推送的消息
需要在 onReceivePassThroughMessage、onNotificationMessageArrived、onNotificationMessageClicked 这 2 个接口中调用 handleSensorsFocusConfig(message.getExtra()) 和 trackAppOpenNotification(message.getExtra(), message.getTitle(), message.getContent())。
public class DemoMessageReceiver extends PushMessageReceiver {
@Override
public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
//处理神策智能运营推送消息的动作
handleSensorsFocusConfig(message.getExtra());
}
@Override
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
//触发 App 打开推送消息 事件
trackAppOpenNotification(message.getExtra(), message.getTitle(), message.getContent());
}
@Override
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
//处理神策智能运营推送消息的动作
handleSensorsFocusConfig(message.getExtra());
}
......
}
FCM 推送
上报 "推送 ID"
在 OnCompleteListener 的 onComplete 接口中调用 SensorsDataAPI.sharedInstance().profilePushId("fcm_id", token)。
若推送 ID 存在实效性,建议调用 SensorsDataAPI.sharedInstance().profileSet("fcm_id",token)。
代码示例
// 推送 ID 的处理
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(Task<String> task) {
if (!task.isSuccessful()) {
return;
}
String token = task.getResult();
//上报FCM "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("fcm_id", data);
}
});
在调用神策 SDK login 接口之后调用 SensorsDataAPI.sharedInstance().profilePushId("fcm_id",FirebaseMessaging.getInstance().getToken().getResult())。
SensorsDataAPI.sharedInstance().login(userId);
//在调用神策 SDK login 接口后,也需要调用 profilePushId 接口上报FCM "推送 ID"
SensorsDataAPI.sharedInstance().profilePushId("fcm_id",FirebaseMessaging.getInstance().getToken().getResult());
记录 「推送点击」事件并处理平台推送的消息
需要在 onMessageReceived 这个接口中调用 handleSensorsFocusConfig(remoteMessage.getData()) 和 trackAppOpenNotification(remoteMessage.getData(), remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody())。
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//处理神策智能运营推送消息的动作
handleSensorsFocusConfig(remoteMessage.getData());
//触发 App 打开推送消息 事件
trackAppOpenNotification(remoteMessage.getData(), remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
......
}
UniPush 推送
上报推送 ID
为了保证登录之后的用户也能设置 cid 属性,需要在获取到 cid 以及调用神策 - login: 接口各上报一次。由于 UniPush 目前有 1.0 和 2.0 两个版本,下面以 2.0 版本来说明,1.0 版本的 请参考 DCloud 官网文档。
uni.getPushClientId({
success: (res) => {
let cid = res.cid;
sensors.setProfile({ "uni-id": cid }); // uni_id 只是一个示例字段
},
fail(err) {
console.log(err);
}
});
// 为了保证登录后的用户也能正确设置 cid,调用 login 之后,再次上报 cid
sensors.login("<#登录 id#>");
sensors.setProfile({"uni-id":cid});
记录 「推送点击」事件并处理智能运营平台推送的消息
uni.onPushMessage((result) => {
let data = result.data;
if (typeof data !== "string") {
let sf_data = data.payload.sf_data;
//记录推送事件,此处需参考 trackSensorsFocusAppOpenNotificationWithUserInfo 中的 json 解析逻辑赋值事件属性
let sf_properties = {};
sf_properties.$sf_plan_id = sf_data.sf_plan_id;
...
sensors.track("$AppPushClick", sf_properties);
// 根据解析的字段,发现跳转 url 然后进行跳转操作
}
});
测试推送
- 首先发送推送 ID 到神策后,选择上报推送 ID 的 key(这里以 jiguang_id 为例),点击测试推送。
- 填入测试机的推送 ID、推送标题、内容,如下图所示,其中通知栏图标和高级设置可根据需求进行配置。
- 确认推送,可查看手机是否收到推送,以及查看埋点上报字段是否正确。
附录
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"));
//在画布中,$sf_strategy_unit_id 是由 画布ID 和 策略器ID(节点ID)拼接的,然后策略器名称会通过维度字典进行映射
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 消息,--> 请启动 App
Log.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 消息,--> 请处理 URL
Log.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 消息,--> 请启动 App
Log.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 消息,--> 请处理 URL
Log.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 来调用示例方法。使用步骤如下:
- 下载 SensorsFocusHelper 类,解压后复制到项目中
- 给 SensorsFocusHelper 类添加 package 声明
- 调用 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 处理自定义消息,--> 请处理自定义消息
}
});
注:本文档内容为神策产品使用和技术细节说明文档,不包含适销类条款;具体企业采购产品和技术服务内容,以商业采购合同为准。