You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo中实现后台来电弹窗UI:CallKeep配置及替代方案求助

Expo + React Native WebRTC 后台来电弹窗解决方案(CallKeep深度配置+替代方案)

一、Expo环境下CallKeep完整配置步骤(EAS Build必做)

1. 依赖安装与基础配置

别用原生的react-native-callkeep,Expo环境必须用官方适配的expo-callkeep,先装依赖:

npx expo install expo-callkeep

然后在app.json或者app.config.js里加配置,把占位符换成你自己的信息:

{
  "expo": {
    "plugins": [
      [
        "expo-callkeep",
        {
          "ios": {
            "appGroupName": "group.your.bundle.id.callkeep",
            "ringtoneFileName": "your-ringtone.caf"
          },
          "android": {
            "alertTitle": "来电通知",
            "alertDescription": "有视频通话请求",
            "cancelButton": "拒绝",
            "acceptButton": "接听"
          }
        }
      ]
    ],
    "ios": {
      "bundleIdentifier": "your.bundle.id",
      "backgroundModes": ["voip", "audio", "fetch", "remote-notifications"]
    },
    "android": {
      "package": "your.package.name",
      "permissions": [
        "android.permission.INTERNET",
        "android.permission.CAMERA",
        "android.permission.RECORD_AUDIO",
        "android.permission.VIBRATE",
        "android.permission.FOREGROUND_SERVICE",
        "android.permission.WAKE_LOCK",
        "com.android.permission.SCHEDULE_EXACT_ALARM"
      ],
      "useNextNotificationsApi": true
    }
  }
}

2. iOS平台关键配置(没做这些肯定成不了)

  • VoIP推送证书:去Apple开发者后台生成VoIP推送证书,绑定你的bundle ID,下载后导入Keychain,导出p12给服务端用——这是iOS后台唤醒的核心,没有这个,App后台收不到来电推送。
  • App Group配置:在Apple开发者后台给你的App创建App Group,名称要和app.json里的appGroupName完全一致,CallKeep靠这个在后台和App通信。
  • 代码初始化与事件监听:
import * as CallKeep from 'expo-callkeep';
import * as Notifications from 'expo-notifications';

// App启动时就初始化CallKeep
async function setupCallKeep() {
  const options = {
    ios: { appName: '你的应用名' },
    android: {
      alertTitle: '来电',
      alertDescription: '视频通话请求',
      cancelButton: '拒绝',
      acceptButton: '接听',
    },
  };
  await CallKeep.setup(options);
  
  // 绑定接听、拒绝、来电事件
  CallKeep.addEventListener('didReceiveStartCallAction', handleIncomingCall);
  CallKeep.addEventListener('answerCall', handleAnswerCall);
  CallKeep.addEventListener('endCall', handleEndCall);
}

// 收到VoIP推送后,调用这个方法弹出来电界面
async function showIncomingCall(callId, callerName) {
  await CallKeep.displayIncomingCall(callId, callerName, callerName, 'video');
}

// 注册VoIP推送令牌,发给服务端用来推送来电
async function registerVoipToken() {
  const token = await Notifications.getExpoPushTokenAsync({ type: 'voip' });
  // 把token传给你的服务端存起来
}

3. Android平台关键配置

  • 前台服务与后台保活:Android系统杀后台狠,光靠CallKeep不够,配合expo-task-manager和expo-background-fetch做个心跳任务,维持和服务端的连接:
import * as TaskManager from 'expo-task-manager';
import * as BackgroundFetch from 'expo-background-fetch';

const BACKGROUND_TASK_NAME = 'webrtc-keep-alive';

// 定义后台任务,发心跳包
TaskManager.defineTask(BACKGROUND_TASK_NAME, async () => {
  // 这里写发送心跳到服务端的逻辑
  return BackgroundFetch.Result.NewData;
});

// 注册后台任务
async function registerBackgroundTask() {
  await BackgroundFetch.registerTaskAsync(BACKGROUND_TASK_NAME, {
    minimumInterval: 15, // 每15分钟触发一次,按需调整
    stopOnTerminate: false,
    startOnBoot: true,
  });
}
  • 高优先级推送:Android上要用FCM的高优先级推送,确保App在后台能收到来电通知,收到后调用CallKeep.displayIncomingCall就能弹出系统级来电界面。

4. EAS Build必看提醒

  • 绝对不能用Expo Go测试,必须用EAS Build生成自定义开发客户端或者正式包,Expo Go不支持CallKeep和VoIP推送。
  • iOS要确保推送证书已经上传到Expo后台,eas.json里的profile配置正确(比如ad-hoc或app-store分发);Android release包要确认权限都被正确授予。

二、CallKeep替代方案

要是折腾半天还是不行,试试这两个选项:

  • react-native-incall-manager:主打通话状态管理,配合本地通知实现后台来电提醒,缺点是要自己写来电界面,优点是自定义空间大。
  • expo-notifications + 自定义弹窗:后台收到推送时发高优先级通知,点击通知直接唤醒App进入通话界面,实现简单,但没有系统原生来电界面的体验好。

内容的提问来源于stack exchange,提问作者Johndev247

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:19:56