接入友盟厂商push通道遇到的坑

article/2025/9/23 23:54:42

 

目录

调试友盟Push问题的检查清单

客户端、服务端数据协议

客户端接入方式

小米厂商通道

华为厂商通道

魅族厂商通道

VIVO厂商通道

  OPPO厂商通道

支持桌面角标的厂商

吐槽一下集成友盟厂商通道时发现的问题


调试友盟Push问题的检查清单

  1. 过滤UmengPushAgent开头的日志可以看到客户端整个执行流程
  2. 过滤UMLog标签就可以打印出客户端注册步骤相关的日志
  3. 过滤NAccs.开头的日志,可以看到SDK内部处理push的执行流程日志
  4. 在和服务端调试之前确保客户端配置正确并且注册成功。注册成功后会有成功的日志,这个日志要好好利用。类似于:在tag:MiPushBroadcastReceiver下面打印log: onCommandResult is called. regid= xxxxxxxxxxxxxxxxxxxxxxx接收到小米消息则会打印log: onReceiveMessage,msg= xxxxxxxxxxxxxxxxxxxxxxx
  5. 当收不到消息时,彻底杀死app之后重新启动再试
  6. 如果各项参数都设置正确了,仍然收不到push。确认下是否开启了通知栏通知权限。如果还不行,重装app、重启手机。
  7. 遇到疑难问题,没有解决思路的时候,文档中每个厂商章节最后边有个xx平台FAQ,可以借助这个文档排查问题(只有魅族没有提供)。

客户端、服务端数据协议

  1. 厂商通道,我们需要传递自定义参数,当然也希望传递尽可能多的自定义参数。所以一开始采用了body.custom参数,但是发现如果after_open:go_activity,这种情况下MipushTestActivity收到的intent是空。扒拉SDK源码后发现是解析intent数据的代码中if条件语句并没有判断这个值而是用的extra这个值。所以传递custom参数会导致MipushTestActivity#onMessage中intent为空。
  2. 那就采用的extra的方式传递,它是(key,value)方式。另外,使用custom传递会有最大1000个字节数的限制。而extra并没有说明是否有字节限制,测试发现满足我们要传的数据大小的要求。姑且认为没有限制吧。
  3. {"msg_id": "uu481201399440513912","display_type": "notification","alias": "","random_min": 0,"body": {"title": "测试自定义参数","ticker": "测试自定义参数","text": "无","after_open": "go_app","url": "","activity": "","custom": "","play_vibrate": "true","play_sound": "true","play_lights": "true"},"extra": {"key1": "value1","key2": "value2"}
    }

     

客户端接入方式

  1. 友盟通道(非厂商通道)下发的push数据走的是UmengMessageHandler#dealWithCustomMessage(),原先接入的,不需要修改。
  2. 厂商通道,对于要传递自定义参数的接入需求。正确的接入方式是,
    1. 离线状态下走MipushTestActivity#onMessage,
    2. 在线状态下走UmengMessageHandler#dealWithCustomMessage()或者UmengMessageHandler#openActivity()
    3. 在线状态不要走MipushTestActivity#onMessage方式,否则会有一系列问题,比如intent为空,intent里数据是加密的等情况
  3. 厂商通道,下发的push数据,走的是UmengNotificationClickHandler,这是个基类,需要自己实现一个子类,并复写openActivity()和dealWithCustomAction()方法。openActivity对应于服务端的after_open=go_activity;dealWithCustomAction对应于服务端的after_open=go_custom。
  4. 所以如果在UmengNotificationClickHandler中实现了openActivity()和dealWithCustomAction()方法,就可以接收到数据(umessage),并做响应的跳转。而且可以在umessage.extra中传递自定义的数据。这是比较方便灵活的接入方式。
  5. 但是如果没有实现一个UmengNotificationClickHandler子类,默认走MipushTestActivity类,文档中说会通过MipushTestActivity#onMessage方法中传递的intent可以接收到数据。但是测试的时候发现并非如此。在应用活跃时收到的intent是空,拿不到任何数据,根本无法跳转。虽然这是文档中一再强调的接入方式,也是我一开始就是采用的接入方式,但是采坑了一周之后发现,这种方式并不适合传递自定义数据。要么是intent为空,要么是intent不为空但是body是加密的数据(SDK内部解密过程出错)。最后发现这个坑根本无法填上。所以才退而求其次,采用了UmengNotificationClickHandler方式。
  6. 但是使用UmengNotificationClickHandler不知道是否对统计push数据有影响,从SDK源代码上看,这种方式并SDK内部没有数据布点。但是MipushTestActivity的方式是有的。

小米厂商通道

  1. 发现小米厂商通道自动支持桌面角标(红点+数字都显示),其他厂商通道是不支持的。
  2. 但是小米系统比较恶心,只有小米系统会禁止App后台启动。app置于后台时,点击push无法把app置于前台。
  3. 小米手机中“后台弹出界面”的权限默认被拒绝了,这样在后台Service中或者其他一些后台操作都无法启动Activity了。在小米手机的应用权限管理中有一个“后台弹出界面权限”,该项权限会限制当APP处在后台时弹出Activity的动作,该权限时默认关闭的,可以在小米系统的权限管理页看到:
  4. 对于这种限制,小米的官方通知是这样的,所以想解决就找法务去谈吧,只有加到白名单才可以正常弹出。
  5. 我把MipushTestActivity这个文件放到了包名目录下,测试功能正常。不知道如果不放到这个目录下是否正常,没有测试这种情况。
  6. 遇到一台手机上的device token有两个的奇怪情况。见如下截图。后来发现原因是接入的时候使用了错误的方法导致的。把mPushAgent.addAlias改成mPushAgent.setAlias就可以了。
  7. addAlias和setAlias的区别,文档中写的很清楚。文档链接 https://developer.umeng.com/docs/66632/detail/98583#h1--tag-alias-4
    //别名增加,将某一类型的别名ID绑定至某设备,老的绑定设备信息还在,别名ID和device_token是一对多的映射关系
    mPushAgent.addAlias("别名ID", "自定义类型", new UTrack.ICallBack() {@Overridepublic void onMessage(boolean isSuccess, String message) {}});
    //别名绑定,将某一类型的别名ID绑定至某设备,老的绑定设备信息被覆盖,别名ID和deviceToken是一对一的映射关系
    mPushAgent.setAlias("别名ID", "自定义类型", new UTrack.ICallBack() {@Overridepublic void onMessage(boolean isSuccess, String message) {}});
    

     

华为厂商通道

  1. 华为厂商通道SDK有个依赖库支持的minSDKVersion版本是16,接入华为意味着只能从16开始支持,符合华为丑的有自己风格的特点。
  2. 友盟没有没有全部适配华为在EMUI8.0+的机型,导致比如EMUI9.0的手机收不到离线消息。建议升级到最新的友盟push SDK,目前最新版是6.0.5。而且为了支持华为EMUI低版本机型,还需要把target SDK version改成25.华为的限制有很多,友盟文档里也写了,符合华为丑的有自己风格的特点。
  3. 在申请华为app id的时候需要一个证书指纹,这个证书就是签名apk的时候的证书。只有华为厂商通道需要这个指纹,符合华为丑的有自己风格的特点。
  4. 从上面几点来看,华为厂商通道侵入性很强,符合华为丑的有自己风格的特点。
  5. 需要在AndroidManifest文件中添加app id,但是奇葩的是需要写成如下形式。
    <meta-dataandroid:name="com.huawei.hms.client.appid"android:value="appid=xxxxxx" />
    

    value中需要添加“appid=”这个前缀。只能说这种与众不同的方式,符合华为丑的有自己风格的特点。

魅族厂商通道

  1. 魅族注册成功的日志要过滤MzPushMessageReceiver,文档中说在MeizuPushReceiver下面打印log。如果用MeizuPushReceiver在某些手机上是没有日志的。使用MzPushMessageReceiver会打印出日志。成功日志是这样的:
    03-04 18:42:27.986 29690-30360/? I/MzPushMessageReceiver: onRegisterStatus BasicPushStatus{code='200', message='already register PushId,dont register frequently'}pushId='xxx', Become invalid after 421388 seconds }

     

  2. 魅族也存在服务端显示下发成功,但是客户端收不到的情况。官方文档给出了一部分解释,如下图。
  3. 如果有类似这样的日志,可以忽略,并不是导致无法接受的问题原因。UmengPushAgent: startPush onFailure s: 503.2, s1=accs channel disabled!
  4. 友盟客服说魅族必须在application的onCreate中进行,并且不能延迟或异步初始化,不能做进程判断。运行起来确实如此。其他厂商接入都没问题了,偏偏魅族手机上无法获取device token。打印日志报错如下:

 详见问题链接 https://developer.umeng.com/docs/66632/detail/67140?um_channel=sdk 

后来发现我的接入的代码中并没有进程判断,但是有多进程,所以会遇到上面那个错误。其实只要重启几次App就可以注册成功了。

VIVO厂商通道

  1. vivo注册成功的日志是这样的

    2020-03-04 18:27:46.411 28994-28994/? I/VivoPush.PushMessageReceiver: (xxx)PushMessageReceiver com.iqoo.secure ; type = 10 ; requestId = null

     

  2. 成功收到离线消息后,在我的vivo手机上该消息是折叠的状态

  3. 使用过程中发现vivo的厂商通道功能比较鸡肋,支持机型少,支持的系统版本少。

  4. Vpush bind成功了,但是手机接收不到push?
    确认系统通知开关是否打开。部分系统版本限制,只能在进程存活下接收通知

  5. 推送成功后但是没有收到消息的问题排查
    1)确认客户端是否已经成功集成并turnOnPush获取到regId,推送指定的regId是否是最新的regId;

    2) 确认手机是否已经打开通知栏开关权限;确认手机时间是否是获取网络时间,不要修改系统时间;

    3)检查消息是否已经送达但是折叠到了消息盒子里面?目前的策略是应用存活时展示,不存活时折叠;

    4)检查单个客户端每日可接收的消息数量是否超出了限制?目前正式应用是每天可接收5条群推消息;

    5)检查设备联网是否有问题,如果连接的wifi设置了代理,一般需要重启手机,可以切换手机网络重试;

    6)如果上诉条件检查了但还是没有接收到消息,可以提供消息Id(taskId)和客户端订阅推送时返回的regId给企业QQ客服定位原因。

  6. 安装测试包之后,vivo手机上该应用的通知权限详情页显示如下。也就是默认是关闭了应用图标标记(桌面角标)、顶部预览、锁屏显示功能。这些都需要手动开启。这些坑需要参考oppo的做法,需要应用程序主动监测是否有通知权限,并在没有开启权限的时候给与弹窗提示,让用户开启弹窗。否则该厂商通道是无法发挥作用的。

  7. 用户收到的推送消息是否有数量限制
    用户可以收到的单推数量不受限制,公共类消息(全推,群推,标签推)一个用户每天接收上限为5条。

  8. vivo推送支持哪些机型和系统版本?
  9. 目前SDK仅支持下表中的机型和对应的系统及以上系统。
  10. image.png
  11. 手机晚上无法收到推送?在限制时间之外发送推送,是会延迟推送还是被直接抛弃?
    1)为避免造成用户打扰,目前vivo手机接收的消息为7:00-23:00,服务器允许推送时间为7:00-22:00,单推不受此时间限制。

    2)在允许时间之外发送的群推或全推,会被抛弃,会计算在发送次数限制中,除非有做入口限制,才会不计。

  12. 如何判断系统是否支持Vpush?    
    可通过调用客户端isSupport()返回的公共状态码判断,状态码为101则系统不支持。     

  13. Vpush目前支持deeplink吗?    
    支持

  14. vivo收到的push内容是一堆加密的串,而不是像其他厂商那样是已经解密之后的数据。如下图所示。
  15. 解析这些数据的逻辑在'com.umeng.umsdk:agoo-accs:3.3.8.8-open-fix2'包里面的AgooFactory类中,解析的方法叫做parseEncryptedMsg。从这个方法的实现可以看出。b对应的就是body数据。i对应的是id信息。此时拿到的body仍然是加密的数据。需要解密。
  16. 解密的逻辑仍然在'com.umeng.umsdk:agoo-accs:3.3.8.8-open-fix2'包里。在agoo包下的b类。它是一个runnable,实现解密的具体是现在AgooFactory.parseEncryptedMsg方法中。从代码可以看到它是HmacSHA1的加密方式。
  17. 至于为什么没有解密成功呢?这个需要再次确认原因。
  18. b类的解密处理完之后,在finally块里会执行onMessage方法,进而把解密之后的数据以intent的形式往下传,因而会进一步调用到MipushTestActivity的回调方法onMessage。
  19. 但是遇到的问题是app在线状态推送消息时,onMeassge中的参数intent是null。
  20. 为了方便排查问题,收到消息后SDK内部执行流程如下
UmengMessageHandler ->  
handleMessage ->  
dealWithNotificationMessage -> 
click -> 
NotificationProxyBroadcastReceiver ->  
onReceive -> 
getNotificationClickHandler.handleMessage -> 
openActivity(go_activity) -> 
startActivity -> 
MipushTestActivity -> 
BaseNotifyClickActivity.onNewIntent -> 
buildMessage -> 
把4中的b类加入线程池执行 -> 
见第5点 -> 
MipushTestActivity.onMessage方法被调用

 

OPPO厂商通道

  1. OPPO手机系统对开发者不友好,双清之后安装的debug包,会默认关闭通知栏的权限。需要重新打开。
  2. OPPO应用通知栏权限默认是关闭的,建议在APP内做弹框提示,调用requestNotificationPermission显示通知权限弹窗,引导用户一键开启通知栏权限。接入OPUSH通知栏弹窗需要客户端sdk1.1.0以上,建议接入最新版的客户端sdk。
  3. 如何开启“通知栏开关授权弹窗”功能?开发者可调用requestNotificationPermission显示通知权限弹窗,用户可通过弹窗自行选择是/否打开应用的通知权限。建议在Activity的onResume方法中调用该接口以避免和其他弹窗重叠。重复调用该接口,弹窗也仅会显示一次。
  4. 通知栏开关授权弹窗是否展示,有数据回调吗,能统计开启和没开启的人数吗?目前通知栏开关授权弹窗是没有数据回调的,不能统计开启人数。
  5. 所有机型都能调用通知栏开关授权弹窗接口吗?系统消息的版本已升级至1.1.0 版本的手机才能接收到通知栏弹窗。(查看方式:【应用管理→ 显示系统进程→ 系统消息】)
  6. 推送成功后为什么收不到消息(或者未展示)?

  7. 目前支持ColorOS3.1及以上的系统。
  8. 目前只支持通知栏消息,透传消息暂不支持。

  9. 没启动过的应用,无法收到消息。曾经启动过的应用,如果30天内该设备有联网行为,后续无需启动也可收到消息。

  10. Registrationid何时产生,何时失效?应用第一次启动时注册生效,后只有在刷机、还原手机(设置-其他设置-还原手机)、卸载应用时才会失效。失效及变更情况参见下表:

支持桌面角标的厂商

  1. 测试发现小米所有机型都支持角标(红点)
  2. 魅族、三星app在线时支持角标显示
  3. 华为app离线时支持角标显示
  4. vivo、oppo均不支持

吐槽一下集成友盟厂商通道时发现的问题

  1. 找客服人员沟通技术问题时,对方一直无法理解,要求提供截图,提供更多详细信息。那如果他要是对友盟SDK内部原理有充分了解的话,是不存在这种问题的,无奈之后自己去debug SDK的执行流程,这被证明比问客服更有效
  2. 提供一个粗制滥造的demo。明明是集成厂商通道的demo却没有任何展示集成厂商通道的代码,一个厂商的都没有。只写了注册和初始化友盟基础功能的示例。写代码只注册,不解注册吗?

http://chatgpt.dhexx.cn/article/kAs1KDbP.shtml

相关文章

Android集成友盟消息推送SDK

消息推送SDK快速集成&#xff1a; 申请AppKey ——> 接入Push SDK ——> 基础接口引入 ——> 消息推送测试 ——> 接入完成 1.申请AppKey 2.接入Push SDK 1&#xff09;、加入依赖 //友盟push相关依赖(必须)implementationcom.umeng.umsdk:push:6.1.0impleme…

机器学习之手写决策树以及sklearn中的决策树及其可视化

文章目录 决策树理论部分基本算法划分选择信息熵 信息增益信息增益率基尼系数基尼指数 决策树代码实现参考 决策树理论部分 决策树的思路很简单&#xff0c;就是从数据集中挑选一个特征&#xff0c;然后进行分类。 基本算法 从伪代码中可以看出&#xff0c;分三种情况考虑&…

android使用友盟推送注册失败获取不到token accs bindapp error!

使用友盟推送注册失败获取不到token public void onFailure(String s, String s1)的值分别是“-9”和“accs bindapp error!”或者s的值为-11.都是同一个问题 就是主工程&#xff08;除友盟PushSDK 其他的module均看成为主工程&#xff09;so目录与PushSDK下的so目录不一致…

同时集成阿里云旺与友盟推送,初始化失败s:-11,s1:accs bindapp error!的解决办法

在应用中需要同时集成聊天和推送功能&#xff0c;聊天选用阿里的sdk&#xff08;百川云旺&#xff09;&#xff0c;推送选用友盟的pushSDK。 这时候悲剧就出现了&#xff0c;注册友盟的时候报错。 I/com.umeng.message.PushAgent: register-->onFailure-->s:-11,s1:accs …

关于友盟s=-11;s1=accs bindapp error!的解决处理

项目使用了友盟推送之后&#xff0c;在部分手机上出现accs bindapp error&#xff0c;错误码-11的问题&#xff0c;为什么会出现这个问题呢&#xff0c;网上查找了很久&#xff0c;友盟给出的解释是so文件不正确。 具体链接&#xff1a;http://bbs.umeng.com/thread-23018-1-1…

友盟register failed: -11 accs bindapp error!

下载官方Demo后,替换自己的id包名后出现 register failed: -11 accs bindapp error! 经过一番搜索之后,都是说这二种原因 1、检查appkey和secret key是否配置正确&#xff0c;如果正确无误&#xff0c;请看步骤2。2、so文件配置有误&#xff0c;需重新配置&#xff1a; Pus…

阿里无线11.11 | 手机淘宝移动端接入网关基础架构演进之路

移动网络优化是超级App永恒的话题&#xff0c;对于无线电商来说更为重要&#xff0c;网络请求体验跟用户的购买行为息息相关&#xff0c;手机淘宝从过去的HTTP API网关&#xff0c;到2014年升级支持SPDY&#xff0c;2015年双十一自研高性能、全双工、安全的ACCS&#xff08;阿里…

VS2015 realease模式下调试

一、将项目属性设置为Release&#xff0c;生成--->配置管理器&#xff1a; 二、按AltF7&#xff0c;弹出属性页进行设置&#xff1a;

AndroidStudio如何打包生成realease版本的arr包,并上传到Nexus搭建的maven仓库,供项目远程依赖(二)

AndroidStudio如何打包生成realease版本的arr包&#xff0c;并上传到Nexus搭建的maven仓库&#xff0c;供项目远程依赖&#xff08;二&#xff09; AndroidStudio如何打包生成realease版本的arr包&#xff0c;并上传到Nexus搭建的maven仓库&#xff0c;供项目远程依赖&#xff…

AndroidStudio如何打包生成realease版本的arr包,并上传到Nexus搭建的maven仓库,供项目远程依赖(一)

AndroidStudio如何打包生成realease版本的arr包&#xff0c;并上传到Nexus搭建的maven仓库&#xff0c;供项目远程依赖&#xff08;一&#xff09; 背景: 公司之前在eclipse上做开发&#xff0c;写了很多library库供项目依赖使用&#xff0c;现在转AS上了&#xff0c;并用Nexu…

QT debug 功能正常 realease和windeplayqt工具打包部分功能无法使用或者不正常

目录 说明开发环境错误说明结论 说明 在项目的开发中&#xff0c;一般程序员都是使用debug版本进行程序的编写和调试&#xff0c;习惯好一些的程序员可能会天天用realease跑一遍自己写的程序是否正常&#xff0c;但是很多程序员可能都不会这么做&#xff0c;直到程序功能完成时…

Python OpenCV10:OpenCV 视频基本操作

1. 读视频 1.1 获取视频对象 要在 OpenCV 中获取视频&#xff0c;需要创建一个 VideoCapture 对象并指定要读取的视频文件。 cv.VideoCapture(filepath) 参数&#xff1a; filepath 视频文件路径 返回值&#xff1a; cap 读取视频的对象 1.2 获取视频属性 cap.get(propId) 获…

Renderers

渲染器 (Renderers) 在将 TemplateResponse 实例返回给客户端之前&#xff0c;必须渲染它。渲染过程采用模板和上下文的中间表示&#xff0c;并将其转换为可以提供给客户端的最终字节流。—— Django 文档 REST framework 包含许多内置的渲染器 (Renderer) 类&#xff0c;允许…

python调用opencv实现视频读写

文章目录 一、从文件中读取视频并播放1.1 基本API讲解1.2 python实现 二、保存视频2.1 基本API讲解2.1 python实现范例 一、从文件中读取视频并播放 1.1 基本API讲解 在OpenCV中我们要获取一个视频&#xff0c;需要创建一个VideoCapture对象&#xff0c;指定你要读取的视频文…

记一次有趣的debug,VS编译器上Debug和Realease的差异

之前自己写过一个imageread的函数&#xff0c;用了好久一直没问题。最近两天&#xff0c;同事让我realease一个项目给他&#xff0c;其中就包含了我自己写的imageread函数。 我的函数就长这样&#xff0c;不包含公司的code&#xff0c;不算泄密哈。 在realse之前&#xff0c;我…

C++语言基础篇

✅作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域新星创作者&#xff0c;阿里云专家博主&#xff0c;华为云云享专家博主&#xff0c;掘金后端评审团成员 &#x1f495;前言&#xff1a; 学长出的这一系列专栏适合有⼀点 C 基础&#xff0c…

PCL12.1 Realease 附加依赖项

PCL12.1 Realease 附加依赖项 libboost_atomic-vc142-mt-g-x64-1_78.lib libboost_bzip2-vc142-mt-g-x64-1_78.lib libboost_chrono-vc142-mt-g-x64-1_78.lib libboost_container-vc142-mt-g-x64-1_78.lib libboost_context-vc142-mt-g-x64-1_78.lib libboost_contract-vc142-…

Vue强制刷新页面重新加载数据方法

业务场景 在管理后台执行完增删改查的操作之后&#xff0c;需要重新加载页面刷新数据以便页面数据的更新 实现原理 就是通过控制router-view 的显示与隐藏&#xff0c;来重渲染路由区域&#xff0c;重而达到页面刷新的效果&#xff0c;show -> flase -> show 具体代码…

Linux 重新加载 nginx 配置命令

1. 查找 nginx 位置 whereis nginx2. 进入 nginx 目录 cd /usr/local/nginx/sbin3. 检查 nginx 配置文件是否正确 ./nginx -t 4. 重新加载配置文件 ./nginx -s reload

IDEA 无法重新加载Maven项目

IDEA 无法重新加载Maven项目 如图&#xff1a; 真头疼&#xff0c;搞了半小时才搞明白&#xff0c;我的Maven版本是3.8.6&#xff0c;而idea版本是2020&#xff0c;用不了这么新版的maven。 解决方案 maven版本高于idea版本&#xff0c;去查找低于idea版本日期的maven或者直…