说明:
TUICallKit 组件支持在 App 退到后台或被系统杀死时,通过国内各厂商推送通道唤醒被叫用户,使其能及时收到来电。本文档为您提供两种集成方式:基础推送(免费) 和 付费推送(基于 TIMPush 推送插件),您可以根据自己的业务需求进行 方案选择。
集成效果
按照本文档接入后,您的 App 在被杀进程或锁屏状态下也能及时唤醒被叫用户的来电。被叫端的实际显示效果会因厂商系统而异,整体类似于系统电话的来电通知:
说明:
不同厂商的系统在通知样式上略有差异,下图以 vivo 设备为例。整体来看用户在 App 退后台或锁屏状态下都能可靠收到来电通知。
应用在后台时或离线时 | 锁屏时 |
![]() | ![]() |
方案选择
您的需求 | 接入方案 | 费用 |
仅在 App 前台使用通话,不需要离线唤醒。 | 无需接入推送,跳过本文档 | 免费 |
仅需要 App 退后台/被杀死时收到来电响铃,无其他诉求。 | 免费 | |
需要数据统计、链路追踪、营销推送、跨平台支持等更完整的能力。 |
说明:
国内通话离线推送由各厂商通道(华为 / 小米 / OPPO / vivo / 荣耀 / 魅族)下发,不依赖 FCM。出厂的中国大陆设备一般不带 GMS 服务,FCM 在大陆环境无法触达,请勿在国内场景下仅依赖 FCM。
各厂商通道由各自的应用市场审核管理,vivo / 小米 / OPPO 正式环境推送通常要求 App 已上架其应用市场,否则推送可能不下发或受频次限制。建议在上架前用厂商提供的"测试推送"模式做基本验证。
前置准备
无论选择方案一还是方案二,都需要先在各厂商的开放平台申请推送应用、把厂商凭据上传到 IM 控制台、并把控制台返回的证书 ID 告诉 SDK。
步骤 1. 申请各厂商推送应用并获取凭据
请按需在各厂商开放平台分别注册推送应用,每家会要求的字段不同,整体清单如下:
厂商 | 必需字段 | 说明 |
华为 HMS Push | agconnect-services.json | |
小米 MiPush | AppId、AppKey | |
OPPO Push | AppKey、AppSecret | |
vivo Push | AppId、AppKey | |
荣耀 Push | mcs-services.json 或 AppId | |
魅族 Flyme Push | AppId、AppKey |
说明:
您的应用包名(applicationId)必须与各厂商开放平台注册时填写的包名完全一致,否则推送无法下发。
步骤 2. 将厂商凭据上传到 IM 控制台


说明:
需要哪几家厂商就上传哪几家,不全也可以(不上传的厂商对应通道不可用)。
应用包名(Bundle ID)必须与您 App 的
applicationId 一致。上传成功后,每家厂商会得到一个证书 ID(数字),用于后续 SDK 调用
setCertificateID 时填写。方案一:基础推送
步骤 1. 添加厂商外挂依赖
在 App 模块的
build.gradle 中按需添加各厂商外挂包(不需要引 TIMPush 主包):dependencies {// 已有 AtomicXCoreimplementation 'com.tencent.atomicxcore:atomicxcore:latest.release'// 按需添加厂商外挂(用哪家加哪家)implementation 'com.tencent.timpush:huawei:latest.release'implementation 'com.tencent.timpush:xiaomi:latest.release'implementation 'com.tencent.timpush:oppo:latest.release'implementation 'com.tencent.timpush:vivo:latest.release'implementation 'com.tencent.timpush:honor:latest.release'implementation 'com.tencent.timpush:meizu:latest.release'}
禁止:
请勿引入
com.tencent.timpush:timpush 主包,主包带有自动注册机制,会和 AtomicXCore 内置推送链路冲突。基础推送方案只需要 FCM 外挂包。注意:
厂商外挂会通过 Gradle 自动传递依赖各自的官方 SDK(如
com.huawei.hms:push、com.xiaomi.push:push),您不需要单独添加。步骤 2. 配置厂商所需的 manifestPlaceholders 和插件
部分厂商外挂需要通过 manifestPlaceholders 注入 AppId / AppKey。在
build.gradle 的 defaultConfig 中加入:android {defaultConfig {manifestPlaceholders = [VIVO_APPKEY : 'YOUR_VIVO_APPKEY',VIVO_APPID : 'YOUR_VIVO_APPID',HONOR_APPID : 'YOUR_HONOR_APPID',]}}
并在工程级和 app 模块的
build.gradle 中应用华为、荣耀的 Gradle 插件:// 工程根目录 build.gradlebuildscript {dependencies {classpath 'com.huawei.agconnect:agcp:1.9.1.301'classpath 'com.hihonor.mcs:asplugin:2.0.1.300'}}// app 模块 build.gradle 顶部apply plugin: 'com.huawei.agconnect'apply plugin: 'com.hihonor.mcs.asplugin'
注意:
工程根目录还需要在 repositories 中添加华为、荣耀 maven 仓库,否则上述插件和 SDK 拉不下来。
把华为的 agconnect-services.json 放到 app 模块根目录、把荣耀的 mcs-services.json 放到对应位置(按各厂商接入文档要求)。
步骤 3. 上报证书 ID
在
Application.onCreate 中调用 LoginStore.setCertificateID,把您在 前置准备 中拿到的各厂商证书 ID 一次性上报。SDK 内部会自动检测当前设备品牌、调用对应厂商外挂拿 token、并同步到 IM 后台。import io.trtc.tuikit.atomicxcore.api.login.LoginStoreclass App : Application() {override fun onCreate() {super.onCreate()LoginStore.shared.setCertificateID(mapOf(// 华为"huaweiCertificateId" to "12345",// 小米(需要 AppId + AppKey)"xiaomiCertificateId" to "12345","xiaomiAppId" to "123454321","xiaomiAppKey" to "123454321",// OPPO(需要 AppKey + AppSecret)"oppoCertificateId" to "12345","oppoAppKey" to "YOUR_OPPO_APPKEY","oppoAppSecret" to "YOUR_OPPO_APPSECRET",// vivo"vivoCertificateId" to "12345",// 荣耀"honorCertificateId" to "12345",// 魅族(需要 AppId + AppKey)"meizuCertificateId" to "12345","meizuAppId" to "12345","meizuAppKey" to "YOUR_MEIZU_APPKEY"))}}
说明:
调用时机不限,登录前后都可以,SDK 会在 IM 登录态就绪后自动同步 token 到 IM 后台。
只需调用一次,登出/重新登录后不需要再调一次,SDK 内部会自动处理。
哪家厂商的 ID 不填,对应通道就不启用,可以按您实际上传的厂商灵活配置。
步骤 4. 拨打通话
AtomicXCore 的 CallStore 在发起通话时自动携带离线推送参数,您不需要手动设置任何 offlinePushInfo 字段。默认推送内容如下:字段 | 默认值 |
推送标题 | 主叫用户的 ID。 |
推送描述 | 中文环境下为「您有新的来电」,其它语言为「You have a new call」。 |
铃声 | SDK 内置铃声。 |
如果您想自定义推送标题或描述,可在发起通话时通过
CallParams 传入 offlinePushTitle / offlinePushDescription,传入后会覆盖上述默认值。import io.trtc.tuikit.atomicxcore.api.call.CallStoreimport io.trtc.tuikit.atomicxcore.api.call.CallParamsimport io.trtc.tuikit.atomicxcore.api.call.CallMediaTypeval params = CallParams().apply {timeout = 30 // 超时时间(秒)userData = "自定义数据" // 扩展信息(可选)// 可选:自定义离线推送标题和描述(不填则使用默认值)offlinePushTitle = "张三"offlinePushDescription = "邀请您视频通话"}val userIdList = listOf("被叫用户的 userID")CallStore.shared.calls(participantIds = userIdList,mediaType = CallMediaType.VIDEO, // VIDEO 视频通话,AUDIO 语音通话params = params) { result ->if (result.isSuccess) {// 通话发起成功,跳转到您自己的通话页面} else {// 通话失败处理}}
方案二:付费推送
步骤 1. 开通服务


步骤 2. 接入 TIMPush 主包和厂商外挂
在 App 模块
build.gradle 中添加:dependencies {implementation 'com.tencent.atomicxcore:atomicxcore:latest.release'// TIMPush 主包(必引)implementation 'com.tencent.timpush:timpush:latest.release'// 各厂商外挂(按需引入)implementation 'com.tencent.timpush:huawei:latest.release'implementation 'com.tencent.timpush:xiaomi:latest.release'implementation 'com.tencent.timpush:oppo:latest.release'implementation 'com.tencent.timpush:vivo:latest.release'implementation 'com.tencent.timpush:honor:latest.release'implementation 'com.tencent.timpush:meizu:latest.release'}
步骤 3. 实现自动登录
您需要在
Application 中监听该事件并实现自动登录逻辑,否则被叫端在应用被杀死后无法拉起来电 UI。import com.tencent.qcloud.tuicore.TUIConstants;import com.tencent.qcloud.tuicore.TUICore;import com.tencent.qcloud.tuicore.interfaces.ITUINotification;TUICore.registerEvent(TUIConstants.TIMPush.EVENT_IM_LOGIN_AFTER_APP_WAKEUP_KEY,TUIConstants.TIMPush.EVENT_IM_LOGIN_AFTER_APP_WAKEUP_SUB_KEY,new ITUINotification() {@Overridepublic void onNotifyEvent(String key, String subKey, Map<String, Object> param) {if (TUIConstants.TIMPush.EVENT_IM_LOGIN_AFTER_APP_WAKEUP_KEY.equals(key)&& TUIConstants.TIMPush.EVENT_IM_LOGIN_AFTER_APP_WAKEUP_SUB_KEY.equals(subKey)) {// 实现您的自动登录逻辑(拉起通话页面前必须先完成 IM 登录)autoLogin();}}});
说明:
该事件由 TIMPush 主包在用户点击通知横幅唤起 App 时发出,仅方案二可用。
方案一(基础推送)请直接在
Application.onCreate 中实现 IM 自动登录逻辑,无需监听该事件。TIMPush 主包通过
ServiceInitializer 机制自动初始化,并在 IM 登录成功后自动 registerPush 拿 token,业务侧无需手动调用任何初始化方法。步骤 4. 拨打通话
高级功能
自定义铃声
SDK 默认使用
phone_ringing 作为离线推送铃声资源名。如果您想自定义铃声,只需在您 App 的 app/src/main/res/raw/ 目录下放置一个名为 phone_ringing.mp3 的音频文件,Android 资源合并机制会自动覆盖 SDK 内置的同名资源。your-app/└── app/└── src/main/res/raw/└── phone_ringing.mp3 ← 您的自定义铃声
注意:
替换后不论应用在前台、后台或者离线,铃声都会是替换后的铃声。
替换后所有厂商手机收到邀请后的铃声都会是替换后的铃声。
文件名必须严格为
phone_ringing.mp3(小写、不带空格),否则不会生效。方案一和方案二均支持该方式自定义铃声。
常见问题
收不到推送,如何排查?
按以下顺序逐项排查:
1. 检查 IM 控制台是否上传了对应厂商的证书:证书 ID 是否与代码里
setCertificateID 填的一致。2. 检查应用包名(applicationId):必须与各厂商开放平台注册时一致,与 IM 控制台上传证书时填的包名一致。
3. 检查通知权限:在系统设置中确认您的 App 已授予"通知"权限。
4. 检查应用是否在厂商应用市场上架:vivo / 小米 / OPPO 在生产环境一般要求 App 已上架其应用市场,否则推送可能不下发。
5. 过滤 Logcat 关键字
[PushManager] 和 [ChannelManager]:查看 SDK 实际调用的厂商通道及返回结果。说明:
如果以上步骤未能解决问题,请参考 插件推送 > 常见问题 进行排查。
应用被杀死后无法弹出来电 UI,怎么办?
如果已经收到推送但没有弹出来电 UI,按以下顺序排查:
1. 确认收到推送:过滤 Logcat 关键字
[PushManager] / [ChannelManager] / TIMPush(方案二),确认厂商通道有 token 注册成功并能收到推送下发。如果没收到推送,请按 常见问题:收不到推送,如何排查? 排查。2. 确认应用已实现自动登录:SDK 收到推送后会自动尝试拉取通话请求,但拉取依赖 IM 已登录态。如果应用被杀进程后没有实现自动登录,SDK 拉不到通话请求,自然也不会显示来电 UI。建议在应用启动入口或
Application.onCreate 中实现 IM 自动登录逻辑。3. 确认权限:部分厂商系统需要授予"显示在其他应用上层"、"后台拉起界面"权限才能在被杀状态下弹出来电 UI,请引导用户在系统设置中开启。
厂商推送服务上架有哪些要求?
各厂商推送通道在生产环境的上架要求和账号要求如下:
厂商通道 | 是否需要上架 | 账号说明 |
小米 | 是 | 需要注册企业开发者账号。 |
vivo | 是 | 需要注册企业开发者账号。 |
OPPO | 否 | 需要注册企业开发者账号。 |
荣耀 | 否 | 需要注册企业开发者账号。 |
华为 | 否 | 个人开发者账号即可。 |
魅族 | 否 | 个人开发者账号即可。 |
上架时,小米 / vivo / OPPO 在开放平台都提供了"测试推送"模式以便联调:
vivo:测试推送每天 1000 条额度,可加白名单设备。
小米:可申请少量公信通道临时权限。
OPPO:可在后台添加测试设备白名单。
方案一相关问题
接入方案一后发现不够用,如何升级到方案二?
按以下步骤切换:
1. 在
build.gradle 中加上 implementation 'com.tencent.timpush:timpush:latest.release'(厂商外挂依赖保持不变)。2. 删除代码中的
LoginStore.shared.setCertificateID(...) 调用——TIMPush 主包通过 ServiceInitializer 自动初始化、并在 IM 登录成功后自动 registerPush,不需要手动初始化。3. 按 方案二 > 实现自动登录 监听
EVENT_IM_LOGIN_AFTER_APP_WAKEUP_KEY 事件实现被推送唤起后的自动登录。4. 完成 方案二 > 开通服务 中的购买或试用流程。
注意:
两种方案不能同时使用,切换时请确保
build.gradle 里只保留一套依赖(要么 AtomicXCore 单独引厂商外挂,要么搭配 timpush 主包),代码里也只保留一套初始化逻辑。方案二相关问题
如何确认 TIMPush 推送链路是否正常工作?
过滤 Logcat 关键字
TIMPush,关注这几条日志:register success:厂商通道注册 token 成功setOfflinePushConfig success:token 上报到 IM 后台成功主叫端发起呼叫后,被叫端日志中出现
onReceiveNotificationMessage:表示已收到推送
