本文介绍 Android SDK 4.x 接收消息、通知到达、点击和删除事件,以及按需拦截通知显示的方法。
适用于移动推送 Android SDK 4.x,本文接口和示例以已发布的 4.0.0 版本为基线。使用 3.x 的应用请参见对应的 3.x API 文档。
选择一种回调方式
Android SDK 4.x 中,MessageReceiver 和 AliyunMessageIntentService 的业务回调范围如下:
ACCS 自有通道和 FCM:支持消息接收(onMessage)、通知到达(onNotification)、通知点击(onNotificationOpened)、通知清除(onNotificationRemoved)等完整业务回调。
除 FCM 外的其他 Android 厂商通道:仅支持 onNotificationOpened(通知点击),不触发消息接收、通知到达、通知清除等其他回调。
MessageReceiver 与 AliyunMessageIntentService 提供相同的业务回调,任选一种。默认使用 MessageReceiver;调用 setPushIntentService 后改由指定服务处理,不再通过 MessageReceiver 分发。
|
回调 |
适用范围 |
|
onMessage |
ACCS 自有通道和 FCM 通道的透传消息到达。 |
|
onNotification |
ACCS 自有通道和 FCM 通道的通知到达;应用拦截通知展示时仍使用此回调。 |
|
onNotificationOpened |
SDK 展示的通知点击,以及正确接入辅助弹窗后的厂商系统通知点击。 |
|
onNotificationRemoved |
ACCS 自有通道和 FCM 通道的通知被删除。其他安卓厂商通道仅提供 onNotificationOpened 点击回调。 |
请先完成 SDK 初始化和注册。FCM 适配器将 data 消息中的 payload 转交移动推送 SDK 处理。小米、华为、荣耀、OPPO、vivo、魅族等厂商系统通知点击仍需要正确配置中转 Activity 和服务端辅助弹窗参数;4.x 将业务点击处理统一交给 onNotificationOpened,不再由 onSysNoticeOpened 处理。
以下回调示例写在已继承 MessageReceiver 或 AliyunMessageIntentService 的类中;其余必需回调仍需实现。回调参数由 SDK 传入,参数表中的“是否必填”表示该值是否必须存在,标为“否”的值使用前应判空。
方式一:MessageReceiver
继承 MessageReceiver 并实现四个业务回调。将类名替换成应用实际类名,Kotlin 示例对可能为空的数据进行判空。
import android.content.Context;
import com.alibaba.sdk.android.push.MessageReceiver;
import com.alibaba.sdk.android.push.notification.CPushMessage;
import java.util.Map;
public class MyMessageReceiver extends MessageReceiver {
@Override
public void onMessage(Context context, CPushMessage message) {
// SDK 处理的透传消息,不会自动显示为通知。
}
@Override
public void onNotification(Context context, String title, String summary,
Map<String, String> extraMap) {
// SDK 处理的通知到达,无论应用是否选择展示通知。
}
@Override
public void onNotificationOpened(Context context, String title, String summary,
Map<String, String> extraMap) {
// 统一处理 SDK 通知及已正确接入的厂商系统通知点击。
// 可从 extraMap 读取发送时设置的扩展参数,使用前需判空。
}
@Override
public void onNotificationRemoved(Context context, String messageId) {
// SDK 展示的通知被删除;messageId 是消息标识。
}
}import android.content.Context
import com.alibaba.sdk.android.push.MessageReceiver
import com.alibaba.sdk.android.push.notification.CPushMessage
class MyMessageReceiver : MessageReceiver() {
override fun onMessage(context: Context, message: CPushMessage) {
// SDK 处理的透传消息。
}
override fun onNotification(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
// SDK 处理的通知到达。
}
override fun onNotificationOpened(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
// 统一处理通知点击。
// 可从 extraMap 读取发送时设置的扩展参数,使用前需判空。
}
override fun onNotificationRemoved(context: Context, messageId: String?) {}
}在 AndroidManifest.xml 的 application 节点内注册。示例 .MyMessageReceiver 必须替换为应用实际的完整类名或可解析的相对类名。
<receiver
android:name=".MyMessageReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
</receiver>
onReceive 回调中的网络请求和其他耗时操作,请交给应用的异步任务处理。
方式二:AliyunMessageIntentService
继承 SDK 的 AliyunMessageIntentService,以服务形式接收回调。回调中的耗时操作请交给异步任务处理,界面操作请切换到主线程执行。
import android.content.Context;
import com.alibaba.sdk.android.push.AliyunMessageIntentService;
import com.alibaba.sdk.android.push.notification.CPushMessage;
import java.util.Map;
public class MyMessageIntentService extends AliyunMessageIntentService {
@Override
public void onMessage(Context context, CPushMessage message) {
// SDK 处理的透传消息,不会自动显示为通知。
}
@Override
public void onNotification(Context context, String title, String summary,
Map<String, String> extraMap) {
// SDK 处理的通知到达,无论应用是否选择展示通知。
}
@Override
public void onNotificationOpened(Context context, String title, String summary,
Map<String, String> extraMap) {
// 统一处理 SDK 通知及已正确接入的厂商系统通知点击。
// 可从 extraMap 读取发送时设置的扩展参数,使用前需判空。
}
@Override
public void onNotificationRemoved(Context context, String messageId) {
// SDK 展示的通知被删除;messageId 是消息标识。
}
}import android.content.Context
import com.alibaba.sdk.android.push.AliyunMessageIntentService
import com.alibaba.sdk.android.push.notification.CPushMessage
class MyMessageIntentService : AliyunMessageIntentService() {
override fun onMessage(context: Context, message: CPushMessage) {
// SDK 处理的透传消息。
}
override fun onNotification(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
// SDK 处理的通知到达。
}
override fun onNotificationOpened(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
// 统一处理通知点击。
// 可从 extraMap 读取发送时设置的扩展参数,使用前需判空。
}
override fun onNotificationRemoved(context: Context, messageId: String?) {}
}在 AndroidManifest.xml 的 application 节点内注册。
<service
android:name=".MyMessageIntentService"
android:exported="false">
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
</service>
setPushIntentService:指定消息处理服务
指定继承 AliyunMessageIntentService 的服务类,使 SDK 通过该服务分发消息和通知事件。
接口定义
void setPushIntentService(Class intentService);
参数说明
|
参数 |
类型 |
是否必填 |
说明 |
|
intentService |
Class |
否 |
已在 AndroidManifest.xml 注册、继承 AliyunMessageIntentService 的服务类;传 null 恢复通过 MessageReceiver 分发。 |
返回值:无(void);该方法不执行推送注册,也不提供结果回调。
在 Application.onCreate() 中完成 init 后尽早设置,并在 register 前完成。每次应用启动均恢复此配置。
代码示例
PushServiceFactory.getCloudPushService()
.setPushIntentService(MyMessageIntentService.class);PushServiceFactory.getCloudPushService()
.setPushIntentService(MyMessageIntentService::class.java)透传消息回调
void onMessage(Context context, CPushMessage message);
SDK 将透传消息交给应用处理,不会自动显示通知。context 是组件上下文;message 包含消息数据。
参数说明
|
参数 |
类型 |
是否必填 |
说明 |
|
context |
Context |
是 |
SDK 分发事件使用的组件上下文。界面操作请使用有效的 Activity。 |
|
message |
CPushMessage |
是 |
本次到达的透传消息对象,读取示例中的 message 均来自此参数。 |
返回值:无(void)。应用处理消息内容;此回调不会自动创建通知。
代码示例
@Override
public void onMessage(Context context, CPushMessage message) {
String content = message.getContent();
if (content != null) {
// 按应用约定解析消息正文;耗时操作交给应用任务调度。
}
}override fun onMessage(context: Context, message: CPushMessage) {
val content = message.content
if (content != null) {
// 按应用约定解析消息正文。
}
}|
CPushMessage 方法 |
说明 |
|
getMessageId() |
消息标识。 |
|
getAppId() |
应用标识。 |
|
getTitle() |
消息标题。 |
|
getContent() |
消息正文。 |
|
getTraceInfo() |
统计上报所需信息,应与原始消息一起保留,不自行改写。 |
若应用根据透传消息自行创建通知,请在实际点击或删除时使用自建通知统计上报接口,传入原始 CPushMessage。
CPushMessage.getMessageId:获取消息标识
读取 onMessage 回调参数 message 中的消息标识。
接口定义
public String getMessageId();
参数说明:无。
返回值:服务端消息标识,用于关联推送消息,不是 Android 整数通知 ID。 返回类型为 String。
示例中的 message 为 onMessage 回调参数,保留原始对象供后续自建通知统计使用。
代码示例
String messageId = message.getMessageId();val messageId = message.getMessageId()CPushMessage.getAppId:获取应用标识
读取 onMessage 回调参数 message 中的应用标识。
接口定义
public String getAppId();
参数说明:无。
返回值:消息携带的应用标识。 返回类型为 String。
示例中的 message 为 onMessage 回调参数,保留原始对象供后续自建通知统计使用。
代码示例
String appId = message.getAppId();val appId = message.getAppId()CPushMessage.getTitle:获取消息标题
读取 onMessage 回调参数 message 中的消息标题。
接口定义
public String getTitle();
参数说明:无。
返回值:透传消息标题;值可能为空。 返回类型为 String。
示例中的 message 为 onMessage 回调参数,保留原始对象供后续自建通知统计使用。
代码示例
String title = message.getTitle();val title = message.getTitle()CPushMessage.getContent:获取消息正文
读取 onMessage 回调参数 message 中的消息正文。
接口定义
public String getContent();
参数说明:无。
返回值:透传消息正文;内容格式由发送方与应用约定。 返回类型为 String。
示例中的 message 为 onMessage 回调参数,保留原始对象供后续自建通知统计使用。
代码示例
String content = message.getContent();val content = message.getContent()CPushMessage.getTraceInfo:获取统计信息
读取 onMessage 回调参数 message 中的统计信息。
接口定义
public String getTraceInfo();
参数说明:无。
返回值:SDK 统计上报使用的原始信息,请随原始消息保留和传递。返回类型为 String。
示例中的 message 为 onMessage 回调参数,保留原始对象供后续自建通知统计使用。
代码示例
String traceInfo = message.getTraceInfo();val traceInfo = message.getTraceInfo()通知到达回调
在 SDK 处理通知到达时调用。通知是否显示在系统通知栏,由展示判断及系统条件决定。
void onNotification(Context context, String title, String summary,
Map<String, String> extraMap);
|
参数 |
类型 |
是否必填 |
说明 |
|
context |
Context |
是 |
SDK 分发事件使用的组件上下文。界面操作请使用有效的 Activity。 |
|
title |
String |
否 |
通知标题。 |
|
summary |
String |
否 |
通知正文。 |
|
extraMap |
Map<String, String> |
否 |
已解析的通知扩展参数;业务参数键由发送方约定,不存在固定的业务跳转键。 |
4.x 中,当 showNotificationNow 返回 false 或自定义样式设置前台不显示时,应用仍通过 onNotification 接收通知数据。通知栏展示还需满足系统通知权限和通知渠道设置。
返回值:无(void)。此回调表示通知数据到达。
代码示例
@Override
public void onNotification(Context context, String title, String summary,
Map<String, String> extraMap) {
String businessId = extraMap == null ? null : extraMap.get("businessId");
if (businessId != null) {
// businessId 为发送方自定义的扩展参数,按业务需要更新应用数据。
}
}override fun onNotification(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
val businessId = extraMap?.get("businessId")
if (businessId != null) {
// businessId 为发送方自定义的扩展参数。
}
}控制是否展示通知
boolean showNotificationNow(Context context, Map<String, String> map);
返回 true 交给 SDK 创建并展示通知;返回 false 不展示,由应用在 onNotification 中处理业务。map 包含 SDK 原始通知数据,业务扩展参数需从 ext 字段解析。默认实现会考虑自定义样式的前台展示设置。免打扰规则优先于此方法。
参数说明
|
参数 |
类型 |
是否必填 |
说明 |
|
context |
Context |
是 |
SDK 创建通知时使用的上下文。 |
|
map |
Map<String, String> |
是 |
SDK 原始通知数据的顶层 Map。业务扩展参数位于 ext 键对应的 JSON 字符串中,不会直接平铺为顶层键。 |
返回值:boolean。true 允许 SDK 继续构建和展示;false 拦截本次 SDK 通知展示。调用 super.showNotificationNow 可保留默认的前台展示规则。
以下示例仅在当前会话与通知业务扩展参数 conversationId 一致时拦截。conversationId 是应用自定义示例键;空值或 JSON 解析失败时回退到 SDK 默认判断。onNotification 和 onNotificationOpened 的 extraMap 已解析业务扩展字段,与这里的顶层 map 不同。
@Override
public boolean showNotificationNow(Context context, Map<String, String> map) {
String ext = map.get("ext");
if (ext != null) {
try {
String conversationId = new org.json.JSONObject(ext)
.optString("conversationId", "");
if (!conversationId.isEmpty()
&& conversationId.equals(getVisibleConversationId())) {
return false;
}
} catch (org.json.JSONException ignored) {
// 非法扩展参数不影响默认展示判断。
}
}
return super.showNotificationNow(context, map);
}
private String getVisibleConversationId() {
return ""; // 替换成应用当前正在查看的会话 ID;空字符串表示未查看会话。
}override fun showNotificationNow(context: Context, map: Map<String, String>): Boolean {
val ext = map["ext"]
if (ext != null) {
try {
val conversationId = org.json.JSONObject(ext).optString("conversationId", "")
if (conversationId.isNotEmpty() && conversationId == getVisibleConversationId()) {
return false
}
} catch (ignored: org.json.JSONException) {
// 非法扩展参数不影响默认展示判断。
}
}
return super.showNotificationNow(context, map)
}
private fun getVisibleConversationId(): String = "" // 替换为应用当前会话 ID。通知点击回调
void onNotificationOpened(Context context, String title, String summary,
Map<String, String> extraMap);
4.x 的 extraMap 是 Map<String,String>,不再是 JSON 字符串;数据可能为空。自有通道的无跳转通知点击也进入本回调,不再实现 onNotificationClickedWithNoAction。厂商点击通过正确配置的中转 Activity 解析后进入同一回调。
需要页面跳转时,请结合应用路由和当前页面状态统一管理跳转入口,并使用有效的 Activity 处理界面操作。
参数说明
|
参数 |
类型 |
是否必填 |
说明 |
|
context |
Context |
是 |
SDK 分发事件使用的组件上下文。界面操作请使用有效的 Activity。 |
|
title |
String |
否 |
通知标题。 |
|
summary |
String |
否 |
通知正文。 |
|
extraMap |
Map<String, String> |
否 |
已解析的通知扩展参数;业务参数键由发送方约定,不存在固定的业务跳转键。 |
返回值:无(void)。在此处理业务点击;SDK 或服务端已配置页面跳转时,应避免重复跳转。
代码示例
@Override
public void onNotificationOpened(Context context, String title, String summary,
Map<String, String> extraMap) {
String businessId = extraMap == null ? null : extraMap.get("businessId");
if (businessId != null) {
// 按应用业务约定处理点击;businessId 不是 SDK 固定字段。
}
}override fun onNotificationOpened(
context: Context, title: String?, summary: String?, extraMap: Map<String, String>?
) {
val businessId = extraMap?.get("businessId")
if (businessId != null) {
// 按应用业务约定处理点击。
}
}通知删除回调
void onNotificationRemoved(Context context, String messageId);
删除通知时返回服务端消息标识 messageId。它与 Android NotificationManager 使用的整数通知 ID 不是同一概念,不可直接互换。
参数说明
|
参数 |
类型 |
是否必填 |
说明 |
|
context |
Context |
是 |
SDK 分发删除事件使用的组件上下文。 |
|
messageId |
String |
否 |
被删除通知对应的服务端消息标识;使用前判空。 |
返回值:无(void)。表示 SDK 展示的通知被用户删除,不用于判断厂商系统通知的删除状态。
代码示例
@Override
public void onNotificationRemoved(Context context, String messageId) {
if (messageId != null) {
// 按消息标识清理应用保存的通知记录。
}
}override fun onNotificationRemoved(context: Context, messageId: String?) {
if (messageId != null) {
// 按消息标识清理应用保存的通知记录。
}
}迁移与验证
|
3.x 用法 |
4.x 用法 |
|
onNotificationOpened(..., String extraMap) |
改为 Map<String,String>,使用前判空。 |
|
onNotificationClickedWithNoAction(...) |
已删除,统一使用 onNotificationOpened。 |
|
onNotificationReceivedInApp(...) |
已删除,统一使用 onNotification。 |
|
辅助弹窗 onSysNoticeOpened |
业务逻辑移到 Receiver/Service 的 onNotificationOpened。 |
分别测试透传消息、自有通道通知前台/后台到达、展示拦截、自有与厂商通知点击、通知删除以及应用重新启动后的服务分发配置。排查 SDK 日志使用 TAG EMAS_PUSH,并结合正文模块筛选;应用示例自己的 Log TAG 与 SDK TAG 不必相同。
相关文档
接入流程请参见Android SDK接入(4.x)。
使用 3.x 的应用请参见消息与通知处理接口(3.x)。