文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-06-06 05:25

关注

前言

在Android开发中,消息推送功能的使用非常常见。

推送消息截图

为了降低开发成本,使用第三方推送是现今较为流行的解决方案。

今天,我将手把手教大家如何在你的应用里集成小米推送

目录

目录

1. 官方Demo解析

首先,我们先对小米官方的推送Demo进行解析。

请先到官网下载官方Demo和SDK说明文档

1.1 Demo概况

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;

  //主要要继承Application
public 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;

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.MIPUSH_RECEIVE" />
//注意要初始化BaseActivity.java类
  <application
    android:name=".BaseActivity"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  //注册广播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=".Mipush_Broadcast"
    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>
  </application>
</manifest>

步骤6:根据需要设置一系列的推送设置,如用户别名、标签等等

此处是简单Demo,所以不作过多的设置 更多设置请回看上方官方Demo解析

运行结果

测试成功结果

好了,客户端的代码写好后,可以去小米官网测试一下消息推送了

步骤1:在小米官网的消息推送里选择你创建的应用,然后点击“推送工具”

点击推送工具

步骤2:设置推送消息的相关信息

可进行的配置非常全面,基本上能满足推送的需求

设置推送消息 

设置推送消息

推送的结果

消息到达客户端

测试结果
测试结果:收到的信息

点击通知栏消息后

4. Demo下载地址  demo

5. 关于对小米推送的思考(问题)

上述说的小米推送看似简单:初始化推送服务 + 相关推送设置。但是,好的代码不仅能在正常情况下工作,还应该充分考虑失败情况。那么,有什么样的失败情况需要我们考虑呢?

背景:在这个初始化推送服务的过程中,是需要联系小米推送的服务器来申请reg id(即推送token)。 冲突:初始化过程可能失败:网络问题(没网or网络信号弱)、服务器问题导致初始化失败。那么,当失败以后,该什么时候再次进行初始化呢? 解决方案:在初始化失败的情况下提供重试机制,直到初始化成功(可以通过检测是否已经拿到推送token来确定),问题解决的逻辑如下:

解决逻辑

总结

全面考虑到所有异常问题并恰当地进行处理才能真正体现程序猿的功力,希望大家做撸代码的时候不要只做代码的搬运工,纯粹写代码并不会让你成长,关键在于思考。

您可能感兴趣的文章:Android手机端小米推送Demo解析和实现方法Android中利用App实现消息推送机制的代码Android中使用WebSocket实现群聊和消息推送功能(不使用WebView)使用SignalR推送服务在Android的实现 SignalAAndroid中使用socket通信实现消息推送的方法详解Erlang实现的百度云推送Android服务端实例Android顶栏定时推送消息android push推送相关基本问答总结Android、iOS和Windows Phone中的推送技术详解Android小米推送简单使用方法


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯