全部产品

快速开始

更新时间:2020-09-21 20:05:04

本文介绍如何快速将消息推送组件接入到 Android 客户端。消息推送支持 原生 AARmPaaS Inside 组件化(Portal & Bundle) 三种接入方式。

完整的接入过程分为以下 5 步:

  1. 添加 pushSDK:添加 SDK 依赖。
  2. 初始化 pushSDK:建立客户端和移动推送网关的长连接,获取设备标识。
  3. 监听消息:为接收消息、获取 Android 设备标识(Ad-token)编写 service,实现设备维度的消息推送。
  4. 上报用户 ID:将用户标识上传到服务端,进行用户和设备绑定,实现用户维度的消息推送。
  5. 上报推送数据:将消息到达、打开和忽略的数据上传至服务端进行统计分析,您可在控制台页面上查看统计分析结果。

前置条件

添加 pushSDK

添加 SDK 依赖。

原生 AAR 方式

参考 AAR 组件管理,通过 组件管理(AAR)在工程中安装 消息推送(PUSH)组件。

mPaaS Inside 方式

在工程中通过 组件管理 安装 消息推送(PUSH)组件。

更多信息,请参考 管理组件依赖 > 增删组件依赖

组件化方式

在 Portal 和 Bundle 工程中通过 组件管理 安装 消息推送(PUSH)组件。

更多信息,请参考 管理组件依赖 > 增删组件依赖

初始化 pushSDK

初始化 pushSDK,建立客户端和移动推送网关的长连接,获取设备标识。

客户端通过调用 mPaaS 中间层的 MPPush 类来实现对 pushSDK 的初始化:

  1. MPPush.setup(Application application);
  2. MPPush.init(Context context);

初始化过程中,pushSDK 会用设定好的地址和端口尝试建立连接。如果客户端建连信息中未携带设备标识,移动推送网关在建连成功后将下发设备标识(Ad-token)。

在 pushSDK 成功获取到设备标识后,您可以通过 App 中配置好的 service 来获取这个设备标识。具体方法,参考 监听消息 中的示例。

监听消息

在接收到推送消息,或者获取到 Ad-token 后,pushSDK 都会启动一个 service 来对该消息或该 Ad-token 进行处理。为接收消息、获取 Android 设备标识(Ad-token)编写 service,实现设备维度的消息推送。

关于此任务

通过编写和配置继承自 AliPushRcvService 的 service,用来接收移动推送网关下发的设备标识和消息。

操作步骤

  1. 编写 service。客户端可以分别为接收消息、获取 Ad-token 各编写一个 service,也可以共用同一个 service。下面是共用同一个 service 的示例代码:

    1. public class PushMsgService extends AliPushRcvService {
    2. private static final String TAG = "pushTag";
    3. public static final String PUSH_SERVICE_ACTION = "tt-action";
    4. //推送消息的类型,用户自定义即可
    5. public static final int TYPE_MSG = -1;
    6. public static final int TYPE_INNER_PUSH_INIT = -2;
    7. public static final int TYPE_THIRD_PUSH_INIT = -3;
    8. //自建渠道推送标识
    9. public static String mAdToken = "";
    10. //第三方渠道推送标识
    11. public static String mThirdToken = "";
    12. public static String mUserId = "mpaas_push_demo";
    13. public static int platformType = 0;
    14. public static boolean useDefault = false;
    15. public PushMsgService() {
    16. super();
    17. }
    18. /**
    19. * 判断展示类消息是否使用内建通知。
    20. * 返回true,则所有展示类(非静默)消息由mPaaS进行处理,handleActionReceived不再被调用。
    21. * 返回false,表示透传所有消息。
    22. */
    23. @Override
    24. protected boolean useDefaultNotification(String msgKey, String msgValue) {
    25. Intent intent = new Intent(PUSH_SERVICE_ACTION);
    26. intent.putExtra("push_type", TYPE_MSG);
    27. intent.putExtra("push_key", msgKey);
    28. intent.putExtra("push_value", msgValue);
    29. LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    30. LoggerFactory.getTraceLogger().debug(TAG, "onHandleIntent sendLocalBroadcast: " + intent.toString());
    31. return useDefault;
    32. }
    33. /**
    34. * 消息处理回调,自建消息需要接入方自行处理弹出通知等工作。
    35. * @param msgKey 消息推送的 key
    36. * @param msgValue 消息推送的 value
    37. * @param clicked 是否已经点击了
    38. * 对于三方渠道来说clicked = true,展示通知栏
    39. * 对于自建渠道来说clicked = false,没有展示通知栏
    40. */
    41. @Override
    42. protected void handleActionReceived(String msgKey, String msgValue, boolean clicked) {
    43. if (TextUtils.isEmpty(msgValue)) {
    44. return;
    45. }
    46. BDataBean data = BDataBean.create(msgValue);
    47. if (clicked) {
    48. try {
    49. Uri uri = Uri.parse(data.getUrl());
    50. Intent actionIntent = new Intent(Intent.ACTION_VIEW);
    51. actionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    52. actionIntent.setData(uri);
    53. actionIntent.putExtra("data", data.getParams());
    54. startActivity(actionIntent);
    55. } catch (Exception e) {
    56. Log.e(TAG, "Unable start activity due to wrong format uri", e);
    57. }
    58. } else {
    59. // show your notification and handle action
    60. NotificationHelper helper = new NotificationHelper(getApplicationContext());
    61. helper.notify("(注意:非内建消息)" + data.getTitle(), data.getContent());
    62. }
    63. }
    64. /**
    65. * @param adToken 自建渠道的推送标识
    66. */
    67. @Override
    68. protected void handleActionId(String adToken) {
    69. PushAppInfo pushAppInfo = new PushAppInfo(getApplicationContext());
    70. pushAppInfo.setAppToken(adToken);
    71. LoggerFactory.getTraceLogger().debug(TAG, "自建渠道的adToken: " + adToken);
    72. Intent intent = new Intent(PUSH_SERVICE_ACTION);
    73. intent.putExtra("push_type", TYPE_INNER_PUSH_INIT);
    74. intent.putExtra("push_token", adToken);
    75. LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    76. mAdToken = adToken;
    77. }
    78. /**
    79. * @param thirdToken 三方渠道的推送标识
    80. * @param platformType 三方渠道的类型 华为=5 小米=4 OPPO=7 VIVO=8
    81. */
    82. @Override
    83. protected void handleActionThirdId(String thirdToken, int platformType) {
    84. LoggerFactory.getTraceLogger().debug(TAG, "第三方渠道的adToken: " + thirdToken + "platformType: " + platformType);
    85. Intent intent = new Intent(PUSH_SERVICE_ACTION);
    86. intent.putExtra("push_type", TYPE_THIRD_PUSH_INIT);
    87. intent.putExtra("push_thirdToken", thirdToken);
    88. intent.putExtra("push_channel", platformType);
    89. LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    90. mThirdToken = thirdToken;
    91. PushMsgService.platformType = platformType;
    92. }
    93. }
  2. AndroidManifest.xml 配置此 service。基于 mPaaS 框架的工程,在 portal 或 bundle 的 AndroidManifest.xml 中都可以配置。
    通配符说明:你需要将代码中 ${} 替换为真实的值。

    • ${applicationId}:包名。
      示例:将 ${applicationId}.push.action.CHECK 替换为 com.mpaas.demo.push.action.CHECK
    • ${appId}${workspaceId}:应用 ID 与工作空间 ID。mPaaS 控制台 > 代码管理 > 代码配置 页面 下载配置文件.config 文件包含了两者的值。
      1. <uses-permission android:name="android.permission.INTERNET" />
      2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
      4. <uses-permission android:name="android.permission.BROADCAST_STICKY" />
      5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      6. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      7. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      8. <uses-permission android:name="android.permission.WRITE_SETTINGS" />
      9. <uses-permission android:name="android.permission.VIBRATE" />
      10. <uses-permission android:name="android.permission.WAKE_LOCK" />
      11. <!-- RecvMsgIntentService 是指前文代码中定义的 service -->
      12. <service android:name="com.mpaas.demo.push.RecvMsgIntentService"
      13. android:exported="false" >
      14. <intent-filter>
      15. //MESSAGE_RECEIVED 表示处理接收到的消息
      16. <action android:name="${applicationId}.push.action.MESSAGE_RECEIVED" />
      17. //REGISTRATION_ID 表示处理获取到的设备标识
      18. <action android:name="${applicationId}.push.action.REGISTRATION_ID" />
      19. <category android:name="${applicationId}" />
      20. </intent-filter>
      21. </service>
      22. <!-- 需要配置您的 alipush appId-->
      23. <meta-data
      24. android:name="ALIPUSH_APPID"
      25. android:value="${appId}-${workspaceId}" />
      26. <service
      27. android:name="com.alipay.pushsdk.push.NotificationService"
      28. android:enabled="true"
      29. android:exported="false"
      30. android:process=":push"
      31. android:label="NotificationService">
      32. <intent-filter>
      33. <action android:name="${applicationId}.push.action.START_PUSHSERVICE" />
      34. </intent-filter>
      35. </service>
      36. <service
      37. android:name="com.alipay.pushsdk.push.AppInfoRecvIntentService"
      38. android:exported="false"
      39. android:process=":push">
      40. </service>
      41. <receiver
      42. android:name="com.alipay.pushsdk.BroadcastActionReceiver"
      43. android:enabled="true"
      44. android:process=":push">
      45. <intent-filter android:priority="2147483647">
      46. <action android:name="android.intent.action.BOOT_COMPLETED" />
      47. <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
      48. <action android:name="android.intent.action.USER_PRESENT" />
      49. <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
      50. </intent-filter>
      51. </receiver>
      52. <receiver
      53. android:name="com.alipay.mobile.logmonitor.ClientMonitorWakeupReceiver"
      54. android:enabled="true"
      55. android:process=":push">
      56. <intent-filter>
      57. <action android:name="android.intent.action.BOOT_COMPLETED" />
      58. <action android:name="${applicationId}.push.action.CHECK" />
      59. <action android:name="${applicationId}.monitor.command" />
      60. </intent-filter>
      61. </receiver>
  3. 您可在控制台上创建极简推送类型的消息,测试基于设备维度的消息推送是否成功。

    创建消息的操作方法,参见 创建消息 > 操作方法

后续步骤

  • 10.1.60 基线已支持内建通知消息,以满足展示类消息推送场景,具体方法参考 内建消息通知
  • 为了提升消息推送的到达率,您可以选择接入 Android 客户端三方推送渠道,具体方法参考 第三方推送渠道
  • pushSDK 支持基于用户标识的推送,你可以选择将用户标识和设备标识进行绑定,具体方法参考 上报用户 ID

上报用户 ID

如果需要用户维度的推送,当用户登录时,将该用户标识上传到服务端,由服务端向移动推送服务发出请求,将用户和设备进行绑定。当用户登出时,将该绑定关系解绑。

服务端的相关处理请参考 配置服务端

操作步骤如下:

  1. 为了方便开发者进行用户绑定,提供接口进行绑定和解除绑定操作,示例代码如下:

    1. // 具体代码可以参考 Demo
    2. // 此处的用户 userId 不一定为开发者用户系统的真实标识,但是一定是可以与用户形成一一映射关系。
    3. // 参数 userId,adtoken(会在 service handleActionId 中接收到)
    4. ResultPbPB resultBean = MPPush.bind(getApplicationContext(), your userId, ad-token);
    5. ResultPbPB resultBean = MPPush.unbind(getApplicationContext(), your userId, ad-token);
    6. // 如果您已经通过调用 MPLogger.reportUserLogin() 或 MPLogger.setUserId() 设置了 userId,也可以直接使用以下方法(版本须为 10.1.60.9 及以上,或 10.1.68.3 及以上)
    7. ResultPbPB resultBean = MPPush.bind(getApplicationContext(), ad-token);
    8. ResultPbPB resultBean = MPPush.unbind(getApplicationContext(), ad-token);
  2. 选择绑定时机,可选的关键时机如下:

    • 用户登录(有登录态 App)和 push 收到 Ad-token 后,为了登录后首次接口收到 push。
    • App 冷启动,为了防止出现未注册情形。

上报推送数据

PushSDK 定义消息到达、打开和忽略的接口,调用这些接口,上报相关数据至服务端后,您可在 控制台 > 后台服务管理 > 消息推送 > API 分析 页面上查看各数据的统计分析结果。

到达

在接入 PushSDK 之后,您无需执行任何操作,MPS 将自动完成消息到达相关数据的统计分析。

对于通过不同渠道推送的消息,MPS 采用不同的方式统计其到达量和到达率。

  • 自建渠道
    通过自建渠道推送的消息,在其到达客户端时,PushSDK 将自动上报消息到达事件,服务端自动统计消息的到达量以及到达率。
  • 三方渠道
    通过三方渠道推送的消息,由相应渠道的后端服务返回推送结果数据,MPS 对此数据进行统计分析,得到消息的到达量和到达率。

打开

调用 reportPushOpen 接口,上报消息打开事件,服务端将统计消息被打开的数量以及打开率。

  1. public static void reportPushOpen(String pushMsgId, String pushMsgValue)

调用时机

对于三方渠道的通知栏消息以及需要自定义展示的消息,调用时机不同,具体如下:

  • 三方渠道通知栏消息:消息被打开后,PushSDk 将自动调用 reportPushOpen 接口,上报相关数据。
  • 自定义展示的消息:您需要添加消息打开操作的监听,监听到打开操作时,调用 reportPushOpen 接口,上报相关数据。

参数说明

pushMsgIdpushMsgValue 可从推送的消息体中获取,如下图所示。

推送消息体

  • pushMsgId:对应于以上消息体中的 k 值,为消息 ID。
  • pushMsgValue:对应于以上消息体中的 bData 值。

忽略

调用 reportPushIgnored 接口,上报消息的忽略事件,服务端将统计消息的忽略量以及忽略率。

  1. public static void reportPushIgnored(String pushMsgId, String pushMsgValue)

调用时机

对于需要自定义展示的消息,您需要添加消息被忽略的监听,监听到消息被忽略时,调用 reportPushIgnored 接口,上报相关数据。

说明:对于无法自定义展示的消息,MPS 将无法统计其忽略量。

参数说明

参见 参数说明

代码示例

点击此处 下载示例代码包。

后续操作

接入完成后,可以通过服务端调用 RESTful 接口,推送消息。具体内容请参考 服务端配置 > 推送消息