Android消息推送:手把手教你集成小米推送(附demo)

时间:2021-05-20

前言

在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<RunningAppProcessInfo> 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.xmlpublic 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<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); 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<String> 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<String> logList = new CopyOnWriteArrayList<String>(); 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() { String AllLog = ""; for (String log : logList) { AllLog = AllLog + log + "\n\n"; } mLogView.setText(AllLog); }}

总结:

根据需求对不同用户设置不同的推送标识,如别名、标签等等。

a. 别名(Alias)

1、开发者可以为指定用户设置别名,然后给这个别名推送消息,

效果等同于给RegId推送消息,Alias是除Regid(自动生成的)和UserAccount之外的第三个用户标识

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

//设置别名MiPushClient.setAlias(Context context, String alias, String category);//撤销别名MiPushClient.unsetAlias(Context context, String alias, String category);//参数说明//context:Android平台上app的上下文,建议传入当前app的application context//alias:为指定用户设置别名 / 为指定用户取消别名//category:扩展参数,暂时没有用途,直接填null//获取该客户端所有的别名public static List<String> getAllAlias(final Context context)

b. 用户账号(UserAccoun)

  • 开发者可以为指定用户设置userAccount
  • 开发者可以取消指定用户的某个userAccount,服务器就不会给这个userAccount推送消息了
//设置MiPushClient.setUserAccount(final Context context, final String userAccount, Stringcategory)//撤销MiPushClient.unsetUserAccount(final Context context, final String userAccount, Stringcategory)//参数说明//context:Android平台上app的上下文,建议传入当前app的application context//userAccount:为指定用户设置userAccount / 为指定用户取消userAccount//category:扩展参数,暂时没有用途,直接填null//获取该客户端所有设置的账号public static List<String> getAllUserAccount(final Context context)

c. 标签(Topic)

  • 开发者可以结合自己的业务特征,给用户打上不同的标签。
  • 消息推送时,开发者可以结合每条消息的内容和目标用户,为每条消息选择对应的标签,为开发者可以根据订阅的主题实现分组群发,从而进行消息的精准推送
//设置标签MiPushClient.subscribe(Context context, String topic, String category);//撤销标签MiPushClient.unsubscribe(Context context, String topic, String category);//参数说明//context:Android平台上app的上下文,建议传入当前app的application context//topic:为指定用户设置设置订阅的主题 / 为指定用户取消订阅的主题//category:扩展参数,暂时没有用途,直接填null//获取该客户端所有的标签public static List<String> getAllTopic(final Context context);

TimeIntervalDialog

作用:用于设置推送的时间-开始时间+暂停时间

package com.xiaomi.mipushdemo;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TimePicker;import android.widget.TimePicker.OnTimeChangedListener;//继承OnTimeChangedListener接口public class TimeIntervalDialog extends Dialog implements OnTimeChangedListener { private TimeIntervalInterface mTimeIntervalInterface; private Context mContext; private TimePicker mStartTimePicker, mEndTimePicker; private int mStartHour, mStartMinute, mEndHour, mEndMinute; private Button.OnClickListener clickListener = new Button.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.apply: dismiss(); //设置时间参数 mTimeIntervalInterface.apply(mStartHour, mStartMinute, mEndHour, mEndMinute); break; case R.id.cancel: dismiss(); mTimeIntervalInterface.cancel(); break; default: break; } } }; public TimeIntervalDialog(Context context, TimeIntervalInterface timeIntervalInterface, int startHour, int startMinute, int endHour, int endMinute) { super(context); mContext = context; this.mTimeIntervalInterface = timeIntervalInterface; this.mStartHour = startHour; this.mStartMinute = startMinute; this.mEndHour = endHour; this.mEndMinute = endMinute; } public TimeIntervalDialog(Context context, TimeIntervalInterface timeIntervalInterface) { this(context, timeIntervalInterface, 0, 0, 23, 59); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.set_time_dialog); setCancelable(true); setTitle(mContext.getString(R.string.set_accept_time)); mStartTimePicker = (TimePicker) findViewById(R.id.startTimePicker); mStartTimePicker.setIs24HourView(true); mStartTimePicker.setCurrentHour(mStartHour); mStartTimePicker.setCurrentMinute(mStartMinute); mStartTimePicker.setOnTimeChangedListener(this); mEndTimePicker = (TimePicker) findViewById(R.id.endTimePicker); mEndTimePicker.setIs24HourView(true); mEndTimePicker.setCurrentHour(mEndHour); mEndTimePicker.setCurrentMinute(mEndMinute); mEndTimePicker.setOnTimeChangedListener(this); Button applyBtn = (Button) findViewById(R.id.apply); applyBtn.setOnClickListener(clickListener); Button cancelBtn = (Button) findViewById(R.id.cancel); cancelBtn.setOnClickListener(clickListener); } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { if (view == mStartTimePicker) { mStartHour = hourOfDay; mStartMinute = minute; } else if (view == mEndTimePicker) { mEndHour = hourOfDay; mEndMinute = minute; } } interface TimeIntervalInterface { void apply(int startHour, int startMin, int endHour, int endMin); void cancel(); }}

总结

  • 使用一个继承了Dialog类的TimeIntervalDialog类进行推送时间的配置
  • 可进行的配置:设置推送时间(开始 & 结束)、暂停推送时间、恢复推送时间
//设置推送时间(开始 & 结束)MiPushClient.setAcceptTime(Context context, int startHour, int startMin, int endHour,int endMin, String category)//设置暂停推送时间、恢复推送时间pausePush(Context context, String category)`和`resumePush(Context context, String category)//参数说明//context:Android平台上app的上下文,建议传入当前app的application context//startHour:接收时段开始时间的小时//startMin :接收时段开始时间的分钟//endHour:接收时段结束时间的小时//endMin:接收时段结束时间的分钟//category:扩展参数,暂时没有用途,直接填null

AndroidManifest文件的配置

//小米推送支持最低的Android版本是2.2<uses-sdk android:minSdkVersion="8"/>//设置一系列权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <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" />//这里com.xiaomi.mipushdemo改成自身app的包名 <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" />//注册广播BroadcastReceiver & Service//都是静态注册,因为要长期处在后台运行//注:共是3个广播接收器和4个服务,其中包括继承了PushMessageReceiver的DemoMessageReceiver //4个后台服务 <service android:enabled="true" android:process=":pushservice" android:name="com.xiaomi.push.service.XMPushService"/> //此service必须在3.0.1版本以后(包括3.0.1版本)加入 <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必须在2.2.5版本以后(包括2.2.5版本)加入 <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" /> //3个广播 <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>//继承了PushMessageReceiver的DemoMessageReceiver的广播注册 <receiver android:name="com.xiaomi.mipushdemo.DemoMessageReceiver" android:exported="true"> <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>

2. 集成小米推送步骤汇总

  • 步骤1:在小米推送平台进行相关注册开发者账号,并进行应用的注册:应用包名,AppID和AppKey
  • 步骤2:将小米推送的SDK包加入库
  • 步骤3:在应用内初始化小米推送服务
  • 步骤4:继承PushMessageReceiver,并复写相关推送消息的方法
  • 步骤5:在AndroidManifest文件里面配置好权限、注册Service和BroadcastReceiver
  • 在Android6.0里面的权限需要动态获取
  • 步骤6:根据需要设置一系列的推送设置,如用户别名、标签等等

接下来,我们来按照上面的步骤,一步步来实现一个简易的小米推送Demo

3. 实例解析

步骤1:在小米推送平台进行相关注册开发者账号,并进行应用的注册:应用包名,AppID和AppKey

注意,填入的包名要跟你的应用App的包名是一致的


步骤2:将小米推送的SDK包加入到你应用的库里

点击此处进行下载

步骤3:在应用内初始化小米推送服务

为了提高推送服务的注册率,我选择在Application的onCreate中初始化推送服务 *BaseActivity.java*

package scut.carson_ho.demo_mipush;import android.app.ActivityManager;import android.app.Application;import android.content.Context;import android.os.Process;import com.xiaomi.mipush.sdk.MiPushClient;import java.util.List;/** * Created by Carson_Ho on 16/10/26. */ //主要要继承Applicationpublic class BaseActivity extends Application { // 使用自己APP的ID(官网注册的) private static final String APP_ID = "2882303761517520369"; // 使用自己APP的Key(官网注册的) private static final String APP_KEY = "5401752085369"; //为了提高推送服务的注册率,我建议在Application的onCreate中初始化推送服务 //你也可以根据需要,在其他地方初始化推送服务 @Override public void onCreate() { super.onCreate(); if (shouldInit()) { //注册推送服务 //注册成功后会向DemoMessageReceiver发送广播 // 可以从DemoMessageReceiver的onCommandResult方法中MiPushCommandMessage对象参数中获取注册信息 MiPushClient.registerPush(this, APP_ID, APP_KEY); } } //通过判断手机里的所有进程是否有这个App的进程 //从而判断该App是否有打开 private boolean shouldInit() { //通过ActivityManager我们可以获得系统里正在运行的activities //包括进程(Process)等、应用程序/包、服务(Service)、任务(Task)信息。 ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)); List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses(); String mainProcessName = getPackageName(); //获取本App的唯一标识 int myPid = Process.myPid(); //利用一个增强for循环取出手机里的所有进程 for (ActivityManager.RunningAppProcessInfo info : processInfos) { //通过比较进程的唯一标识和包名判断进程里是否存在该App if (info.pid == myPid && mainProcessName.equals(info.processName)) { return true; } } return false; }}

注意要在Android.manifest.xml里的application里加入

android:name=".BaseActivity"

这样在应用初始化时是第一个加载BaseActivity.java类文件的

如下图:

步骤4:设置子类继承PushMessageReceiver,并复写相关推送消息的方法

Mipush_Broadcast.java

package scut.carson_ho.demo_mipush;import android.content.Context;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;/** * Created by Carson_Ho on 16/10/26. */public class Mipush_Broadcast extends PushMessageReceiver { //透传消息到达客户端时调用 //作用:可通过参数message从而获得透传消息,具体请看官方SDK文档 @Override public void onReceivePassThroughMessage(Context context, MiPushMessage message) { //打印消息方便测试 System.out.println("透传消息到达了"); System.out.println("透传消息是"+message.toString()); }//通知消息到达客户端时调用 //注:应用在前台时不弹出通知的通知消息到达客户端时也会回调函数 //作用:通过参数message从而获得通知消息,具体请看官方SDK文档 @Override public void onNotificationMessageArrived(Context context, MiPushMessage message) { //打印消息方便测试 System.out.println("通知消息到达了"); System.out.println("通知消息是"+message.toString()); } //用户手动点击通知栏消息时调用 //注:应用在前台时不弹出通知的通知消息到达客户端时也会回调函数 //作用:1. 通过参数message从而获得通知消息,具体请看官方SDK文档 //2. 设置用户点击消息后打开应用 or 网页 or 其他页面 @Override public void onNotificationMessageClicked(Context context, MiPushMessage message) { //打印消息方便测试 System.out.println("用户点击了通知消息"); System.out.println("通知消息是" + message.toString()); System.out.println("点击后,会进入应用" ); } //用来接收客户端向服务器发送命令后的响应结果。 @Override public void onCommandResult(Context context, MiPushCommandMessage message) { String command = message.getCommand(); System.out.println(command ); if (MiPushClient.COMMAND_REGISTER.equals(command)) { if (message.getResultCode() == ErrorCode.SUCCESS) { //打印信息便于测试注册成功与否 System.out.println("注册成功"); } else { System.out.println("注册失败"); } } } //用于接收客户端向服务器发送注册命令后的响应结果。 @Override public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) { String command = message.getCommand(); System.out.println(command ); if (MiPushClient.COMMAND_REGISTER.equals(command)) { if (message.getResultCode() == ErrorCode.SUCCESS) { //打印日志:注册成功 System.out.println("注册成功"); } else { //打印日志:注册失败 System.out.println("注册失败"); } } else { System.out.println("其他情况"+message.getReason()); } }}

步骤5:在AndroidManifest文件里面配置好权限、注册Service和BroadcastReceiver

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="scut.carson_ho.demo_mipush"> //相关权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <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.MIPUSH_RECEIVE是自身app的包名 <permission android:name="scut.carson_ho.demo_mipush.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" /> //注意这里.permission.MIPUSH_RECEIVE是自身app的包名 <uses-permission android:name="scut.carson_ho.demo_mipush.permission.MI

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章