前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 手记 | Android MobPush 接入小结

Android 手记 | Android MobPush 接入小结

原创
作者头像
贺biubiu
修改2021-09-07 10:50:25
2K0
修改2021-09-07 10:50:25
举报
文章被收录于专栏:HLQ_StruggleHLQ_Struggle


PS:这不仅仅是一篇简单 MobPush 接入总结,同时也会掺杂个人理解以及不成熟的想法。接入的本身很 easy,总要透过现象看本质,去深入了解其他的内容。文章涉及到三方统计数据截图,均已在文末提供链接地址,如有异议,请联系我删除~

手记开始,记录项目点滴,一起加油~

上来还是简单叨叨几句,不吐不快。

推送的目的是什么?在地铁上我想了很多:

  • 拉活,通过产品各种特性(活动)吸引用户点击使用,进一步验证产品思路、方向;
  • 促进用户粘性,好比今天收到通知,鸡老大直播 ing,马不停蹄的点击进去开始膜拜;
  • 重大事件通知与防范,科技的力量,在某些方面,总会统一战线,无时无刻提示风险以及加强警惕;
  • 。。。

其实推送最终的目的,个人更大的感觉还是将用户进一步留存,无论采取任何方式方法。

而相比 iOS 的推送,则 Android 要痛苦的很多。Android 的开放性使其自身逐步发展壮大,同时开放性也衍生了国内各种厂商的定制化。各种 系统 层出不穷,百花齐放的场景也给 Android 开发小伙伴带来了很多兼容性的问题。iOS 只需要发送苹果服务器,然后进行后续处理 个人理解,而 Android?这里特意搜索了下国内几大厂商的历史图:

image.png
image.png

瞧瞧,目前五大厂商赫然在目!!!我们再看看截止 2021 年国内手机出货量:

image.png
image.png

除了魅族暂时未上榜单,其余依旧坚挺。这里排除华为鸿蒙,这个不在这篇文章考虑范围内。

那么对于我们原生 Android 开发而言,如何处理,能达到最好的推送效果?我想那可能是依次对主流厂商进行兼容适配,但是同时也带来了成倍的接入工作。

较好的一点是,有困难,便有专业解决困难提供商。对于小公司而言,一键接入成型并且经过市场检验的三方推送服务便是上上策。而国内众多推送服务商,我们又该选择哪儿个?接着往下看~

Push 厂商对比


我一直都是小公司,小公司里面对于方案的选择,大部分是 直系领导 直接拍板决定,少部分是看 主程 更倾向于哪儿家就用哪儿家。

下面从我个人关注的几个维度进行极光、友盟、Mob、个推这四个厂商简单的对比吧。  (❌ 代表不支持,✅ 代表支持。特殊情况单独注明) (截止到 2021 年 8 月 10 日):

极光

友盟

Mob

个推

支持消息格式

通知栏通知、自定义消息(透传)、富媒体、本地通知

通知栏通知、自定义消息(透传)、本地通知

通知栏通知、自定义消息(透传)、本地通知

通知消息、自定义消息(透传)、分组对比

离线厂商通道支持

华为、小米、OPPO、vivo、魅族、华硕、FCM

华为、小米、OPPO、vivo、魅族

华为、小米、魅族、OPPO、vivo

小米、华为、OPPO、vivo、魅族、坚果、海信、索尼等

别名、标签支持

移除关联启动

需要开通 VIP

消息撤回

卸载统计

高级版支持

支持平台

Android、iOS、Windows Phone、QuickApp

Android、iOS、Flutter

Android、iOS、Flutter、Unity、JavaScript、Cocos2d-X

Android、iOS

分析对比,找瞎眼,如果不对,欢迎拍砖~

上图中只是个人简单对比,部分详细内容未考虑,当然也包括默认支持服务端 Web 调用,例如每个厂商对某个功能特性支持是否完整,这里就不一一诉说了。

方案很多,各位按照自身需求进行对应接入即可,下面开始个人习惯的 MobPush 集成啦~

MobPush 集成


从下面官网进入,准备开始接入:

登录成功后选择工作台:

image.png
image.png

0、Mob 后台创建 App 信息

创建应用:

  • 上传 Icon
  • 填写 App 名称
image.png
image.png

随后选择「立即接入」:

image.png
image.png

这里选择 MobPush:

image.png
image.png

添加应用包名以及选择接入厂商通道:

image.png
image.png

接入指南:

image.png
image.png

1、合规处理

由于目前针对用户个人信息/数据进一步管控加强,首要保证 App 符合合规。这里根据 Mob 官方进行部分整理:

  • 确保App有《隐私政策》,并且在用户首次启动App时就弹出《隐私政策》取得用户同意;
  • 务必告知用户选择 MobSDK 服务,并在《隐私政策》中增加参考条款;
  • 务必确保用户同意《隐私政策》之后,调用 MobSDK 提交隐私协议接口。

2、项目根目录 build 中添加 MobPush 依赖:

代码语言:txt
复制
buildscript {
    repositories { 
        // 配置 Mob Maven 库
        maven {
            url "https://mvn.mob.com/android"
        }
    }
    dependencies { 
        // 集成 MobPush
        classpath "com.mob.sdk:MobSDK:2018.0319.1724" 
    }
}

3、app 下 build 中新增 Mob 插件和扩展:

这里建议单独提出一个 Mob gradle,避免后续维护混乱.

代码语言:txt
复制
// 调用MobTech SDK
apply plugin: 'com.mob.sdk'

// 在 MobSDK 的扩展中注册 MobPush 的相关信息
MobSDK {
    appKey "appKey"
    appSecret "appSecret"
    MobPush {
        // 集成其他推送通道(可选)
        devInfo {
            // 华为推送配置信息
            HUAWEI {
                appId "华为的appid"
            }

            // 魅族推送配置信息
            MEIZU {
                appId "魅族的appid"
                appKey "魅族的appkey"
            }

            // 小米推送配置信息
            XIAOMI {
                appId "小米的appid"
                appKey "小米的appkey"
            }

            // FCM 推送通道配置
            FCM {
                // 设置默认推送通知显示图标
                iconRes "@mipmap/ic_launcher"
            }

            // OPPO 推送配置信息
            OPPO {
                appKey "OPPO的appKey"
                appSecret "OPPO的appSecret"
            }

            // VIVO 推送配置信息
            VIVO {
                appId "应用对应的vivo appID"
                appKey "应用对应的vivo appKey"
            }
        }
    }
}

随后在主 app 下 build 文件中进行引用:

代码语言:txt
复制
// 引入 Mob 配置
apply from: 'MobSettings.gradle'

4、gradle.properties 中配置隐私协议适配版本

代码语言:txt
复制
# 设定 MobSDK 为隐私协议适配版本
MobSDK.spEdition=FP

5、添加混淆代码

这块可以按照实际需求进行对应 CV 即可~

代码语言:txt
复制
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

# Mob 混淆代码
-keep class com.mob.**{*;}
-dontwarn com.mob.**

#厂商的混淆规则
-keep class android.os.SystemProperties
-dontwarn android.os.SystemProperties
-keep class com.huawei.**{*;}
-keep class com.meizu.**{*;}
-keep class com.xiaomi.**{*;}

-dontwarn com.huawei.**
-dontwarn com.meizu.**
-dontwarn com.xiaomi.**

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keep class com.huawei.hms.**{*;}
-keep class com.meizu.cloud.**{*;}
-keep class com.xiaomi.mipush.sdk.**{*;}
-keep class org.apache.thrift.**{*;}
-keep class com.google.** {*;}
-keep class com.coloros.** {*;}
-keep class com.mob.tools.* {*;}
-keep class com.mob.wrappers.* {*;}

-dontwarn com.mob.commons.**
-dontwarn com.mob.wrappers.**
-dontwarn com.huawei.hms.**
-dontwarn com.meizu.cloud.**
-dontwarn com.xiaomi.mipush.sdk.**
-dontwarn org.apache.thrift.**
-dontwarn com.google.**
-dontwarn com.coloros.**

-dontwarn com.vivo.push.**
-keep class com.vivo.push.**{*; }
-keep class com.vivo.vms.**{*; }
-keep class com.mob.pushsdk.plugins.vivo.PushVivoReceiver{*;}

-keep class com.meizu.cloud.pushsdk.MzPushMessageReceiver{
public *;
}

-keep class com.mob.pushsdk.plugins.xiaomi.PushXiaoMiRevicer {*;}
-dontwarn com.xiaomi.push.**

#这是oppo的混淆规则
-keep public class * extends android.app.Service
-keep class com.heytap.msp.** { *;}
-keep class com.mob.pushsdk.plugins.oppo.** { *;}

6、番外

当然,也可以选择在 AndroidManifest 中选择开启 Debug 功能:

代码语言:txt
复制
<!-- 开启日志调试功能 -->
<meta-data
    android:name="com.mob.mobpush.debugLevel"
    android:value="4" />

7、Test 一波,发个通知

在 Mob 后台选择发送一条通知测试下~

image.png
image.png

结果如下:

Kapture 2021-08-15 at 15.43.56.gif
Kapture 2021-08-15 at 15.43.56.gif

再 Test 一波,这次我们将应用回到后台,再来测试下。

Kapture 2021-08-16 at 23.13.45.gif
Kapture 2021-08-16 at 23.13.45.gif

那如果我们现在应用被杀了呢?再来测试下?

Kapture 2021-08-16 at 23.17.55.gif
Kapture 2021-08-16 at 23.17.55.gif

在这里明显可以观察到,当应用被杀(模拟用户非在线时刻),Mob 后台推送并没有及时下发客户端。而当用户再次打开 App 时,才能收到之前的推送。那么,如果我时隔几天后打开呢?消息的及时性又如何保证呢?当然,什么事情也不是绝对的。

那我们现在配置下华为厂商推送再试试?

8、华为厂商推送

这块较为简单,MobPush 写的也狠明确,按照要求进行操作就可以了。

MobSettings 中填写对应的 appId:

代码语言:txt
复制
// 调用MobTech SDK
apply plugin: 'com.mob.sdk'

// 在 MobSDK 的扩展中注册 MobPush 的相关信息
MobSDK {
    appKey "appKey"
    appSecret "appSecret"
    MobPush {
        // 集成其他推送通道(可选)
        devInfo {
            // 华为推送配置信息
            HUAWEI {
                appId "appId"
            } 
        }
    }
}

随后我们在 Mob 后台进行测试离线推送测试:

Kapture 2021-08-17 at 22.46.17.gif
Kapture 2021-08-17 at 22.46.17.gif

经过如上几个测试小 case,我想大家对于接入离线厂商的必要性不言而喻了吧。

其实对于这块,个人理解是:当 Mob 自有通道开启状态,也就是 App 在线时,Mob 后台通过 Mob 自有通道进行消息通知下发。而如果 Mob 通道被关闭,也就是 App 被杀死,这块我猜测可能是心跳包检测?说实话还真没去了解过。关闭时通过设备对应不同厂商通道进行消息下发。从而保证了消息下发并不依赖 App 是否存活,比较厂商(系统)通道,肯定不会被干死,从而进一步的保证了 App 的消息接受性。

其它厂商这里就不一一进行对接测试了,大家前提记得注册好相关厂商帐号,随后按照 MobPush 进行配置即可。

9、再来个指定用户推送并传递对应 key

首先在 App 获取注册 ID:

代码语言:txt
复制
MobPush.getRegistrationId {
    Log.e("HLQ", "------> getRegistrationId $it")
}

随后获取到注册 ID 并设置 Mob 后台,接着选择自定义消息,并设置如下几个内容:

  • content:This is content.
  • hlqType:1
  • hlqCode:666
image.png
image.png
image.png
image.png
image.png
image.png

对应的消息监听如下:

代码语言:txt
复制
MobPush.addPushReceiver(object : MobPushReceiver {

    /**
     * 接收到自定义消息(透传消息)
     */
    override fun onCustomMessageReceive(
        p0: Context?,
        p1: MobPushCustomMessage?
    ) {
        Log.e(TAG, "----> onCustomMessageReceive $p1")
    }

    /**
     * 接收到通知消息
     */
    override fun onNotifyMessageReceive(
        p0: Context?,
        p1: MobPushNotifyMessage?
    ) {
        Log.e(TAG, "----> onNotifyMessageReceive $p1")
    }

    /**
     * 通知被点击事件
     */
    override fun onNotifyMessageOpenedReceive(
        p0: Context?,
        p1: MobPushNotifyMessage?
    ) {
        Log.e(TAG, "----> onNotifyMessageOpenedReceive $p1")
    }

    /**
     * 标签操作回调
     */
    override fun onTagsCallback(
        p0: Context?,
        p1: Array<out String>?,
        p2: Int,
        p3: Int
    ) {
        Log.e(TAG, "----> onTagsCallback $p1")
    }

    /**
     * 别名操作回调
     */
    override fun onAliasCallback(
        p0: Context?,
        p1: String?,
        p2: Int,
        p3: Int
    ) {
        Log.e(TAG, "----> onAliasCallback $p1")
    }
})

当在 Mob 后台点击发送时,App 是没有显式通知的,而在回调接口中,则输出我们刚刚设置的内容:

代码语言:txt
复制
onCustomMessageReceive 
    messageId={4bp6i0t0m5xnyia9ds},
    content={This is content.},
    offlineFlag={0},
    extrasMap={{hlqCode=666, hlqType=1, 
    pushData={"hlqCode":"666","hlqType":"1"}, 
    channel=mobpush, 
    id=4bp6i0t0m5xnyia9ds}},
    timestamp={1629216359101}

好咧,针对 MobPush 推送呢,代码部分到此结束了。大部分官方都有,就不充斥太多的重复性的代码段了。

MobPush 小结


从个人角度而言,每一次都需要有些收获,或者来说,把自己遇到的问题暴露出来,万一官方不好意思调整了呢?

O(∩_∩)O哈哈~

那就从以下几点,简单说说吧。

1、技术保障

周末的时候,出现 MobSDK 拉取不下来的情况,梯子、切换网络、热点,均无效。大周末本来不好意思打扰,结果直接拉群解决,虽然最后还是按照自己降低 gradle 版本处理,但是态度上让人觉得很不错。

周三的时候,中午特意给我反馈,说他们的技术测试正常,并提供了对应的测试 Demo。虽然因为工作原因没能认真看看,但是这个认真负责的态度,赞一波~

一句话,免费的东西,这就不错了。莫抬杠~

2、文档友好度

从 MobPush 的集成来看,如果前期准备工作都已完成(这里指的账号,我从来没遇到过账号准备齐全的,都是自己折腾去),在线推送集成很 Easy,似乎就是分分钟,Mob 后台创建应用,拷贝依赖到根 build,然后跟着官方继续拷贝,剩下就是根据产品进行必要的授权。

而后期厂商集成,相对折腾的点,个人感觉更多的是各个厂商折腾相关信息,开通相关服务。比如华为乱七八糟一大堆,还要下载文件。这块其实对于 Mob 后台配置较为简单,那个 key 之类的就好了,本地项目同理。

这里简单小总结下个人感观:

代码语言:txt
复制
“文档简洁”.apply{
    便于接入
    不便于获取详细日志情况,例如华为集成是否成功?
    针对某些失败情况,未能提供更多的解决示例 
}

关于第二点,这里我拿接入华为离线厂商推送举个例子:

以上两个链接是 MobPush 官方提供,但是我怎么能再接入的同时就了解到我华为渠道接入成功了呢?相关的说明请原谅我没找到。这里我随便找个正面示例:

image.png
image.png

其实针对文档友好度,个人觉得,最简单的方式就是让开发者能否最快速的接入所需要的功能?并且能对于接入内容,官方给出详细说明文档,好比怎么算成功失败了?我怎么能第一时间了解到这些?而不是需要个人实际发送通知测试,才能得出结论。(Mob 小哥哥别打我~ -_-)

关于这个文档更新这块,其实还是会导致人产生误区,简单举几个例子:

  • 官方针对 MobSDK 依赖地址,集成文档是 https 打头,下载 SDK 却写着 http。虽然后续咨询官方,官方说都支持,但是还是上来给人产生误区的感觉。
  • 目前个人测试看是根据配置的厂商渠道自动配置对应的厂商,有个疑问是,假设某天 MobPush 未能主动更新厂商或者开发者想自己替换呢?挺好奇这块的。

还是希望官方能认真统一对待,毕竟一个疏忽会造成集成者的无奈。

人呐,总想得到更多,O(∩_∩)O哈哈~

深入 SDK 稍微看看


整套集成下来,不知道大家注意到我们从始至终都没有调用过 init 方法,那么它在哪儿完成的初始化呢?

会不会是 ContentProvider?印象中此物调用时机介于 Application 的 attachBaseContext 和 onCreate 之间。

盲猜还是不如直接进入 SDK 瞅瞅~

深入 SDK,发现目前 Mob 提供了两种方式:

  • MobApplication:onCreate() init
  • ContentProvider:onCreate() init

反编译生成的 Apk,发生 Mob 将 application name 替换为 MobApplication,如下所示:

代码语言:txt
复制
<application 
    android:name="com.mob.MobApplication" >

这里我不仅微笑一下,那如果我要是 application 继承 MobApplication 呢?还会给我替换么?

代码语言:txt
复制
class BaseApplication : MobApplication() {

    override fun onCreate() {
        super.onCreate()
    }

}

再次反编译 apk 查看下:

代码语言:txt
复制
<application 
    android:name="com.hlq.mob.BaseApplication" >

也是,都继承了 MobApplication 还替换个锤锤?

还别说,这块动态替换还是蛮有意思的,比如说,我集成的过程并没有添加权限,那这些权限什么时候被注入的呢?

奇怪的是在 AndroidManifest 中也看到了上文说到的 ContentProvider:

代码语言:txt
复制
<provider
    android:name="com.mob.MobProvider"
    android:exported="false"
    android:multiprocess="true"
    android:authorities="com.pwccn.klcore.com.mob.MobProvider" />

这到底是什么逻辑?有点茫然了,先拿个小本本记上吧,后续再说。

期间还发现个比较 6 的操作:

  • 当我配置文件中未配置渠道时,SDK 自动拉取 Mob 相关依赖;
  • 而当我配置文件中只有华为时,SDK 自动拉取华为相关依赖。

这个操作很神奇啊,有没有老哥指导的点拨一下下那~

各种混淆,看的茫然,下次有机会再说吧~

Error


  • 如果当前 AS 版本最新,并且 gradle 版本为 7.0 时,出现 MobSDK 拉取失败的情况,直接降低 gradle 版本即可。当然官方最后提供了同样 gradle 7.0 的 Demo,因为个人懒得原因就没有细细研究了。
  • 针对厂商推送失败的情况,认真检查相关包名等是否按照官方要求配置。我这就坑了自己一把。再不行给官方丢个 Demo,让官方帮忙处理下。O(∩_∩)O哈哈~

THK


原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0、Mob 后台创建 App 信息
  • 1、合规处理
  • 2、项目根目录 build 中添加 MobPush 依赖:
  • 3、app 下 build 中新增 Mob 插件和扩展:
  • 4、gradle.properties 中配置隐私协议适配版本
  • 5、添加混淆代码
  • 6、番外
  • 7、Test 一波,发个通知
  • 8、华为厂商推送
  • 9、再来个指定用户推送并传递对应 key
    • 1、技术保障
      • 2、文档友好度
      相关产品与服务
      云直播
      云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档