小米推送服务Android版客户端SDK使用指南

 

1. 客户端SDK说明

在使用小米推送服务前,开发者需要先登录小米开发者网站http://developer.xiaomi.com ,注册app,申请AppId, AppKey,
AppSecret。其中AppId和AppKey是客户端的身份标识,在客户端SDK初始化时使用;AppSecret是服务器端的身份标识,在使用Server
SDK向客户端发送消息时使用。然后下载最新的SDK压缩包,其中包括了Server SDK、Client SDK、android DEMO。

Android的SDK以jar形式提供, 第三方APP只需要添加少量代码即可接入小米推送服务。

推送服务客户端SDK主要功能接口请参考第3节API说明。客户端在注册成功后,会得到服务器颁发的regId,然后可以通过订阅topic、设置alias(参考2.3)来接收推送消息。小米推送目前支持两种消息传递方式:透传方式和通知栏方式。透传消息到达手机端后,SDK会将消息通过广播方式传给AndroidManifest中注册的PushMessageReceiver的子类的onReceivePassThroughMessage;对于通知栏消息,SDK会根据消息中设置的信息弹出通知栏通知,通知消息到达时会到达PushMessageReceiver子类的onNotificationMessageArrived方法,用户点击之后再传给您的PushMessageReceiver的子类的onNotificationMessageClicked方法;对于应用在前台时不弹出通知的通知消息,SDK会将消息通过广播方式传给AndroidManifest中注册的PushMessageReceiver的子类的onNotificationMessageArrived方法(在MIUI上,如果没有收到onNotificationMessageArrived回调,是因为使用的MIUI版本还不支持该特性,需要升级到MIUI7之后。非MIUI手机都可以收到这个回调)。

2. SDK使用说明

这里介绍如何配置和使用小米推送,您也可以参照SDK中的demo来配置和使用小米推送。

2.1.  配置AndroidManifest.xml文件

  1. 小米推送服务SDK支持的最低安卓版本为2.2。
    <uses-sdk  android:minSdkVersion="8"/>
  2. 推送服务需要的权限列表
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.VIBRATE"/>
    <permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" />
    <!--这里com.xiaomi.mipushdemo改成app的包名-->   
    <uses-permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE" />
    <!--这里com.xiaomi.mipushdemo改成app的包名-->
  3. 推送服务需要配置的service和receiver
    <service
      android:enabled="true"
      android:process=":pushservice"
      android:name="com.xiaomi.push.service.XMPushService"/>
    <service
      android:name="com.xiaomi.push.service.XMJobService"
      android:enabled="true"
      android:exported="false"
      android:permission="android.permission.BIND_JOB_SERVICE"
      android:process=":pushservice" />
    <!--注:此service必须在3.0.1版本以后(包括3.0.1版本)加入-->
    <service
      android:enabled="true"
      android:exported="true"
      android:name="com.xiaomi.mipush.sdk.PushMessageHandler" /> 
    <service android:enabled="true"
      android:name="com.xiaomi.mipush.sdk.MessageHandleService" /> 
    <!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入-->
    <receiver
      android:exported="true"
      android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" >
      <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </receiver>
    <receiver
      android:exported="false"
      android:process=":pushservice"
      android:name="com.xiaomi.push.service.receivers.PingReceiver" >
      <intent-filter>
        <action android:name="com.xiaomi.push.PING_TIMER" />
      </intent-filter>
    </receiver>

这里将XMPushService和PingReceiver定义在了pushservice进程中,您也可以配置其运行在任意进程。如果没有配置android:process这个属性,那么它们将运行在应用的主进程中。

从3.1版本开始,我们会在 debuggable 是 true 时(也就是说不会影响 release 的版本)自动检测 AndroidManifest.xml,如果 AndroidManifest.xml 不符合上述配置,就会在启动时抛出 IllegalManifestException。

2.2. 自定义一个BroadcastReceiver类

为了接收消息,您需要自定义一个继承自PushMessageReceiver类的BroadcastReceiver,实现其中的onReceivePassThroughMessage,onNotificationMessageClicked,onNotificationMessageArrived,onCommandResult和onReceiveRegisterResult方法,然后把该receiver注册到AndroidManifest.xml文件中。onReceivePassThroughMessage用来接收服务器发送的透传消息,onNotificationMessageClicked用来接收服务器发来的通知栏消息(用户点击通知栏时触发),onNotificationMessageArrived用来接收服务器发来的通知栏消息(消息到达客户端时触发,并且可以接收应用在前台时不弹出通知的通知消息),onCommandResult用来接收客户端向服务器发送命令消息后返回的响应,onReceiveRegisterResult用来接受客户端向服务器发送注册命令消息后返回的响应。

例如:

自定义的BroadcastReceiver

public class DemoMessageReceiver extends PushMessageReceiver {
    private String mRegId;
    private long mResultCode = -1;
    private String mReason;
    private String mCommand;
    private String mMessage;
    private String mTopic;
    private String mAlias;
    private String mUserAccount;
    private String mStartTime;
    private String mEndTime;
    @Override
    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();
        } else if(!TextUtils.isEmpty(message.getUserAccount())) {
            mUserAccount=message.getUserAccount();
        }
    }
    @Override
    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();
        } else if(!TextUtils.isEmpty(message.getUserAccount())) {
            mUserAccount=message.getUserAccount();
        }
    }
    @Override
    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();
        } else if(!TextUtils.isEmpty(message.getUserAccount())) {
            mUserAccount=message.getUserAccount();
        }
    }
    @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);
        String cmdArg2 = ((arguments != null && arguments.size() > 1) ? arguments.get(1) : null);
        if (MiPushClient.COMMAND_REGISTER.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mRegId = cmdArg1;
            }
        } else if (MiPushClient.COMMAND_SET_ALIAS.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mAlias = cmdArg1;
            }
        } else if (MiPushClient.COMMAND_UNSET_ALIAS.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mAlias = cmdArg1;
            }
        } else if (MiPushClient.COMMAND_SUBSCRIBE_TOPIC.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mTopic = cmdArg1;
            }
        } else if (MiPushClient.COMMAND_UNSUBSCRIBE_TOPIC.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mTopic = cmdArg1;
            }
        } else if (MiPushClient.COMMAND_SET_ACCEPT_TIME.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mStartTime = cmdArg1;
                mEndTime = cmdArg2;
            }
        } 
    }
    @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);
        String cmdArg2 = ((arguments != null && arguments.size() > 1) ? arguments.get(1) : null);
        if (MiPushClient.COMMAND_REGISTER.equals(command)) {
            if (message.getResultCode() == ErrorCode.SUCCESS) {
                mRegId = cmdArg1;
            }
        } 
    }
}

将自定义的BroadcastReceiver注册到AndroidManifest.xml文件中

<receiver
  android:exported="true"
  android:name="com.xiaomi.mipushdemo.DemoMessageReceiver">
          <!--这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名-->
  <intent-filter>
    <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
  </intent-filter>
    <intent-filter>
    <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
  </intent-filter>
  <intent-filter>
    <action android:name="com.xiaomi.mipush.ERROR" />
  </intent-filter>
</receiver>

注意:

  1. 上述方法运行在非UI线程中。
  2. 如果你的应用使用了混淆,你需要keep自定义的BroadcastReceiver。自定义的BroadcastReceiver继承PushMessageReceiver,使用下面的代码是不行的。
    -keep public class * extends android.content.BroadcastReceiver

    你需要使用下面的代码keep自定义的BroadcastReceiver。

    #这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名
    -keep class com.xiaomi.mipush.sdk.DemoMessageReceiver {*;}

2.3. 调试日志

2.3.1. 打开Logcat调试日志

在自定义Application的onCreate方法加入如下代码。

LoggerInterface newLogger = new LoggerInterface() {
     @Override
     public void setTag(String tag) {
         // ignore
     }
     @Override
     public void log(String content, Throwable t) {
         Log.d(TAG, content, t);
     }
     @Override
     public void log(String content) {
         Log.d(TAG, content);
     }
};
Logger.setLogger(this, newLogger);

注:默认情况下,我们会将日志内容写入SDCard/Android/data/app
pkgname/files/MiPushLog目录下的文件。如果app需要关闭写日志文件功能(不建议关闭),只需要调用Logger.disablePushFileLog(context)即可。

2.4. 注册推送服务

通过调用MiPushClient.registerPush来初始化小米推送服务。注册成功后,您可以在自定义的onCommandResult和onReceiveRegisterResult中收到注册结果,其中的regId即是当前设备上当前app的唯一标示。您可以将regId上传到自己的服务器,方便向其发消息。

为了提高push的注册率,你可以在Application的onCreate中初始化push。你也可以根据需要,在其他地方初始化push。

代码如下:

public class DemoApplication extends Application {

    public static final String APP_ID = "your appid";
    public static final String APP_KEY = "your appkey";
    public static final String TAG = "your packagename";

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化push推送服务
        if(shouldInit()) {
            MiPushClient.registerPush(this, APP_ID, APP_KEY);
        }
        //打开Log
        LoggerInterface newLogger = new LoggerInterface() {

            @Override
            public void setTag(String tag) {
                // ignore   
            }

            @Override
            public void log(String content, Throwable t) {
                Log.d(TAG, content, t);
            }

            @Override
            public void log(String content) {
                Log.d(TAG, content);
            }
        };
        Logger.setLogger(this, newLogger);
    }

    private boolean shouldInit() {
        ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
        List<RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        String mainProcessName = getPackageName();
        int myPid = Process.myPid();
        for (RunningAppProcessInfo info : processInfos) {
            if (info.pid == myPid && mainProcessName.equals(info.processName)) {
                return true;
            }
        }
        return false;
    }
}

注意:因为推送服务XMPushService在AndroidManifest.xml中设置为运行在另外一个进程,这导致本Application会被实例化两次,所以我们需要让应用的主进程初始化。

2.5. 设置alias、userAccount和订阅topic

在注册成功,收到regId之后,即可调用MiPushClient.setAlias来设置alias,调MiPushClient.setUserAccount来设置userAccount,调MiPushClient.subscribe订阅topic。

alias可以理解为regId的别名,开发者可以将alias设置为自己应用帐号系统的帐号,或者设备标识等。然后在使用Server
SDK发送消息的时候,即可直接指定发送给特定的alias,而不是regId,避免存储regId。

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

主题用来做广播消息。不同手机上的同一个app可以订阅同一个主题。通过发送主题消息的API,即可同时向所有订阅该主题的客户端发送消息。比如,您有一个新闻类的app,可以自定义“财经”、“体育”、“科技“等主题;对于经常阅读财经新闻的用户,您可以帮用户订阅“财经”类主题,当有新的财经要闻发生时,直接通过主题推送该新闻给所有订阅该主题的用户。

3. API说明

对开发者而言,使用客户端SDK可以完成两方面功能,一方面是客户端给服务器发送各种请求,另一方面是服务器给客户端发送的消息和对客户端请求的响应。它们分别对应MiPushClient的接入类和PushMesssageReceiver的实现类。

3.1. MiPushClient的接入类

MiPushClient是MiPush Client
SDK在Android平台的接入类。该类提供了一系列静态方法(static),无需实例化。

3.1.1. MiPushClient

public abstract class
extends Object
java.lang.Object 
↳ com.xiaomi.mipush.sdk.MiPushClient

3.1.2. 成员列表

表 1. MiPushClient成员列表

API 功能 使用场景
registerPush(Context context, String appID, String appToken) 注册MiPush推送服务。详细说明请参照3.4.1 由开发者决定是否开启推送
unregisterPush(Context context) 注销MiPush推送服务。详细说明请参照3.4.2 由开发者决定是否注销推送
setAlias(Context context, String alias, String category) 为指定用户设置alias。详细说明请参照3.4.3 开发者决定通过alias推送
unsetAlias(Context context, String alias, String category) 取消指定用户的alias。详细说明请参照3.4.4 开发者需要取消用户别名
setUserAccount(final Context context, final String userAccount, String
category)
为指定用户设置userAccount。详细说明请参照3.4.5 开发者决定通过userAccount推送
unsetUserAccount(final Context context, final String userAccount, String
category)
取消指定用户的userAccount。详细说明请参照3.4.6 开发者需要取消用户userAccount
subscribe(Context context, String topic, String category) 为某个用户设置订阅topic。详细说明请参照3.4.7 按照用户的订阅,开发者实现根据订阅分组群发
unsubscribe(Context context, String topic, String category) 取消某个用户的订阅topic。详细说明请参照3.4.8 用户取消某个订阅topic
pausePush(Context context, String category) 暂停接收MiPush服务推送的消息。详细说明请参照3.4.10 app在恢复MiPush推送服务之前,不接收任何推送消息
resumePush(Context context, String category) 恢复接收MiPush服务推送的消息,这时服务器会把暂停时期的推送消息重新推送过来。详细说明请参照3.4.11 恢复接收MiPush服务推送消息
setAcceptTime(Context context, int startHour, int startMin, int endHour,
int endMin, String category)
设置接收MiPush服务推送的时段,不在该时段的推送消息会被缓存起来,到了合适的时段再向app推送原先被缓存的消息。详细说明请参照3.4.9 用户可以控制什么时段接收推送消息
getAllAlias(Context context) 方法返回了客户端设置的别名列表(如果客户端没有设置别名,则返回空列表)。详细说明请参照3.4.12 开发者需要查询所设置的别名。
getAllTopic(Context context) 方法返回了客户端订阅的主题列表(如果客户端没有订阅主题,则返回空列表)。详细说明请参照3.4.13 开发者需要查询所订阅的主题。
reportMessageClicked(Context context, String msgid) 上报点击的消息。详细说明请参照3.4.14 开发者获取消息的点击率。
checkManifest(Context context) 检查AndroidManifest是否正确声明本SDK要求的所有组件和权限。详细说明请参照3.4.17 3.1版本已移除,开发应用时。
clearNotification(Context context, int notifyId) 清除小米推送弹出的某一个notifyId通知。详细说明请参照3.4.18 清除小米推送弹出的某一个notifyId通知。
clearNotification(Context context) 清除小米推送弹出的所有通知。详细说明请参照3.4.19 清除小米推送弹出的所有通知。
setLocalNotificationType(final Context context, int notifyType) 客户端设置通知消息的提醒类型。注:当服务端指定了消息的提醒类型,会优选考虑客户端设置的。 客户端设置通知消息的提醒类型。
clearLocalNotificationType(final Context context) 清除客户端设置的通知消息提醒类型。 清除客户端设置的通知消息提醒类型。
getRegId(Context context) 获取客户端的RegId。 获取客户端的RegId。
disablePush(Context context) 关闭MiPush推送服务,不再维护长连接,服务不可用。详细说明请参照3.4.24。 长期不需要推送服务,保留设备注册信息(RegID等)。
enablePush(Context context) 打开 MiPush 推送服务,继续维护长连接。详细说明请参照3.4.25。 disablePush 后,需要再次使用推送服务,RegID等信息与disablePush前保持一致。

 

3.2. ErrorCode错误类型

ErrorCode是接入push失败后,返回的错误类型。

3.2.1. ErrorCode

public abstract class
extends Object
java.lang.Object 
↳ com.xiaomi.mipush.sdk.ErrorCode

3.2.2. 静态变量

表 2. ErrorCode静态变量

静 态 变 量 含 义
SUCCESS 表示接入push成功。
ERROR_SERVICE_UNAVAILABLE 表示由于网络原因导致的push连接失败。
ERROR_INTERNAL_ERROR push内部状态错误,遇到此类错误请联系开发人员。
ERROR_AUTHERICATION_ERROR push连接的认证失败。
ERROR_INVALID_PAYLOAD 客户端的发给PUSH通道的消息格式不合法。

 

3.3. PushMesssageReceiver广播接收器

PushMessageReceiver是一个抽象的BroadcastReceiver类,里面定义了五个方法,分别为onReceivePassThroughMessage,onNotificationMessageClicked,onNotificationMessageArrived,onCommandResult和onReceiveRegisterResult。

它的用途有两种:

  1. 获取服务器推送的消息
  2. 获取调用MiPushClient方法的返回结果

3.3.1. PushMesssageReceiver

public abstract class
extends Object
java.lang.Object 
↳ com.xiaomi.mipush.sdk.PushMesssageReceiver

3.3.2. 成员列表

表 3. PushMesssageReceiver成员列表

API 功能
onReceivePassThroughMessage(Context context, MiPushMessage message) 接收服务器推送的透传消息,消息封装在 MiPushMessage类中。详细说明请参照3.4.13
onNotificationMessageClicked(Context context, MiPushMessage
message)
接收服务器推送的通知消息,用户点击后触发,消息封装在 MiPushMessage类中。详细说明请参照3.4.13
onNotificationMessageArrived(Context context, MiPushMessage
message)
接收服务器推送的通知消息,消息到达客户端时触发,还可以接受应用在前台时不弹出通知的通知消息,消息封装在
MiPushMessage类中。在MIUI上,只有应用处于启动状态,或者自启动白名单中,才可以通过此方法接受到该消息。详细说明请参照3.4.13
onCommandResult(Context context, MiPushCommandMessage
message)
获取给服务器发送命令的结果,结果封装在MiPushCommandMessage类中。详细说明请参照3.4.14。
onReceiveRegisterResult(Context context, MiPushCommandMessage
message)
获取给服务器发送注册命令的结果,结果封装在MiPushCommandMessage类中。详细说明请参照3.4.14。

 

3.4. API详细说明

3.4.1. public static void registerPush(Context context, String appID, String appKey)

注册MiPush推送服务,建议在app启动的时候调用。

表 4. registerPush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
appID 在开发者网站上注册时生成的,MiPush推送服务颁发给app的唯一认证标识
appKey 在开发者网站上注册时生成的,与appID相对应,用于验证appID是否合法

 

3.4.2. public static void unregisterPush(Context context)

关闭MiPush推送服务,当用户希望不再使用MiPush推送服务的时候调用,调用成功之后,app将不会接收到任何MiPush服务推送的数据,直到下一次调用registerPush
()。

注: 调用unregisterPush()之后,服务器不会向app发送任何消息。

表 5. unregisterPush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.3. public static void setAlias(Context context, String alias, String category)

开发者可以为指定用户设置别名,然后给这个别名推送消息,效果等同于给RegId推送消息。

注: 一个RegId可以被设置多个别名,如果设置的别名已经存在,会覆盖掉之前的别名。

表 6. setAlias函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
alias 为指定用户设置别名
category 扩展参数,暂时没有用途,直接填null

 

3.4.4. public static void unsetAlias(Context context, String alias, String category)

开发者可以取消指定用户的某个别名,服务器就不会给这个别名推送消息了。

表 7. unsetAlias函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
alias 为指定用户取消别名
category 扩展参数,暂时没有用途,直接填null

 

3.4.5. public static void setUserAccount(final Context context, final String userAccount,
String category)

开发者可以为指定用户设置userAccount。

表 8. setUserAccount函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
userAccount 为指定用户设置userAccount
category 扩展参数,暂时没有用途,直接填null

 

3.4.6. public static void unsetUserAccount(final Context context, final String userAccount,
String category)

开发者可以取消指定用户的某个userAccount,服务器就不会给这个userAccount推送消息了。

表 9. unsetUserAccount函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
userAccount 为指定用户取消userAccount
category 扩展参数,暂时没有用途,直接填null

 

3.4.7. public static void subscribe(Context context, String topic, String category)

为某个用户设置订阅主题;根据用户订阅的不同主题,开发者可以根据订阅的主题实现分组群发。

表 10. subscribe函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
topic 某个用户设置订阅的主题
category 扩展参数,暂时没有用途,直接填null

 

3.4.8. public static void unsubscribe(Context context, String topic, String
category)

为某个用户取消某个订阅主题。

表 11. unsubscribe函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
topic 某个用户取消订阅的主题
category 扩展参数,暂时没有用途,直接填null

 

3.4.9. public static void setAcceptTime(Context context, int startHour, int startMin, int
endHour, int endMin, String category)

设置接收MiPush服务推送的时段,不在该时段的推送消息会被缓存起来,到了合适的时段再向app推送原先被缓存的消息。

这里采用24小时制,如果开始时间早于结束时间,则这个时段落在一天内;否则,这个时间将会跨越凌晨0点。

注:
这里使用与regId相关联的alias和topic推送消息,也会受到限制。

如果时间设置为0:00-0:00,就是暂停push推送服务,也可以直接调用pausePush()方法,其本质相同

如果时间设置为0:00-23:59,就是恢复push推送服务,即全天接收push推送消息,也可以直接调用resumePush()方法,其本质相同

表 12. setAcceptTime函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
startHour 接收时段开始时间的小时
startMin 接收时段开始时间的分钟
endHour 接收时段结束时间的小时
endMin 接收时段结束时间的分钟
category 扩展参数,暂时没有用途,直接填null

 

3.4.10. public static void pausePush(Context context, String category)

暂停接收MiPush服务推送的消息,app在恢复MiPush推送服务之前,不接收任何推送消息

注: 这里使用与RegId相关联的alias和topic推送消息,也是被暂停的

表 13. pausePush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
category 扩展参数,暂时没有用途,直接填null

 

3.4.11. public static void resumePush(Context context, String category)

恢复接收MiPush服务推送的消息

注: 这里使用与RegId相关联的alias和topic推送消息,也是被恢复的;这时服务器会把暂停时期的推送消息重新推送过来

表 14. resumePush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
category 扩展参数,暂时没有用途,直接填null

 

3.4.12. public static List<String> getAllAlias(final Context context)

获取客户端所有设置的别名。

表 15. getAllAlias函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.13. public static List<String> getAllTopic(final Context context)

获取客户端所有订阅的主题。

表 16. getAllTopic函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.14. public static List<String> getAllUserAccount(final Context context)

获取客户端所有设置的帐号。

表 17. getAllUserAccount函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.15. public static void reportMessageClicked(Context context, String msgid)

上报点击的消息。

表 18. reportMessageClicked函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
msgid 调用server api推送消息后返回的消息ID。

 

3.4.16. public void onReceiveMessage(Context context, MiPushMessage message)

接收服务器推送的消息。

表 19. onReceiveMessage函数参数列表

参数列表 参数说明
message 服务器推送的消息封装在 MiPushMessage的对象中,可以从该对象中获取messageType、messageId、
content、alias、 topic、passThrough、isNotified、 notifyType、 description、
title、extra等信息。

  1. messageType表示消息的类型,分为三种:MESSAGE_TYPE_REG、MESSAGE_TYPE_ALIAS、MESSAGE_TYPE_TOPIC,这三个是MiPushMessage的静态变量。
  2. 如果服务器是给alias推送的消息,则alias不为null。
  3. 如果服务器是给topic推送的消息,则topic内容不为null。
  4. passThrough指示服务器端推送的消息类型。
    如果passThrough值为1,则是透传消息;如果passThrough值为0,则是通知栏消息。
  5. isNotified表示消息是否通过通知栏传给app的。如果为true,表示消息在通知栏出过通知;如果为false,表示消息是直接传给app的,没有弹出过通知。
  6. messageId是消息的id。
  7. content是消息的内容,对应发送消息时的 payload。
  8. notifyType是消息的提醒方式,如震动、响铃和闪光灯。
  9. description是消息描述。
  10. title是消息的标题。
  11. extra是一个map类型,包含一些附加信息,如自定义通知栏铃声的URI、通知栏的点击行为等等。

 

3.4.17. public void onCommandResult(Context context, MiPushCommandMessage message)

当客户端向服务器发送注册push、设置alias、取消注册alias、订阅topic、取消订阅topic等等命令后,从服务器返回结果。

表 20. onCommandResult函数参数列表

参数列表 参数说明
message 服务器返回的命令封装在 MiPushCommandMessage的对象中,可以从该对象中获取command、commandArguments、
resultCode、 reason等信息。

  1. command表示命令的类型。
    • 调用MiPushClient.registerPush(),返回MiPushClient.COMMAND_REGISTER
    • 调用MiPushClient.setAlias(),返回MiPushClient.COMMAND_SET_ALIAS
    • 调用MiPushClient.unsetAlias(),返回MiPushClient.COMMAND_UNSET_ALIAS
    • 调用MiPushClient.subscribe(),返回MiPushClient.COMMAND_SUBSCRIBE_TOPIC
    • 调用MiPushClient.unsubscribe(),返回MiPushClient.COMMAND_UNSUBSCIRBE_TOPIC
    • 调用MiPushClient.setAcceptTime(),返回MiPushClient.COMMAND_SET_ACCEPT_TIME
    • 调用MiPushClient.pausePush(),返回MiPushClient.COMMAND_SET_TARGETPT_TIME
    • 调用MiPushClient.resumePush(),返回MiPushClient.COMMAND_SET_ACCEPT_TIME
  2. commandArguments 表示命令的参数。例如:
    注册app就会返回app本次初始化所对应MiPush推送服务的唯一标识regId,alias就会返回alias的内容,订阅和取消订阅主题就会返回topic,setAcceptTime就会返回时间段。
  3. resultCode 表示调用命令的结果。如果成功,返回ErrorCode.Sussess即0;否则返回错误类型值。
  4. reason表示调用命令失败的原因。如果失败,则返回失败原因,否则返回为null。

 

3.4.18. public void checkManifest(Context context) throws IllegalManifestException

从3.1版本开始,去除了这个接口,改为 debuggable 为 true 时自动检测。

客户端在接入本SDK时,通过调用该API来检查AndroidManifest.xml是否正确声明了本SDK要求的所有组件和权限。当有组件和权限未定义,或者组件的属性声明错误时,该API抛出异常MiPushClient.IllegalManifestException。

3.4.18.1. 异常MiPushClient.IllegalManifestException

checkManifest(Context)抛出的异常类,继承自java.lang.Exception。

表 21. MiPushClient.IllegalManifestException的成员列表

成员列表 成员说明
PackageItemInfo getInfo() 获取导致异常的组件的信息。

  1. 参数:无。
  2. 返回值:如果是null,说明有组件或权限未定义;否则说明有组件的属性声明错误。通过判断返回值的类型是ServiceInfo还是ActivityInfo可以判断导致错误的是<service
    />还是<receiver />
String getMessage() 继承自Exception,获取异常的打印信息。

 

3.4.19. public static void clearNotification(Context context, int notifyId)

清除小米推送弹出的某一个notifyId通知。

表 22. clearNotification函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
notifyId 调用server api设置通知消息的notifyId。

 

3.4.20. public static void clearNotification(Context context)

清除小米推送弹出的所有通知。

表 23. clearNotification函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.21. public static void setLocalNotificationType(final Context context, int
notifyType)

客户端设置通知消息的提醒类型。

注:当服务端指定了消息的提醒类型,会优选考虑客户端设置的。

表 24. setLocalNotificationType函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context
notifyType 通知栏消息的提醒类型。

 

3.4.22. public static void clearLocalNotificationType(final Context context)

清除客户端设置的通知消息提醒类型。

表 25. clearLocalNotificationType函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.23. public static String getRegId(Context context)

获取客户端的RegId。

表 26. getRegId函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.24. public static void disablePush(Context context)

关闭MiPush推送服务,当用户希望不再使用MiPush推送服务的时候调用,调用成功后,app将不会接收到任何MiPush服务端的数据,直到下次调用enablePush()。

注:调用disablePush()成功后,服务器不会向APP发送任何消息,在非MIUI上,SDK会主动断开和服务端的长连接。需要注意的是:与unregisterPush()不同,disablePush后,设备的注册信息(regID)将会保留,只要再次enablePush后所有信息与之前保持一致。

表 27. disablePush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

3.4.25. public static void enablePush(Context context)

打开MiPush推送服务。

注:只有设备在调用disablePush()后,如果需要再次使用push服务才需要再次调用enablePush,否则不需要使用这一方法。

表 28. enablePush函数参数列表

参数列表 参数说明
context Android平台上app的上下文,建议传入当前app的application context

 

4. 专题

4.1.  定制通知栏通知的图标

目前通知类的消息, 通知的图标展示规则如下:

  • 如果app中同时存在名为mipush_notification和mipush_small_notification的drawable文件,则使用mipush_notification的drawable作为通知的大图标,mipush_small_notification的drawable作为通知的小图标。
  • 如果app中只存在其中一个drawable文件,则使用该drawable作为通知的图标。
  • 如果app中不存在这两个drawable文件,则使用app的icon作为通知的图标。在MIUI中,通知栏图标统一显示为app的icon,不可以定制。

4.2. 消息的处理

消息类型:分为透传消息和通知消息。

服务端发送消息,请参考服务端文档:/doc/?p=533

4.2.1. 透传消息的处理

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

客户端收到透传消息后,可以自定义一些操作。

4.2.2. 通知消息的处理

通知消息分为自定义通知消息和预定义通知消息。

如果服务端调用Message.Builder类的extra(String key, String
value)方法设置了Constants.EXTRA_PARAM_NOTIFY_EFFECT的值,则为预定义通知消息;否则为自定义通知消息(具体细节请参考服务端文档:/doc/?p=533)。

如果在小米推送服务开发者站推送消息,需要通过指定“点击后续动作”来指定通知消息类型。

通知消息到达客户端后会在通知栏弹出notification,这时候消息已经传到PushMessageReceiver继承类的onNotificationMessageArrived方法,但这时候消息还没有通过PushMessageReceiver继承类的的onNotificationMessageClicked方法传到客户端。当用户需要点击了自定义通知消息,消息会通过onNotificationMessageClicked方法传到客户端。

注:用户点击了预定义通知消息,消息不会通过onNotificationMessageClicked方法传到客户端。

客户端定义了不同的通知栏消息点击行为,分为下面四种。

  1. 自定义通知消息的处理服务端没有设置Constants.EXTRA_PARAM_NOTIFY_EFFECT的值表示是自定义通知消息。客户端收到自定义通知消息后,可以自定义一些操作。
    比如:通过启动一个Activity将消息传过去,这时需要给Intent添加FLAG_ACTIVITY_NEW_TASK。

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    透传消息和自定义通知消息的处理参考代码如下:

    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();
            }
        }
  2. 打开当前app对应的Launcher Activity服务端调用Message.Builder类的extra(String key, String
    value)方法,将key设置为Constants.EXTRA_PARAM_NOTIFY_EFFECT,value设置为Constants.NOTIFY_LAUNCHER_ACTIVITY。具体请参考服务端文档:/doc/?p=533。封装消息的MiPushMessage对象通过Intent传到客户端,客户端在相应的Activity中可以调用Intent的getSerializableExtra(PushMessageHelper.KEY_MESSAGE)方法得到MiPushMessage对象。
  3. 打开当前app内的任意一个Activity服务端调用Message.Builder类的extra(String key, String
    value)方法,将key设置为Constants.EXTRA_PARAM_NOTIFY_EFFECT,value设置为Constants.NOTIFY_ACTIVITY。具体请参考服务端文档:/doc/?p=533。封装消息的MiPushMessage对象通过Intent传到客户端,客户端在相应的Activity中可以调用Intent的getSerializableExtra(PushMessageHelper.KEY_MESSAGE)方法得到MiPushMessage对象。
  4. 打开网页服务端调用Message.Builder类的extra(String key, String
    value)方法,将key设置为Constants.EXTRA_PARAM_NOTIFY_EFFECT,value设置为Constants.NOTIFY_WEB。具体请参考服务端文档:/doc/?p=533

4.3. 自定义通知栏

服务端在发送消息时可以自定义通知栏的行为,详细内容请参考:/doc/?p=533

4.3.1. 自定义通知栏消息铃声

服务端发送消息时调用Message.Builder类的extra(String key, String
value)方法将key设置为Constants.EXTRA_PARAM_SOUND_URI,value设置为铃声的URI。

注:

  • 铃声只能使用当前app内的资源,URI格式满足 android.resource://your packagename/XXX/XXX。
  • 铃声文件放在Android app的raw目录下。

Demo:

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.3.2. 自定义通知栏样式

如果系统默认的通知栏样式不满足需求,开发者可以自定义通知栏样式。服务端推送消息通过指定layout文件和填充内容,自由定制展示样式。

注意,在MIUI中,通知展示由系统通道负责,需要MIUI升级后才支持自定义通知。

具体使用方法如下:

  1. layout文件中只能包含以下控件: FrameLayout, LinearLayout, RelativeLayout, Button,
    ImageButton, ImageView, ProgressBar, TextView;
  2. 调用Message.Builder类的extra(String key, String
    value)方法将以“layout_name”为key,value设置为客户端要展示的layout文件名;
  3. 以“layout_value”为key,指定layout中各控件展示的内容,其value为一个Json。其格式为{“text”:{“txt_res_name1”:”txt_value1”,
    “txt_res_name2”:”txt_value2”…}, “image”:{“img_res_name1”:”img_value1”,
    “img_res_name2”:”img_value2”…}, “time”:{“time_res_name”:”format_value”}}。

其中:txt_res_name为layout文件中的控件名字,txt_value为控件上需要展示的文本内容。
img_res_name为layout中需要展示图片资源的控件名字,img_value为程序中对应的资源名。
time_res_name为layout文件中的控件名字,format_value为控件上需要展示的时间format样式。默认 yy-MM-dd hh:mm。

Demo:

以下消息,将指定以custom_notify为通知栏样式,将其中的titleText设置为“我是标题”,descText设置为“我是描述”;将iconImage设置为icon对应的图片。

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("layout_name","custom_notify")
             .extra("layout_value", "{\"text\":{\"titleText\":\"标题\"},\"image\": {\"iconImage\": \"icon\"},
                                      \"time\": {\"timeText\": \"HH:mm\"}}")​
             .build();
     return message;
}

4.4.  Proguard 配置

如果使用了 proguard,需要在配置文件中加入:

#这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名
-keep class com.xiaomi.mipush.sdk.DemoMessageReceiver {*;}
#可以防止一个误报的 warning 导致无法成功编译,如果编译使用的 Android 版本是 23。
-dontwarn com.xiaomi.push.**