小米推送Android版快速接入指南

如对小米推送有任何技术问题,请通过推送客服系统与我们联系http://dev.xiaomi.com/mipush/feedback/fe/

push&米币支付SDK接入 徐泽伟
xuzewei@xiaomi.com   qq:1145278810

 

目录

1. 客户端接入小米推送前的准备工作

  1. 小米开发者站开通小米开发者账号。
  2. 创建应用,开发者账号审核通过后你就可以在开发者站创建你的应用。
  3. 开启应用的推送服务。
  4. 下载SDK、文档和DEMO。

具体的操作,请参考《推送服务接入指南》

2. Demo的使用

Android Demo提供了一些基本功能,比如注册小米推送服务、设置别名、取消别名、订阅标签、取消标签、设置消息的接收时间段等等。

Demo的主Activity包含两个部分:基本操作的Button和显示这些操作结果信息(成功或失败)TextView。

通过修改Anroid Demo中部分代码,可以使在开发者站创建的应用快速的接入小米推送服务。

    1. 将DemoApplication.java中APP_ID、APP_KEY值替换为应用的对应值,TAG替换为应用的包名。
    2. 将AndroidManifest.xml中package和permission包名替换为应用的包名。
    3. 如果使用的 IDE 是 Android Studio,还需要修改 gradle 配置gradle_change

修改了以上几处的代码,可以在模拟器或者手机上安装此应用。Demo启动后,主界面上显示了”Register push success.”表示注册小米推送服务成功,这时可以设置别名、订阅标签。开发者可以利用小米网页推送工具向对应的别名或标签推送消息。为了能够看到更详细的log信息,可以在命令行下输入: adb logcat | grep 应用包名

3. 推送对象的选择

推送对象目前支持四种:RegID、别名、userAccount、标签。

  1. RegID:针对单一设备推送消息。应用调用MiPushClient类的静态方法registerPush注册小米推送服务,注册的结果将通过PushMessageReceiver继承类的onCommandResult方法和onReceiveRegisterResult中的MiPushCommandMessage参数对象message传到客户端。当message对象的command等于MiPushClient.COMMAND_REGISTER并且message对象的resultCode等于ErrorCode.SUCCESS时,message对象commandArguments包含了服务器返回的RegID。客户端的关键代码如下:
    public void onCommandResult(Context context, MiPushCommandMessage message) {
            String command = message.getCommand();
            List<String> arguments = message.getCommandArguments();
            if (MiPushClient.COMMAND_REGISTER.equals(command)) {
                if (message.getResultCode() == ErrorCode.SUCCESS) {
                  mRegID = arguments.get(0);
            }
    }

    RegID是由服务器端生成的,能够唯一标识某台手机上的某个应用。

    应用在获取到RegID后,需要将RegID上报到应用的服务器,此时应用服务端就可以利用RegID向客户端发送消息。

  2. 别名:针对单一设备推送消息。应用只有在成功注册小米推送服务后才能调用MiPushClient类的静态方法setAlias设置别名。同样,设置别名的结果将通过PushMessageReceiver继承类的onCommandResult方法中的MiPushCommandMessage参数对象message传到客户端。客户端关键代码如下:
    public void onCommandResult(Context context, MiPushCommandMessage message) {
            String command = message.getCommand();
            List<String> arguments = message.getCommandArguments();
            if (MiPushClient.COMMAND_SET_ALIAS.equals(command)) {
                if (message.getResultCode() == ErrorCode.SUCCESS) {
                  mAlias = arguments.get(0);
            }
    }

    成功设置别名后,服务器就可以通过这个别名将消息推送到对应的设备上。

    利用别名向设备推送消息的方法不需要应用服务器保存客户端上传的RegID。开发者可以根据业务的需要给不同设备设置不同的别名。

    注:一台设备可以设置多个不同的别名,而一个别名只能对应某一台设备。如果多台设备设置同一个别名,那么只有最后设置的一台设备生效。

  3. userAccount:针对多个设备推送消息。应用只有在成功注册小米推送服务后才能调用MiPushClient类的静态方法setUserAccount设置userAccount。同样,设置userAccount的结果将通过PushMessageReceiver继承类的onCommandResult方法中的MiPushCommandMessage参数对象message传到客户端。客户端关键代码如下:
    public void onCommandResult(Context context, MiPushCommandMessage message) {
            String command = message.getCommand();
            List<String> arguments = message.getCommandArguments();
            if (MiPushClient.COMMAND_SET_ACCOUNT.equals(command)) {
                if (message.getResultCode() == ErrorCode.SUCCESS) {
                  mAccount = arguments.get(0);
            }
    }

    开发者可以在不同设备上设置同一个userAccount。然后使用Server
    SDK给该userAccount发送消息;此时,所有设置了该userAccount的设备都可以收到消息。

  4. 标签:针对多个设备推送消息。应用只有成功注册小米推送服务后才能调用MiPushClient类的静态方法subscribe订阅标签。同样,订阅标签的结果将通过PushMessageReceiver继承类的onCommandResult方法中的MiPushCommandMessage参数对象message传到客户端。客户端关键代码如下:
    public void onCommandResult(Context context, MiPushCommandMessage message) {
            String command = message.getCommand();
            List<String> arguments = message.getCommandArguments();
            if (MiPushClient.COMMAND_SUBSCRIBE_TOPIC.equals(command)) {
                if (message.getResultCode() == ErrorCode.SUCCESS) {
                  mTopic = arguments.get(0);
            }
    }

    开发者可以结合自己的业务特征,给用户打上不同的标签(Topic)。在消息的推送过程中,开发者结合每条消息的内容和目标用户群,选择每条消息所对应的标签,可以进行更精准的定向推送。

    注:一台设备可以订阅多个不同的标签,并且一个标签可以对应多台设备,这点和别名不同。

4. 推送消息的类型

用户成功设置别名(订阅标签)后,服务端可以向该别名(标签)发送消息。

从开发者网站中下载的包含Server API的jar包只是封装了一些简单的HTTP请求,开发者可以根据需要封装成不同的语言版本。

服务端通过调用Message.Builder类的passThrough(int)方法设置pass_through参数来定义消息的类型,1表示透传消息,0表示通知消息。

  • 透传消息———
    封装消息的MiPushMessage对象直接通过PushMessageReceiver继承类的的onReceivePassThroghMessage方法传到客户端。
  • 通知消息
    ———消息到达客户端后会弹出通知,通知消息到达时,不需要用户点击通知就会通过PushMessageReceiver继承类的onNotificationMessageArrived方法传到客户端,只有在用户点击了通知后封装消息的MiPushMessage对象才会通过PushMessageReceiver继承类的onNotificationMessageClicked方法传到客户端。对于应用在前台时不弹通知类型的通知信息,通知到达后会通过PushMessageReceiver继承类的onNotificationMessageArrived方法传到客户端,但不会触发onNotificationMessageClicked方法。注:通知消息通过onNotificationMessageClicked传到客户端只对”自定义点击行为”有效。注:在MIUI上,如果没有收到onNotificationMessageArrived回调,是因为使用的MIUI版本还不支持该特性,需要升级MIUI。非MIUI手机都可以收到这个回调。

客户端接收消息的关键代码:

public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
        mMessage = message.getContent();
        if(!TextUtils.isEmpty(message.getTopic())) {
            mTopic=message.getTopic();
        } else if(!TextUtils.isEmpty(message.getAlias())) {
            mAlias=message.getAlias();
        }
    }
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
        mMessage = message.getContent();
        if(!TextUtils.isEmpty(message.getTopic())) {
            mTopic=message.getTopic();
        } else if(!TextUtils.isEmpty(message.getAlias())) {
            mAlias=message.getAlias();
        }
    }
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
        mMessage = message.getContent();
        if(!TextUtils.isEmpty(message.getTopic())) {
            mTopic=message.getTopic();
        } else if(!TextUtils.isEmpty(message.getAlias())) {
            mAlias=message.getAlias();
        }
    }

4.1. 透传消息

为了发送通知消息,服务端必须调用Message.Builder类的passThrough(int)方法将参数pass_through设置为1。

除了需要pass_through参数外,通知消息还需要设置一些其他的参数,比如payload 、 restricted_package_name 、
registration_id 、 alias 、 topic。

注:服务器不需要设置的title和description,即使设置了对客户端也是无效的。

参数的详细用法请参考《小米推送服务器SDK使用说明文档》

封装消息的MiPushMessage对象直接通过PushMessageReceiver继承类的的onReceivePassThroughMessage方法传到客户端。

4.2. 通知消息

为了发送通知消息,服务端必须调用Message.Builder类的passThrough(int)方法将参数pass_through设置为0。

除了需要pass_through参数外,通知消息还需要设置一些其他的参数,比如payload 、 restricted_package_name 、
registration_id 、 alias、topic 、 pass_through 、 title 、
description、notify_type等。参数的详细用法请参考《小米推送服务器SDK使用说明文档》

首先,介绍如何开启/关闭app在前台时的通知弹出。

应用在前台的情况下,通知消息到达客户端后是否弹出通知可以服务端来设置。服务端调用Message.Builder类的extra(String key, String
value)方法将EXTRA_PARAM_NOTIFY_FOREGROUND的值设置为”0″或者”1″。

当EXTRA_PARAM_NOTIFY_FOREGROUND值为”1″时,app会弹出通知栏消息;

当EXTRA_PARAM_NOTIFY_FOREGROUND值为”0″时,app不会弹出通知栏消息。

注:默认情况下会弹出通知栏消息。

例如:

private Message buildMessage() throws Exception {
     String PACKAGENAME = "com.xiaomi.mipushdemo";
     String messagePayload = “This is a message”;
     String title = “notification title”;
     String description = “notification description”;
     Message message = new Message.Builder()
          .title(title)
          .description(description).payload(messagePayload)
          .restrictedPackageName(MY_PACKAGE_NAME)
          .passThrough(0)
          .notifyType(1)
          .extra(Constants.EXTRA_PARAM_NOTIFY_FOREGROUND, "0")
          .build();
    return message;
}

接下来介绍通知消息的提醒类型和通知消息的点击行为。

4.2.1. 通知消息的提醒类型

通知的提醒类型分为三种:声音、振动和呼吸灯,可以是它们的任一组合。

服务端调用Message.Builder类的notifyType(int)方法设置通知的提醒类型。

notifyType的值可以是以下几种的OR组合:

  • DEFAULT_SOUND = 1;
  • DEFAULT_VIBRATE = 2;
  • DEFAULT_LIGHTS = 4;
  • DEFAULT_ALL = -1;

另外,服务端可以调用Message.Builder类的extra(String key, String
value)方法将Constants.EXTRA_PARAM_SOUND_URI的值设置为对应通知声音的URI。

例如:

private Message buildMessage() throws Exception {
     String PACKAGENAME = "com.xiaomi.mipushdemo";
     String messagePayload = “This is a message”;
     String title = “notification title”;
     String description = “notification description”;
     Message message = new Message.Builder()
          .title(title)
          .description(description).payload(messagePayload)
          .restrictedPackageName(MY_PACKAGE_NAME)
          .passThrough(0)
          .notifyType(1)
          .extra(Constants.EXTRA_PARAM_SOUND_URI, "android.resource://" + PACKAGENAME + "/raw/shaking")
          .build();
    return message;
}

4.2.2. 通知消息的点击行为

通知消息的点击行为,分为自定义点击行为和预定义点击行为。

4.2.2.1. 自定义点击行为

用户点击了客户端弹出的通知消息后会将封装消息的MiPushMessage对象通过PushMessageReceiver继承类的onNotificationMessageClicked方法传到客户端。

下面介绍一个应用场景。

场景1:开发者希望客户端在收到消息后启动应用的某一个Activity。

解决方法:开发者可以在onNotificationMessageClicked中调用context.startActivity方法,将所需要的信息通过Intent传过去。

对于场景1,如果客户端工程师不想写启动actvity的代码,可以使用下面介绍的预定义点击行为。

4.2.2.2. 预定义点击行为

预定义点击行为目前支持三种:(1) 打开当前的Launcher Activity (2) 打开当前app内的任意一个Activity (3)
打开网页。

服务端调用Message.Builder类的extra(String key, String
value)方法,将key设置为Constants.EXTRA_PARAM_NOTIFY_EFFECT,value设置为Constants.NOTIFY_LAUNCHER_ACTIVITY、Constants.NOTIFY_ACTIVITY或Constants.NOTIFY_WEB以得到不同的预定义行为。

  • Constants.NOTIFY_LAUNCHER_ACTIVITY:打开当前app对应的Launcher Activity。
  • Constants.ACTIVITY:打开当前app内的任意一个Activity。
  • Constants.NOTIFY_WEB:打开网页。

对于第一种和第二种预定义的点击行为,用户点击了客户端弹出的通知消息后会将封装消息的MiPushMessage对象通过Intent传到客户端,客户端在相应的Activity中可以调用Intent的getSerializableExtra(PushMessageHelper.KEY_MESSAGE)方法得到MiPushMessage对象。而第三种预定义行为,客户端是获取不到MiPushMessage对象。

对于自定义点击行为中介绍的场景1,服务端通过通过Message.Builder的extra方法设置Constants.EXTRA_PARAM_NOTIFY_EFFECT和Constants.EXTRA_PARAM_INTENT_URI值就可以解决,不需要客户端添加任何代码。

详细用法请参考《小米推送服务器SDK使用说明文档》

5. 推送统计

目前小米推送提供了推送数据、消息记录、用户数据供开发者查询。

开发者既可以在小米开发者中心网站上查看,也可以利用数据API获取。

  1. 推送数据提供当日实时和历史每日的已推送总量(区分群发和单发)、已送达消息数和已点击数,开发者可以指定日期查询相应数据。
  2. 用户数据实时数据提供当日实时在线用户数、截至目前最高在线用户数;历史数据提供历史上每天的最高在线用户数、新增用户数和日活跃用户数,同样支持指定时间段的查询。注:用户数据中的在线和活跃是以长连接是否连接为标准的,应用不一定启动。
  3. 消息记录消息记录:提供最近30天内的消息记录列表,每条消息提供计划推送数、送达数和送达率、点击数和点击率的统计,支持通过消息id或通知标题摘要中的关键词进行查询。注:为了避免展示用户较为隐私的信息,计划推送数在10以下的通知我们没有展示通知的内容,也屏蔽了针对这部分通知内容的检索。