ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

友盟U-Push接入避坑指南:厂商通道、SDK集成与服务端推送全解

友盟U-Push接入避坑指南:厂商通道、SDK集成与服务端推送全解 1. 友盟消息推送能解决什么问题为什么值得认真搞做App推送这件事表面上看是发一条通知栏消息实际做起来却是一堆糟心事厂商通道各有各的规则、离线设备收不到消息、不同品牌手机的后台策略五花八门、用户卸载重装后推送ID还变了。我接手过好几个项目每次提到推送开发同学的第一反应都是叹气。友盟U-Push这类聚合推送平台核心价值就是把这堆糟心事统一收口。你在友盟后台配置一次厂商通道调用一套API它自动帮你走华为、小米、OPPO、vivo这些厂商的官方通道用户在线时走高可用长连接离线时走厂商通道你不用自己维护长连接、不用研究每个厂商的推送协议差异、不用每天盯着服务器看连接数。对于中小团队来说这是最划算的推送方案没有之一。这篇笔记基于我实际接入友盟推送项目的经历把从创建应用、申请厂商密钥、集成SDK、服务端调用到排查收不到推送这类典型问题的完整链路都写出来。适合三类人看第一次做推送功能的新手、被厂商通道搞到崩溃的Android开发、以及需要自己写服务端推送逻辑的后端同学。iOS的证书配置虽然单独一块我也会把关键节点说明白。你大概率遇到的坑基本都能在下面找到对应解法。2. 集成前的准备工作账号、应用与密钥2.1 创建应用与获取AppKey的细节友盟推送的接入入口是友盟官网注册账号之后进入控制台选择消息推送U-Push。这里有个很多人第一次会搞混的点友盟旗下有移动统计UMeng Analytics和消息推送U-Push两个独立产品虽然是同一个账号体系但要在控制台里分别创建应用。创建应用时填的应用名和包名必须和实际App保持一致特别是Android包名一旦创建后不能修改。我见过有同事先在后台随便填了个包名测试后面要上线时发现包名不一致推送完全收不到排查了一天才发现是这个低级错误。你要认真对待这一步宁可先确认好再填。创建完成之后在应用信息页面能看到两个关键参数AppKey标识你的应用客户端初始化和服务端发推送都要用到App Master Secret服务端调用API时的签名密钥相当于你的推送接口密码绝对不要写在客户端代码里签名机制后面讲服务端时会详细说这里先记住一条凡是出现在客户端代码里的密钥都不叫密钥。2.2 厂商通道的申请与参数配置友盟推送的省心是有前提的Android的厂商通道必须先在各个厂商开放平台注册账号、创建应用、获取密钥然后在友盟后台填入对应参数。这一步绕不开因为厂商通道是厂商控制的用户离线时只能靠它触达设备。当前主流厂商通道需要准备的材料如下厂商开放平台需要获取的关键参数备注华为华为开发者联盟APPID、SecretKey需开通Push Kit服务小米小米开放平台AppID、AppSecret需创建消息推送服务OPPOOPPO开放平台AppKey、AppSecret、MasterSecretMasterSecret用于服务端调用vivovivo开放平台AppID、AppKey、AppSecret推送服务需单独申请魅族魅族开放平台AppID、AppSecret部分老机型通道效果一般荣耀荣耀开发者服务APPID、APPSecret荣耀和华为分家后需要单独申请申请厂商开发者账号时需要企业资质个人开发者往往卡在这一步。如果你们公司暂时只能提供营业执照那就优先接能申请的通道暂时接不了的先用友盟自有的长连接通道顶上后面资质补齐再补配。这种有多少通道配多少的渐进式接入策略在项目上线初期是比较务实的做法。拿到密钥后回到友盟后台在厂商推送设置里逐个填入。有个细节要留意部分厂商后台需要配置包名、应用签名等信息比如华为的SHA256指纹、小米的应用包名配置时保持和App实际信息一致否则厂商通道注册会静默失败你完全察觉不到。3. SDK接入的完整流程与关键代码3.1 Android端基础依赖与初始化友盟推送SDK的接入方式在不同版本上有差异我用的是基于AndroidX的较新版本集成方式。在项目根目录的build.gradle中配置仓库然后在App模块的build.gradle中加入依赖implementation com.umeng.umsdk:common:9.6.7 implementation com.umeng.umsdk:push:6.6.1 implementation com.umeng.umsdk:alicloud-httpdns:2.3.3版本号建议以友盟官方文档最新的release为准但要注意common和push两个版本的兼容关系友盟的SDK对版本配对比较敏感我见过有人从网上随便搜了一对版本号结果编译能过、初始化直接抛ClassNotFoundException。依赖加好之后在AndroidManifest.xml中补充必要权限uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / uses-permission android:nameandroid.permission.WAKE_LOCK / uses-permission android:nameandroid.permission.VIBRATE / uses-permission android:nameandroid.permission.RECEIVE_BOOT_COMPLETED /然后创建你自己的Application类在里面做初始化public class App extends Application { Override public void onCreate() { super.onCreate(); // 初始化友盟推送SDK PushSdk.init(this); } }PushSdk.init是整个集成的核心入口它内部会做几件事生成本地设备标识、建立长连接或者检测厂商通道可用性、注册设备Token。在较新版SDK中友盟的初始化是异步的你在init之后立刻拿Token可能拿不到后面会讲正确的注册回调方式。3.2 初始化时机与隐私合规的坑这里必须单独强调一个合规问题。现在各大应用市场上架隐私政策弹窗是硬要求不能App一启动就去收集设备信息。友盟官方给的规范流程是用户同意隐私协议之前不要调用任何SDK的初始化方法。等用户在隐私弹窗里点击同意后再执行PushSdk.init。我在实际项目中踩过这个坑。当时为了省事把初始化放在了第一个Activity的onCreate里结果应用市场检测到SDK在隐私弹窗出现前就启动采集直接给了违规收集个人信息的警告。后面改成先弹出隐私协议用户点同意后再初始化才算过审。这也直接回应了很多人搜友盟SDK安全吗时的顾虑SDK本身是合规的关键在于接入方是否按规范控制了初始化时机。友盟SDK内部有隐私合规开关但你得确保调用时机正确而不是事后用代码开关去补救。推荐的做法是做一个全局的隐私管理类public class PrivacyManager { public static void onUserAgreePrivacy() { PushSdk.init(App.getInstance()); // 其他需要合规后初始化的SDK } }隐私弹窗点击同意按钮的回调里调用这个方法而不是在Application.onCreate里直接初始化。3.3 厂商通道SDK的辅助集成基础SDK只提供了友盟自有的推送通道要让离线推送真正可靠需要按后台配置的厂商通道逐个在工程里加上对应的辅助SDK。以小米为例implementation com.umeng.umsdk:xiaomi-push:4.3.0 implementation com.umeng.umsdk:xiaomi-umengaccs:4.3.0华为需要在AppGallery Connect里配置推送服务然后再加依赖implementation com.huawei.hms:push:6.11.0.300 implementation com.umeng.umsdk:huawei-umengaccs:6.11.0每个厂商的辅助SDK在集成后友盟SDK会在运行时自动检测设备所属厂商调用对应的系统级通道注册逻辑。这里有个很容易被忽视的问题不同厂商的辅助SDK版本尽量不要自己随意升降。你手动升了某个厂商SDK的小版本可能友盟的accs桥接层和它不兼容轻则日志打报错重则厂商通道注册失败。我的原则是官方Demo里用哪个版本上线前就锁哪个版本。3.4 iOS端推送证书与Token配置服务推送的整体逻辑和Android类似打通APNsApple Push Notification Service是核心调试时最常用的是真机加开发证书的组合。流程大致为在Apple Developer后台开启App的Push Notification权限生成开发版和发布版的推送证书.p12在友盟后台的iOS应用配置里上传对应环境的证书客户端引入友盟推送iOS SDK在didFinishLaunchingWithOptions中初始化并申请APNs权限iOS端的权限弹窗时机同样涉及合规UNUserNotificationCenter的授权请求建议放在用户操作某个功能的场景里这样也能降低首次弹窗被拒绝的概率。4. 服务端推送API调用与消息格式设计4.1 消息签名机制为什么总是401你要在服务端给用户发推送可以直接调用友盟的Rest API。接口地址是POST https://msg.umeng.com/api/send每次请求必须在HTTP头里带两个参数。关键的是签名参数它的生成规则是sign md5(POST https://msg.umeng.com/api/send body字符串 App_Master_Secret)注意这里的细节是拼接字符串后整体做MD5不是把每个字段单独MD5再拼起来。body字符串必须和实际发出去的请求体完全一样包括字段顺序、空格。很多人在这一步踩坑返回401{ret:FAIL,data:{err_msg:SIGN_ERROR}}十有八九是body的原始字符串和实际发送的不一致。写一个可参考的签名代码逻辑import hashlib import requests import json import time import uuid def send_unicast(appkey, secret, device_tokens, alert_text): timestamp str(int(time.time())) payload { body: { ticker: alert_text, title: 你的标题, text: alert_text, after_open: go_app }, display_type: notification, extra: {} } body { appkey: appkey, timestamp: timestamp, type: unicast, device_tokens: device_tokens, payload: payload, production_mode: false # true为生产模式false为测试模式 } body_str json.dumps(body) sign_str POST https://msg.umeng.com/api/send body_str secret sign hashlib.md5(sign_str.encode(utf-8)).hexdigest() url fhttps://msg.umeng.com/api/send?sign{sign} resp requests.post(url, databody_str, headers{Content-Type: application/json}) return resp.json()production_mode这个字段要特别留意。开发测试阶段必须设为false否则消息发送到只有开发证书的设备时推送会显示成功但实际上设备收不到。上线时切换为true这个字段的失误会导致后台显示发送成功、用户收不到消息这种低概率但影响恶劣的问题。4.2 四种发送类型选错会误伤用户友盟的API支持四种发送类型unicast单播指定一个device_token发送适合测试和定向通知listcast列播传逗号分隔的多个device_token最多500个broadcast广播发给所有活跃设备适合全量通知groupcast组播按标签或文件推送适合运营分层日常运营最常用的是groupcast和listcast。每次推送前一定要想清楚用哪个类型。我见过有同事测试时不小心用了broadcast结果一条今晚版本更新的测试消息直接推给了线上所有用户运营群里炸开了锅。血的教训测试环境默认只允许用unicast和listcast别碰broadcast。device_tokens这个参数来自客户端注册成功后回调拿到的Token格式是一长串数字看起来像xxxxxxxxxxxxx。它是单设备维度的App卸载重装后会变化。如果你的业务需要做到用户注销登录后不再收到推送这类逻辑需要在服务端维护一个用户ID和Token的映射关系每次客户端上报Token时更新用户退出登录时删除映射。5. 实测中典型的收不到推送问题排查5.1 从App到服务端的完整排查链路收不到推送的原因可以分布在链路的不同环节从客户端到服务端走一遍逐步排查是最稳的。我们团队排这个问题的排查路径一般是这样先确认设备在线状态前台打开App杀掉后台进程再打开看通知栏有没有消息再确认友盟后台的推送记录里任务状态是不是成功失败时附带的具体报错是no_device_token还是tokens_invalid确认设备的Token是否存在在小伙伴的初始化回调里打印DeviceToken看看是不是为空确认Token是否绑定到某个用户上服务端有没有把Token和用户关系记录在库里发送时有没有传对Token最后看厂商通道设备离线时杀掉App进程在友盟后台用单播Test模式发一条如果在线能收到、离线收不到问题基本锁定在厂商通道环节对应关系整理成表格排查时对着看现象可能原因验证方式在线收不到初始化失败、令牌为空、签名错误查看客户端日志与API返回码离线收不到厂商密钥未填、厂商注册失败确认友盟后台厂商密钥与SDK注册日志后台显示成功但收不到production_mode与App环境不匹配核对测试/生产模式部分机型收不到厂商通道白屏厂商后台被系统限制按厂商单独验证5.2 厂商通道离线推送失效的几个坑离线推送失效是排查中最耗时的场景。有一次我们的消息在小米手机上App在前台能收到杀掉进程后永远收不到。排查了很久才发现友盟后台的小米AppSecret填的是开放平台上消息推送服务里的AppSecret但是因为小米平台改版新申请的应用要额外绑定包名我们后台填的包名和实际APK签名里的包名不一致导致小米通道静默注册失败。另一个坑在Android 13及以上动态权限。现在Android的新版本要求通知栏权限单独弹窗如果用户在弹窗里点了不允许厂商通道消息到达设备时通知直接不进通知栏。这个问题的表现是友盟后台显示已送达厂商后台显示已推送但用户完全看不到。需要在App内做二次引导或者在首次弹窗被拒后引导到系统设置里手动打开通知权限。还有一个常被忽略的点部分厂商后台有通知分类和免打扰策略。即使系统通道正常用户如果对某个App在系统设置里选了静默通知那条消息也只会出现在通知列表不会有横幅和声音。这种情况不能靠推送端解决需要在测试用例中区分清楚。6. 进阶玩法与日常维护建议6.1 设置别名、标签与自定义通知样式友盟推送支持别名alias是比device_token更上层的用户标识。给用户绑定别名的好处是即使用户换设备服务端也能通过同一个alias找到设备不用每次换设备都更新Token映射。绑定代码在客户端AliasManager.setAlias(this, userId, USER_ID, new UMCallback() { Override public void onSuccess(String requestId, String s) { // 绑定成功 } Override public void onFailure(String requestId, UMCallback.UMError error) { // 绑定失败可以重试 } });别名也不是绑定成功就一劳永逸了App重装Token变化时客户端重新注册后应再次调用setAlias否则服务端通过alias推送时可能找到旧Token导致推送失效。最稳妥的做法是推送SDK注册成功后把alias与Token的上报放在同一个网络请求里服务端同步更新。自定义通知样式也是日常运营要用的能力。友盟的payload里不仅有title和text还可以带图片、富媒体通过extra字段传自定义参数。比如电商类App的营销推送点开通知后要跳转到商品详情页做法是在payload的extra里带上url或page_path客户端在后台运行或被杀掉时通过解析Intent附加数据再跳转。这要求客户端在推送回调里处理两种情况一种是App在前台自定义处理事件而不是默认展示通知栏另一种是App被杀死后用户点击通知冷启动App需要在启动参数里拿推送数据。6.2 推送策略与后台维护的长期经验推送做得好不好不止是技术问题更是一个策略问题。从我接触过的项目看优秀的推送方案应该在发送前考虑用户的感受时间策略运营消息尽量安排在用户高频使用时段避开深夜。友盟后台支持定时发送你的服务端也可以在生产环境设定窗口期。频控策略对同一用户一天内的推送条数做上限尤其是营销推广类消息。友盟在控制台有针对单台设备的频控设置但业务层面最好自己控制比如一天最多两条营销通知、一条系统通知。退订机制App内要有通知设置入口让用户按场景全部接收、只接收系统消息、完全不接收自主控制。这样短期看推送触达量下降了长期看留存和投诉风险要好得多。服务端日常维护上要写定时任务定期清理无效Token。凡是推送API返回tokens_invalid或device_token为空的记录累计到一定阈值就从映射表里删除。清理得越勤后续推送的到达率、有效率越高费用越省。这里插入一个实际经历我们曾经有大量用户半年不打开App导致了推送API费用上升做了季度级Token清理后有效推送成本明显下降。6.3 消息推送的质量监控体系有一位做增长的朋友跟我说过一句特别认同的话推送是技术也是产品。如果你连自己发出的推送有没有被用户看到都不知道这个推送功能就是半残的。所以接入友盟推送的收尾工作一定是搭一套质量监控在友盟后台看每个推送任务的到达数展示数点击数对照目标指标判断单次活动效果客户端主动上报推送到达埋点。友盟SDK本身有推送统计但自定义埋点能帮你更细粒度地定位用户行为收到通知有多少人点了、点了之后是否进入指定页面服务端记录每次API调用的耗时和返回码。如果发送耗时一直在涨可能是某个渠道配置出了问题及时预警做完了产品和数据的监控推送这整套系统才算真正跑起来。最后补充一个个人经验友盟推送这种聚合平台广告词里宣传的那些优势什么一键接入厂商通道自动适配机型都是以你仔细完成配置为前提的。厂商密钥漏填一个、App环境设错一次、Token映射忘记清理任何一个环节出问题用户那边就是收不到推送四个字。接入本身不难难的是把每个细节都钉到位。建议你按本文的顺序把账号、密钥、SDK、服务端、测试验证这套流程完整走通一遍再放量推广。祝你的推送到达率能稳定在90%以上。
返回列表