MixPush

Project Url: taoweiji/MixPush
Introduction: Android 融合推送 MixPush 集成多家推送平台,共享系统级推送,杀死 APP 也能收到推送
More: Author   ReportBugs   
Tags:

Download

基于 统一推送联盟 的思想,快速集成了六个厂商的推送平台,共享系统的厂商推送通道,避免 APP 需要长期在后台运行,杀死 APP 也能收到推送,大大提高推送到达率。接入有一定的开发成本,需要前后端一起参与才可以完成,如果遇到什么问题可以发 Issue 提问解答。

  1. 开发者只需要少量代码即可集成 小米、华为、魅族、OPPO、VIVO,苹果的厂商推送;

  2. 根据手机厂商推送的支持情况智能选择不同的推送;

  3. 共享系统推送通道,杀死 APP 也能收到推送,推送到达率高达 90%以上;

  4. 提供服务端的 Java 代码,方便开发者快速实现服务端;

  5. SDK 已经为开发者考虑好各种问题,避免碰壁,从 2 人超一周开发时间压缩到只需要半天时间即可。

本 SDK 不支持商业推送平台,因为第三方商业推送 SDK 的免费版本基本都存在黑产行为,偷偷给用户推送通知栏广告,诱导用户下载其他 APP 或打开其他 APP,非法获利。

这一点我们已经亲身经历过,我们集成的国内排名前三的推送平台就对我们公司的 APP 下了毒手,618 的时候偷偷给用户发伪造成拼多多、淘宝、京东、微博的通知栏消息,诱导用户打开电商 APP 领红包,我们通过源码分析查证了,并且他们的商务已经向我公司道歉,所以切莫使用免费的商业推送 SDK。

厂商推送平台介绍

在以前没有厂商推送的情况下,各家公司或推送平台为了让 APP 可以在后台收到推送,会通过各种方式让 APP 保持后台运行,甚至还会出现APP 之间相互唤醒。近年来,手机系统的管控越来越严格,不再允许后台运行也不允许 APP 相互唤醒。如果无法收到推送,会导致很多 APP 无法正常工作,比如微信消息,淘宝订单等。为了解决 APP 收到推送的问题,国内的手机厂商纷纷推出了自己的厂商推送平台,APP 无需在后台运行即可收到推送,可以大大节省手机的电量问题。那么另外一个问题来了,这么多推送平台,每一个平台的接入方式都不一样,会导致接入成本大大增加,为了解决这个问题,MixPush 来了。

推送平台 透传 全局推送 别名/标签 支持说明
小米推送 支持 支持 支持 所有 Android 设备,小米设备支持系级别推送,其它设备支持普通推送
华为推送 支持 不支持 不支持 仅华为设备,部分 EMUI4.0 和 4.1,及 EMUI5.0 及之后的华为设备。
OPPO 推送 不支持 支持 支持 仅 OPPO 和一加手机,支持 ColorOS3.1 及以上的系统。
VIVO 推送 不支持 支持 支持 仅 VIVO 手机,部分 Android 9.0,及 9.0 以上手机
魅族推送 不支持 支持 支持 仅魅族手机,Flyme 系统全平台
APNs 不支持 不支持 不支持 仅苹果设备
小米推送 APNs 不支持 支持 支持 仅苹果设备,代替 APNs,可以有效降低服务器压力
建议
  1. 如果手机支持建厂商推送就使用厂商推送 SDK,否则使用小米推送。
  2. 由于华为推送不支持别名和标签,所以建议所有的手机都统一通过 regId 进行推送。
  3. 由于多数的推送 SDK 不支持透传,如果 APP 需要支持透传,建议统一使用小米推送作为透传方案,但是如果使用小米作为所有 Android 手机的透传功能,那么小米推送就不再支持全局推送。
  4. 由于华为推送和 APNs 不支持全局推送,如果要推送给所有用户,请查询最近 3 个月有打开 APP 的用户,进行分组推送。因为多数的有效期都是三个月,就算推送用户也收不到,如果把所有历史的用户都查询出来,推送压力将会加倍。
  5. 建议 iOS 也使用小米推送,可以有效降低服务器的推送压力,特别是在全局推送和分组推送的时候。

注册各大的推送平台的账号

这个步骤在这里就不详细展开说了,自行注册配置,除了小米推送外,其它推送都必须要公司主体才可以申请,请务必注意,避免浪费时间。

Android 客户端配置

修改项目的根目录 build.gradle

buildscript {
    repositories {
          ...
        mavenCentral()
        maven { url 'http://developer.huawei.com/repo/' }
    }
    dependencies {
        ...
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
}
allprojects {
    repositories {
        ...
        mavenCentral()
        jcenter()
        maven { url 'http://developer.huawei.com/repo/' }
    }
}

修改 app 目录的 build.gradle

小米、VIVO 和魅族需要在推送管理后台创建项目并且把对应的 APP_ID 和 APP_KEY 配置到文件中,OPPO 比较特殊,是配置 APP_KEY 和 APP_SECRET。

apply plugin: 'com.huawei.agconnect'
android {
    compileSdkVersion 31
    defaultConfig {
        ...
        manifestPlaceholders["VIVO_APP_ID"] = "<VIVO_APP_ID>"
        manifestPlaceholders["VIVO_APP_KEY"] = "<VIVO_APP_KEY>"
        manifestPlaceholders["MI_APP_ID"] = "<MI_APP_ID>"
        manifestPlaceholders["MI_APP_KEY"] = "<MI_APP_KEY>"
        manifestPlaceholders["OPPO_APP_KEY"] = "<OPPO_APP_KEY>"
        manifestPlaceholders["OPPO_APP_SECRET"] = "<OPPO_APP_SECRET>"
        manifestPlaceholders["MEIZU_APP_ID"] = "<MEIZU_APP_ID>"
        manifestPlaceholders["MEIZU_APP_KEY"] = "<MEIZU_APP_KEY>"
    }
}
dependencies {
    def mixpush_version = '2.4.0'
    implementation "io.github.mixpush:mixpush-core:$mixpush_version" // 核心包
    implementation "io.github.mixpush:mixpush-mi:$mixpush_version" // 小米推送
    implementation "io.github.mixpush:mixpush-meizu:$mixpush_version"  // 魅族推送
    implementation "io.github.mixpush:mixpush-huawei:$mixpush_version"  // 华为推送
    implementation "io.github.mixpush:mixpush-oppo:$mixpush_version"  // OPPO 推送
    implementation "io.github.mixpush:mixpush-vivo:$mixpush_version"  // VIVO 推送
}

华为推送

华为推送麻烦一些,需要做 3 步配置:

  1. 参考官方文档下载 “agconnect-services.json”并拷贝到 app 目录。
  2. 配置 SHA256 证书指纹,否则会提示 错误 6003 ,详细查看通用错误码
  3. 配置指纹证书,否则会提示 错误 907135702,详细查看通用错误码

华为图片配置

初始化

定义监听器

public class MyPushReceiver extends MixPushReceiver {
    @Override
    public void onRegisterSucceed(Context context, MixPushPlatform mixPushPlatform) {
        // 这里需要实现上传 regId 和推送平台信息到服务端保存,
        //也可以通过 MixPushClient.getInstance().getRegisterId 的方式实现
    }

    @Override
    public void onNotificationMessageClicked(Context context, MixPushMessage message) {
      // TODO 通知栏消息点击触发,实现打开具体页面,打开浏览器等。
    }
}

在 Application 初始化

// 开启日志
//MixPush.getInstance().setLogger(new PushLogger(){});
MixPush.getInstance().setPushReceiver(new MyPushReceiver());
// 默认初始化 5 个推送平台(小米推送、华为推送、魅族推送、OPPO 推送、VIVO 推送),以小米推荐作为默认平台
MixPush.getInstance().register(this);

获取 regId,建议在首页的 onCreate 调用,并上报 regId 给服务端

MixPushClient.getInstance().getRegisterId(this, new GetRegisterIdCallback() {
    public void callback(MixPushPlatform platform) {
        if (platform != null) {
            Log.e("GetRegisterIdCallback", platform.toString());
            // TODO 上报 regId 给服务端
        }
    }
});
  1. 务必在 onRegisterSucceed 或 getRegisterId 实现上传 RegId 到服务端。
  2. 请在 onNotificationMessageClicked 实现对通知栏的操作,比如打开浏览器、跳转某个页面。

混淆配置

# MixPush
-keep class com.mixpush.mi.MiPushProvider {*;}
-keep class com.mixpush.meizu.MeizuPushProvider {*;}
-keep class com.mixpush.huawei.HuaweiPushProvider {*;}
-keep class com.mixpush.oppo.OppoPushProvider {*;}
-keep class com.mixpush.vivo.VivoPushProvider {*;}

# 华为推送
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}

# 小米推送
-keep class com.xiaomi.**{*;}

# OPPO
-keep public class * extends android.app.Service
-keep class com.heytap.msp.** { *;}

# VIVO
-dontwarn com.vivo.push.** 
-keep class com.vivo.push.**{*; } 
-keep class com.vivo.vms.**{*; }

# 魅族
-keep class com.meizu.**{*;}

Java 服务端配置

  1. 支持全局推送、单条推送、分组推送。
  2. 建议客户端每次打开 APP 的时候,都请求 api 登记 RegId 更新,服务端并记录时间,无论 regId 是否有修改。
  3. 由于华为和苹果推送不支持全局推送,需要从数据库查询全部的 RegId 进行分组推送。
  4. 超过 3 个月没有打开 APP,建议不要推送,避免浪费资源,特别是全局推送的时候。
添加依赖
<dependencies>
    <dependency>
        <groupId>io.github.mixpush</groupId>
        <artifactId>mixpush-sender</artifactId>
        <version>2.3.9</version>
    </dependency>
</dependencies>
示例
class MixPushServerExample {
    public static void main(String[] args) {
        MixPushSender sender = new MixPushSender.Builder()
                .packageName("<packageName>")
                .mi("<appSecretKey>",false)
                .meizu("<appId>", "<appSecretKey>")
                .huawei("<appId>", "<appSecretKey>")
                .oppo("<appKey>", "<masterSecret>")
                .vivo("<appId>", "<appKey>", "<appSecretKey>")
                .miAPNs("<appSecretKey>")
                .test(true)
                .build();
        MixPushMessageConfig activitiesMessageConfig = new MixPushMessageConfig.Builder()
                // OPPO 必须在“通道配置 → 新建通道”模块中登记通道,再在发送消息时选择
                .oppoPushChannelId("activities")
                .build();
        MixPushMessage message = new MixPushMessage.Builder()
                .title("这里是标题")
                .description("这里是副标题")
                .payload("{\"url\":\"http://github.com/taoweiji\"}")
                .config(activitiesMessageConfig)
                .build();
          MixPushTarget target = MixPushTarget.single("mi","xxxx");
        sender.sendNotificationMessage(message,target);
    }
}
MixPushMessageConfig.Builder
方法 说明
huaweiPushChannelId 非必填
vivoSystemMessage 必填,false:运营类消息,true:系统类消息
timeToLive 非必填,消息有效期,最长 72 小时,单位:毫秒
miPushChannelId 非必填,由于普通消息内日推送数量有限,如果是 IM、订单变化等消息可以向小米官方申请
oppoPushChannelId 必填,必须在“通道配置 → 新建通道”模块中登记通道,OPPO 渠道适配
MixPushMessage.Builder
方法 说明
title 通知栏标题,如果 passThrough 是 false,必填
description 通知栏副标题,如果 passThrough 是 false,必填
payload 必须是 json 格式
passThrough false:通知栏推送,true:透传消息
messageId 非必填,会默认生成一个,用于追踪 Result
config 必填,配置 ChannelId 等信息

问题汇总

小米推送
  1. MIUI 日联网设备数≥10000 时,当日可推送普通消息数量为 MIUI 日联网设备数*5。
  2. 普通消息`每日推送数量有限,如果需要开发即时聊天/订单变化,请申请通知消息权限,发送数量不受限制。
  3. 使用使用 miAPNS,并开启了沙箱,会导致 Android 手机无法收到推送(相当于只能在正式环境测试)
OPPO 推送
  1. 目前单日推送数量为:累计注册用户数*2。
  2. 目前私信处于公测阶段,需要申请才能开启私信通道,私信申请请参考OPPO PUSH 通道升级公测邀请
  3. 必须在“通道配置 → 新建通道”模块中登记通道,再在发送消息时选择。
VIVO 推送
  1. 目前 vivo 手机接收的消息为 7:00-23:00,服务器允许推送时间为 7:00-22:00,系统消息不受此时间限制。
  2. 用户单应用每日运营消息接收条数上限 5 条,系统消息无限制。
  3. 正式消息分为运营消息和系统消息,两者每日限制发送量均根据 SDK 订阅数推算,SDK 订阅数小于 10000,按 10000 计数;大于 10000,则等于 SDK 订阅数。
  4. 运营推送 vivoSystemMessage 必须设置为 false,否则会被禁用推送功能。
魅族推送
  1. 无需区分运营推送和系统消息。
华为推送
  1. 不支持全局推送,需要从数据库查询所有的 regId 进行推送,建议不要查询超过 3 个月没有打开 APP 的 regId,降低推送压力。
小米推送 APNs 服务
  1. 不支持透传功能。
  2. 推荐用来代替 APNs,可以有效降低服务器推送压力。
APNs
  1. 不支持全局推送,需要从数据库查询所有的 regId 进行推送,建议不要查询超过 6 个月没有打开 APP 的 regId,降低推送压力。
  2. 推送的证书需要区分正式和测试,并且有效期是一年,需要及时更换。
需要区分运营推送和系统推送(通知栏渠道匹配)

由于运营推送每日推送的数量是有限,如果需要用于开发 IM 和订单变化的推送,推送的数量是不够的,为了解决这个问题,各家推送都有自己的规范,推出了“系统消息”推送。必须严格准守,运营推送严禁走系统消息通道,否则会被禁用。

透传消息
  1. 默认不开启透传功能,需要手动开启,但是如果开启小米推送作为默认透传,将无法使用小米进行全局推送,因为会导致非小米手机推送 2 条推送,必须走分组推送。
  2. iOS 不支持透传功能。

测试报告

mi 代表使用小米推送,huawei 代表是使用华为推送。ok 代表通过、- 代表没有测试设备、error 代表异常。 | Android 系统 | 小米手机 | 华为手机 | 魅族手机 | OPPO 手机 | VIVO 手机 | 一加手机 | | ------ | -------- | -------- | -------- | -------- | -------- | -------- | | 4.4 | mi, ok | mi, ok | - | mi, ok | mi, ok | - | | 5.x | mi, ok | mi, ok | meizu, ok | mi, ok | mi, ok | mi, ok | | 6.x | mi, ok | mi, ok | meizu, ok | mi, ok | mi, ok | - | | 7.x | mi, ok | huawei, ok | meizu, ok | oppo, ok | mi, ok | mi, ok | | 8.x | mi, ok | huawei, ok | meizu, ok | oppo, ok | mi, ok | mi, ok | | 9.x | mi, ok | huawei, ok | meizu, ok | oppo, ok | vivo, ok | oppo, ok | | 10.x | mi, ok | huawei, ok | meizu, ok | oppo, ok | vivo, ok | oppo, ok |

TODO

  • 支持 Google FCM
  • Flutter 插件,支持 Android 和 iOS。
  • 实现消息回执功能
  • 平滑推送
  • 定时推送
  • 通知栏重要等级设置
  • APNS 官方通道(iOS 建议使用小米推送)
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools