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

React Native Android11后台FCM推送触发CallKeep来电显示失败求助

React Native + Firebase FCM + CallKeep 安卓11无头模式来电显示问题解决方案

针对安卓11设备应用处于静默/关闭状态时,FCM后台消息无法触发CallKeep来电界面的问题,以下是具体解决步骤:

1. 提前初始化CallKeep,确保无头环境可用

你当前在权限页面才初始化CallKeep的方式不可行——应用处于无头模式时不会走到权限页面,导致CallKeep未初始化,调用相关方法自然无效。需要在App启动最早期完成初始化:

// index.js 最顶部执行
import RNCallKeep from 'react-native-callkeep';

const setupCallKeep = () => {
  const callKeepOptions = {
    ios: { appName: '你的应用名称' },
    android: {
      alertTitle: '权限申请',
      alertDescription: '需要电话权限以显示来电界面',
      okButton: '允许',
      cancelButton: '取消'
    }
  };
  
  // 初始化CallKeep核心服务
  RNCallKeep.setup(callKeepOptions);
  
  // 主动申请必要权限
  RNCallKeep.requestPermissions().catch(err => {
    console.error('CallKeep权限申请失败:', err);
  });
};

// 立即执行初始化
setupCallKeep();

2. 适配安卓11后台限制,保持进程活跃

安卓11对后台进程管控严格,需在后台消息处理中添加唤醒锁,避免进程被系统杀死:

messaging().setBackgroundMessageHandler(async (remoteMessage) => {
  const callId = remoteMessage.data.callId || Date.now().toString();
  
  try {
    // 获取唤醒锁,保持进程活跃
    await RNCallKeep.acquireWakeLock();
    
    // 触发来电界面显示
    await RNCallKeep.displayIncomingCall(
      callId,
      remoteMessage.data.phoneNumber || "123",
      remoteMessage.data.name || "shb",
      "number",
      false,
      { supportsDTMF: true, supportsHolding: true }
    );
    
    // 尝试唤起应用到前台
    RNCallKeep.backToForeground();
    
    // 10秒后释放唤醒锁,避免过度耗电
    setTimeout(() => {
      RNCallKeep.releaseWakeLock();
    }, 10000);
  } catch (err) {
    console.error('后台来电处理失败:', err);
  }
});

3. 配置FCM推送的高优先级参数

FCM推送必须设置为高优先级,否则安卓11会延迟甚至丢弃后台消息,payload示例:

{
  "to": "设备推送令牌",
  "priority": "high",
  "content_available": true,
  "data": {
    "callId": "唯一通话ID",
    "phoneNumber": "123",
    "name": "shb"
  }
}

4. 补充安卓Manifest配置与权限

需要在AndroidManifest.xml中添加必要权限与CallKeep服务配置:

<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- 安卓13+ -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application ...>
  <!-- CallKeep核心服务 -->
  <service 
    android:name="io.wazo.callkeep.VoiceConnectionService" 
    android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
    <intent-filter>
      <action android:name="android.telecom.ConnectionService" />
    </intent-filter>
  </service>
  
  <!-- 通话状态广播接收器 -->
  <receiver 
    android:name="io.wazo.callkeep.CallKeepBroadcastReceiver" 
    android:exported="true">
    <intent-filter>
      <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
  </receiver>
</application>

5. 引导用户开启系统权限

安卓11+默认禁用后台弹出界面与悬浮窗权限,需在应用内引导用户手动开启:

import { Linking, Platform } from 'react-native';

const openAppSettings = () => {
  if (Platform.OS === 'android') {
    Linking.openSettings();
  }
};

在应用首次启动或权限申请失败时,调用该方法跳转到系统设置页面,提示用户开启「后台弹出界面」和「显示悬浮窗」权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:45:33