Android消息推送:手把手教你集成小米推送
消息推送:手把手教你集成小米推送(附附demo)
前言
在Android开发中,消息推送功能的使用非常常见。
为了降低开发成本,使用第三方推送是现今较为流行的解决方案。
今天,我将手把手教大家如何在你的应用里集成小米推送
目录目录
1. 官方Demo解析
首先,我们先对小米官方的推送Demo进行解析。
请先到官网下载官方Demo和SDK说明文档
1.1 Demo概况
目录说明:
目录说明:
DemoApplication类类
继承自Application类,其作用主要是:设置App的ID & Key、注册推送服务
DemoMessageReceiver类类
继承自BroadcastReceiver,用于接收推送消息并对这些消息进行处理
MainActivity
实现界面按钮处理 & 设置本地推送方案
TimeIntervalDialog
设置推送的时间间段
接下来,我将对每个类进行详细分析
1.2 详细分析
详细分析
1.2.1 DemoApplication类类
继承自Application类,其作用主要是:
设置App的ID & Key
注册推送服务
接下来我们通过代码来看下这两个功能如何实现:
DemoApplication.Java
package com.xiaomi.mipushdemo;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.xiaomi.channel.commonutils.logger.LoggerInterface;
import com.xiaomi.mipush.sdk.Logger;
import com.xiaomi.mipush.sdk.MiPushClient;
import java.util.List;
public class DemoApplication extends Application {
// 使用自己APP的ID(官网注册的)
private static final String APP_ID = "1000270";
// 使用自己APP的KEY(官网注册的)
private static final String APP_KEY = "670100056270";
// 此TAG在adb logcat中检索自己所需要的信息, 只需在命令行终端输入 adb logcat | grep
// com.xiaomi.mipushdemo
public static final String TAG = "com.xiaomi.mipushdemo";
private static DemoHandler sHandler = null;
private static MainActivity sMainActivity = null;
//为了提高推送服务的注册率,官方Demo建议在Application的onCreate中初始化推送服务
//你也可以根据需要,在其他地方初始化推送服务
@Override
public void onCreate() {
super.onCreate();
//判断用户是否已经打开App,详细见下面方法定义
if (shouldInit()) {
//注册推送服务
//注册成功后会向DemoMessageReceiver发送广播
// 可以从DemoMessageReceiver的onCommandResult方法中MiPushCommandMessage对象参数中获取注册信息
MiPushClient.registerPush(this, APP_ID, APP_KEY);
//参数说明
//context:Android平台上app的上下文,建议传入当前app的application context
//appID:在开发者网站上注册时生成的,MiPush推送服务颁发给app的唯一认证标识
//appKey:在开发者网站上注册时生成的,与appID相对应,用于验证appID是否合法
}
//下面是与测试相关的日志设置
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);
if (sHandler == null) {
sHandler = new DemoHandler(getApplicationContext());
}
}
//通过判断手机里的所有进程是否有这个App的进程
//从而判断该App是否有打开
private boolean shouldInit() {
//通过ActivityManager我们可以获得系统里正在运行的activities
//包括进程(Process)等、应用程序/包、服务(Service)、任务(Task)信息。
ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
List processInfos = am.getRunningAppProcesses();
String mainProcessName = getPackageName();
//获取本App的唯一标识
int myPid = Process.myPid();
//利用一个增强for循环取出手机里的所有进程
for (RunningAppProcessInfo info : processInfos) {
//通过比较进程的唯一标识和包名判断进程里是否存在该App
if (info.pid == myPid && mainProcessName.equals(info.processName)) {
return true;
}
}
return false;
}
public static DemoHandler getHandler() {
return sHandler;
}
public static void setMainActivity(MainActivity activity) {
sMainActivity = activity;
}
//通过设置Handler来设置提示文案
public static class DemoHandler extends Handler {
private Context context;
public DemoHandler(Context context) {
this.context = context;
}
@Override
public void handleMessage(Message msg) {
String s = (String) msg.obj;
if (sMainActivity != null) {
sMainActivity.refreshLogInfo();
}
if (!TextUtils.isEmpty(s)) {
Toast.makeText(context, s, Toast.LENGTH_LONG).show();
}
}
}
}
总结:
步骤1:先判断应用App是否已开启 – 通过判断系统里的进程
通过静态方法
public static void registerPush(Context context, String appID, String appKey)
进行推送服务注册,详细参数如下:
为了提高注册率,最好在Application的onCreate中初始化推送服务
你也可以根据需要,在其他地方初始化推送服务
1.2.2 DemoMessageReceiver类类
继承自PushMessageReceiver(抽象类,继承自BroadcastReceiver),其作用主要是:
接收推送消息
对推送消息进行处理
DemoMessageReceiver.java
package com.xiaomi.mipushdemo;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import com.xiaomi.mipush.sdk.ErrorCode;
import com.xiaomi.mipush.sdk.MiPushClient;
import com.xiaomi.mipush.sdk.MiPushCommandMessage;
import com.xiaomi.mipush.sdk.MiPushMessage;
import com.xiaomi.mipush.sdk.PushMessageReceiver;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* 1、PushMessageReceiver 是个抽象类,该类继承了 BroadcastReceiver。
* 2、需要将自定义的 DemoMessageReceiver 注册在 AndroidManifest.xml
public class DemoMessageReceiver extends PushMessageReceiver {
private String mRegId;
private String mTopic;
private String mAlias;
private String mAccount;
private String mStartTime;
private String mEndTime;
//透传消息到达客户端时调用
//作用:可通过参数message从而获得透传消息,具体请看官方SDK文档
@Override
public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
Log.v(DemoApplication.TAG,
"onReceivePassThroughMessage is called. " + message.toString());
String log = context.getString(R.string.recv_passthrough_message, message.getContent());
MainActivity.logList.add(0, getSimpleDate() + " " + log);
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
}
Message msg = Message.obtain();
msg.obj = log;
DemoApplication.getHandler().sendMessage(msg);
}
//通知消息到达客户端时调用
//注:应用在前台时不弹出通知的通知消息到达客户端时也会回调函数
//作用:通过参数message从而获得通知消息,具体请看官方SDK文档
@Override
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
Log.v(DemoApplication.TAG,
"onNotificationMessageArrived is called. " + message.toString());
String log = context.getString(R.string.arrive_notification_message, message.getContent());
MainActivity.logList.add(0, getSimpleDate() + " " + log);
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
}
Message msg = Message.obtain();
msg.obj = log;
DemoApplication.getHandler().sendMessage(msg);
}
//用户手动点击通知栏消息时调用
//注:应用在前台时不弹出通知的通知消息到达客户端时也会回调函数
//作用:1. 通过参数message从而获得通知消息,具体请看官方SDK文档
//2. 设置用户点击消息后打开应用 or 网页 or 其他页面
@Override
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
Log.v(DemoApplication.TAG,
"onNotificationMessageClicked is called. " + message.toString());
String log = context.getString(R.string.click_notification_message, message.getContent());
MainActivity.logList.add(0, getSimpleDate() + " " + log);
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
}
Message msg = Message.obtain();
if (message.isNotified()) {
msg.obj = log;
}
DemoApplication.getHandler().sendMessage(msg);
}
//用来接收客户端向服务器发送命令后的响应结果。
@Override
public void onCommandResult(Context context, MiPushCommandMessage message) {
Log.v(DemoApplication.TAG,
"onCommandResult is called. " + message.toString());
String command = message.getCommand();
List 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);
String log;
if (MiPushClient.COMMAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mRegId = cmdArg1;
log = context.getString(R.string.register_success);
} else {
log = context.getString(R.string.register_fail);
}
} else if (MiPushClient.COMMAND_SET_ALIAS.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mAlias = cmdArg1;
log = context.getString(R.string.set_alias_success, mAlias);
} else {
log = context.getString(R.string.set_alias_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_UNSET_ALIAS.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mAlias = cmdArg1;
log = context.getString(R.string.unset_alias_success, mAlias);
} else {
log = context.getString(R.string.unset_alias_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_SET_ACCOUNT.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mAccount = cmdArg1;
log = context.getString(R.string.set_account_success, mAccount);
} else {
log = context.getString(R.string.set_account_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_UNSET_ACCOUNT.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mAccount = cmdArg1;
log = context.getString(R.string.unset_account_success, mAccount);
} else {
log = context.getString(R.string.unset_account_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_SUBSCRIBE_TOPIC.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mTopic = cmdArg1;
log = context.getString(R.string.subscribe_topic_success, mTopic);
} else {
log = context.getString(R.string.subscribe_topic_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_UNSUBSCRIBE_TOPIC.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mTopic = cmdArg1;
log = context.getString(R.string.unsubscribe_topic_success, mTopic);
} else {
log = context.getString(R.string.unsubscribe_topic_fail, message.getReason());
}
} else if (MiPushClient.COMMAND_SET_ACCEPT_TIME.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mStartTime = cmdArg1;
mEndTime = cmdArg2;
log = context.getString(R.string.set_accept_time_success, mStartTime, mEndTime);
} else {
log = context.getString(R.string.set_accept_time_fail, message.getReason());
}
} else {
log = message.getReason();
}
MainActivity.logList.add(0, getSimpleDate() + " " + log);
Message msg = Message.obtain();
msg.obj = log;
DemoApplication.getHandler().sendMessage(msg);
}
//用于接收客户端向服务器发送注册命令后的响应结果。
@Override
public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
Log.v(DemoApplication.TAG,
"onReceiveRegisterResult is called. " + message.toString());
String command = message.getCommand();
List arguments = message.getCommandArguments();
String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);
String log;
if (MiPushClient.COMMAND_REGISTER.equals(command)) {
if (message.getResultCode() == ErrorCode.SUCCESS) {
mRegId = cmdArg1;
//打印日志:注册成功
log = context.getString(R.string.register_success);
} else {
//打印日志:注册失败
log = context.getString(R.string.register_fail);
}
} else {
log = message.getReason();
}
Message msg = Message.obtain();
msg.obj = log;
DemoApplication.getHandler().sendMessage(msg);
}
@SuppressLint("SimpleDateFormat")
private static String getSimpleDate() {
return new SimpleDateFormat("MM-dd hh:mm:ss").format(new Date());
}
}
总结总结
根据需要复写PushMessageReceiver里对消息的相关处理方法,以下是相关方法的详情:
关于onCommandResult(Context context,MiPushCommandMessage message)
a. 作用:当客户端向服务器发送注册push、设置alias、取消注册alias、订阅topic、取消订阅topic等等命令后,从服务器返回结果。
b. 参数说明:
1.2.3 MainActivity
用于给用户设置标识,如别名、标签、账号等等
MainActivity.java
public class MainActivity extends Activity {
public static List logList = new CopyOnWriteArrayList();
private TextView mLogView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DemoApplication.setMainActivity(this);
mLogView = (TextView) findViewById(R.id.log);
// 设置别名
findViewById(R.id.set_alias).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.set_alias)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String alias = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.setAlias(MainActivity.this, alias, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 撤销别名
findViewById(R.id.unset_alias).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.unset_alias)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String alias = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.unsetAlias(MainActivity.this, alias, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 设置帐号
findViewById(R.id.set_account).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.set_account)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String account = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.setUserAccount(MainActivity.this, account, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 撤销帐号
findViewById(R.id.unset_account).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.unset_account)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String account = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.unsetUserAccount(MainActivity.this, account, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 设置标签
findViewById(R.id.subscribe_topic).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.subscribe_topic)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String topic = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.subscribe(MainActivity.this, topic, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 撤销标签
findViewById(R.id.unsubscribe_topic).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.unsubscribe_topic)
.setView(editText)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String topic = editText.getText().toString();
//调用静态方法进行设置 MiPushClient.unsubscribe(MainActivity.this, topic, null);
}
})
.setNegativeButton(R.string.cancel, null)
.show();
}
});
// 设置接收消息时间
findViewById(R.id.set_accept_time).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new TimeIntervalDialog(MainActivity.this, new TimeIntervalInterface() {
@Override
public void apply(int startHour, int startMin, int endHour,
int endMin) {
//调用静态方法进行设置
MiPushClient.setAcceptTime(MainActivity.this, startHour, startMin, endHour, endMin, null);
}
@Override
public void cancel() {
//ignore
}
})
.show();
}
});
// 暂停推送
findViewById(R.id.pause_push).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MiPushClient.pausePush(MainActivity.this, null);
}
});
findViewById(R.id.resume_push).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//调用静态方法进行设置
MiPushClient.resumePush(MainActivity.this, null);
}
});
}
@Override
protected void onResume() {
super.onResume();
refreshLogInfo();
}
@Override
protected void onDestroy() {
super.onDestroy();
DemoApplication.setMainActivity(null);
}
public void refreshLogInfo() {