---
title: "Android FCM + ConnectionService for AI Inbound Calls (2026)"
description: "FCM high-priority + Telecom CallsManager is the Android equivalent of PushKit + CallKit for AI voice. Here is how to ship it without losing future push priority."
canonical: https://callsphere.ai/blog/vw4e-android-fcm-connectionservice-ai-inbound-2026
category: "AI Voice Agents"
tags: ["Android", "FCM", "ConnectionService", "Voice AI", "Push"]
author: "CallSphere Team"
published: 2026-03-21T00:00:00.000Z
updated: 2026-05-07T16:13:34.188Z
---

# Android FCM + ConnectionService for AI Inbound Calls (2026)

> FCM high-priority + Telecom CallsManager is the Android equivalent of PushKit + CallKit for AI voice. Here is how to ship it without losing future push priority.

> Android does not have a separate VoIP push channel. You use FCM with high-priority on a data message, and you have a few seconds to show an incoming-call UI through the Telecom framework — or Android deprioritizes your next push.

## Background

Firebase Cloud Messaging is the universal push channel on Android. For AI voice agents in 2026, the recipe is: send a high-priority data message, receive it in a service even from Doze, and immediately register an incoming call with the Telecom framework's CallsManager (or legacy ConnectionService for older devices). If you fail to show a UI, FCM will quietly throttle your next high-priority delivery — Google's quota system penalizes apps that abuse the priority lane.

The good news: with Core-Telecom CallsManager (Jetpack, alpha 2023, stable across 2024–2026), the boilerplate is now manageable. The bad news: every OEM (Samsung, Xiaomi, OPPO, Huawei) layers extra battery-optimization on top of stock Android, and you must convince users to whitelist your app or they will miss calls.

## Architecture

```mermaid
flowchart LR
  Backend[Voice Agent Backend] -- HTTP v1 API --> FCM[(Firebase FCM)]
  FCM -- high-priority data --> Device[Android Device]
  Device -- onMessageReceived --> Service[Foreground Service]
  Service -- addCall --> CallsManager[Core-Telecom CallsManager]
  CallsManager -- CallControlScope --> WebRTC[WebRTC PeerConnection]
  WebRTC -- SRTP --> Gateway[Pion Go gateway 1.23]
```

## CallSphere implementation

The Android client across CallSphere's six verticals (real estate, healthcare, behavioral health, legal, salon, insurance) follows the same pattern:

- **Real Estate (OneRoof)** — High-priority FCM wakes the app, CallsManager surfaces the incoming UI, WebRTC peers the Pion Go gateway 1.23. NATS routes to the 6-container pod (CRM, MLS, calendar, SMS, audit, transcript). See [/industries/real-estate](/industries/real-estate).
- **Healthcare** — Same FCM + Telecom + WebRTC stack with HIPAA-safe opaque IDs. See [/industries/healthcare](/industries/healthcare).
- **/demo browser path** — Skip FCM entirely; runs in Chrome. See [/demo](/demo).

37 agents · 90+ tools · 115+ DB tables · 6 verticals · HIPAA + SOC 2 · $149/$499/$1499 · 14-day [/trial](/trial) · 22% affiliate at [/affiliate](/affiliate).

## Build steps with code

```kotlin
class VoiceMessagingService : FirebaseMessagingService() {
  override fun onMessageReceived(message: RemoteMessage) {
    val callId = message.data["call_id"] ?: return
    val from = message.data["from"] ?: "AI Agent"

```
// Start a foreground service so we have time to attach to Telecom
val intent = Intent(this, IncomingCallService::class.java).apply {
  putExtra("call_id", callId); putExtra("from", from)
}
ContextCompat.startForegroundService(this, intent)
```

}
}

class IncomingCallService : Service() {
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    startForeground(NOTIF_ID, buildPlaceholderNotification(),
      ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL)

```
val callsManager = CallsManager(this)
val attrs = CallAttributesCompat(
  displayName = intent?.getStringExtra("from") ?: "AI Agent",
  address = Uri.parse("voice:agent"),
  direction = CallAttributesCompat.DIRECTION_INCOMING,
  callType = CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
)
CoroutineScope(Dispatchers.Main).launch {
  callsManager.addCall(attrs,
    onAnswer = { startWebRTC() },
    onDisconnect = { stopSelf() })
}
return START_NOT_STICKY
```

}
}
```

```xml

\`\`\`

Backend: use the FCM HTTP v1 API with `"priority": "high"` and a `data` payload (no `notification` block — that one goes through display channels and gets coalesced).

## Pitfalls

- **Sending notification payloads instead of data payloads** — display payloads cannot wake a Doze-mode app; only data payloads can.
- **Skipping the phoneCall foreground service type** — Android 14+ rejects the service start.
- **Failing to show a call UI within seconds** — Google's FCM throttles future high-priority deliveries.
- **Battery optimizations from OEMs** — Samsung's "Sleeping Apps" list silently kills FCM; you must guide users to whitelist.
- **Forgetting MANAGE_OWN_CALLS permission** — CallsManager addCall throws.

## FAQ

**Why not a regular notification?** Notification payloads are deprioritized in Doze; only high-priority data messages wake the app.

**How fast is FCM?** P50 around 250 ms in 2026; p99 around 2 s on poor networks.

**Does it work on devices without Google Services?** Push HMS for Huawei or Mi Push for Xiaomi-only markets; the Telecom side is identical.

**What if the user is in Do Not Disturb?** Telecom respects DND; CallsManager surfaces the UI but mutes the ringtone.

**Are call audio routes managed automatically?** Yes — CallsManager sets MODE_IN_COMMUNICATION and routes to Bluetooth SCO if connected.

## Sources

- [https://firebase.google.com/docs/cloud-messaging/concept-options](https://firebase.google.com/docs/cloud-messaging/concept-options)
- [https://developer.android.com/develop/connectivity/telecom/voip-app/telecom](https://developer.android.com/develop/connectivity/telecom/voip-app/telecom)
- [https://github.com/react-native-webrtc/react-native-callkeep](https://github.com/react-native-webrtc/react-native-callkeep)
- [https://developer.android.com/develop/background-work/services/foreground-services](https://developer.android.com/develop/background-work/services/foreground-services)
- [https://www.twilio.com/docs/voice/sdks/android/faq](https://www.twilio.com/docs/voice/sdks/android/faq)

Try the Android client at [/demo](/demo), browse plans at [/pricing](/pricing), or start a [/trial](/trial).

---

Source: https://callsphere.ai/blog/vw4e-android-fcm-connectionservice-ai-inbound-2026
