Skip to content

Ikolvi/callbundle

Repository files navigation

CallBundle

pub package License: MIT Flutter

Native incoming & outgoing call UI for Flutter.

CallBundle provides CallKit on iOS and TelecomManager + OEM-adaptive notifications on Android — as a single, reliable federated plugin.

Built by Ikolvi.


Why CallBundle?

Existing call plugins suffer from silent event drops, cold-start failures, and OEM incompatibilities. CallBundle was built from scratch to solve these problems:

Problem CallBundle Solution
EventChannel accept events silently dropped MethodChannel for ALL communication
3 parallel accept-detection paths Single reliable MethodChannel path
Budget OEM notifications silently fail Built-in OEM-adaptive notification strategy
Cold-start 3-second hardcoded delay Deterministic PendingCallStore handshake
iOS audio session conflict with HMS AudioSessionManager with .mixWithOthers
16 ProGuard keep rules in app Consumer ProGuard rules shipped in plugin
437-line fallback plugin in app code Built-in AdaptiveCallNotification
_isEndingCallKitProgrammatically flag isUserInitiated field on every event

Platform Support

Feature iOS Android
Native incoming call UI CallKit TelecomManager + Notification
Native outgoing call UI CallKit Notification
VoIP push token management PushKit
Cold-start call acceptance UserDefaults SharedPreferences
OEM-adaptive notifications 18+ manufacturers detected
Missed call notifications UNNotification NotificationCompat
Audio session management AVAudioSession
Caller avatar support Missed call notifications Incoming call UI + notifications
Consumer ProGuard rules Built-in
Background isolate support BinaryMessenger

Quick Start

Installation

dependencies:
  callbundle: ^1.0.0

The Android and iOS platform packages are endorsed — they are automatically included. No additional dependency lines needed.

Usage

import 'package:callbundle/callbundle.dart';

// 1. Configure
await CallBundle.configure(NativeCallConfig(
  appName: 'MyApp',
  android: AndroidCallConfig(phoneAccountLabel: 'MyApp Calls'),
  ios: IosCallConfig(supportsVideo: false, includesCallsInRecents: true),
));

// 2. Listen for events
CallBundle.onEvent.listen((event) {
  switch (event.type) {
    case NativeCallEventType.accepted:
      print('Call accepted: ${event.callId}');
    case NativeCallEventType.declined:
      print('Call declined: ${event.callId}');
    case NativeCallEventType.ended:
      print('Call ended: ${event.callId}');
    default:
      break;
  }
});

// 3. Show incoming call
await CallBundle.showIncomingCall(NativeCallParams(
  callId: 'unique-call-id',
  callerName: 'John Doe',
  handle: '+1 234 567 8900',
  callType: NativeCallType.voice,
  callerAvatar: 'https://example.com/photos/john.jpg',
  android: const AndroidCallParams(),
  ios: const IosCallParams(),
));

// 4. End call
await CallBundle.endCall('unique-call-id');

See the full implementation guide for permissions, FCM integration, cold-start handling, and advanced usage.


Documentation

Document Description
Implementation Guide Full setup, API reference, permissions, FCM, cold-start
Platform Interface Abstract API contract and data models
Android Implementation TelecomManager, notifications, OEM detection
iOS Implementation CallKit, PushKit, audio session management
Example App Working demo with all features

Architecture

┌─────────────────────────────────┐
│         Your Flutter App        │
│   import 'callbundle.dart'      │
└──────────────┬──────────────────┘
               │
┌──────────────▼──────────────────┐
│      callbundle (app-facing)    │
│   Static CallBundle API class   │
└──────────────┬──────────────────┘
               │
┌──────────────▼──────────────────┐
│  callbundle_platform_interface  │
│  Abstract API + Models + Enums  │
└──────┬──────────────────┬───────┘
       │                  │
┌──────▼──────┐   ┌───────▼──────┐
│  callbundle │   │  callbundle  │
│  _android   │   │     _ios     │
│  (Kotlin)   │   │   (Swift)    │
└─────────────┘   └──────────────┘

All communication uses MethodChannel (com.callbundle/main) in both directions. No EventChannel, no WeakReference.


Requirements

Platform Minimum
Flutter 3.10+
Dart SDK 3.0+
iOS 13.0+
Android API 21 (Android 5.0)
Kotlin 1.9+
Swift 5.0+

Development

This project uses Melos for monorepo management and FVM for Flutter version management.

# Bootstrap all packages
melos bootstrap

# Run analysis across all packages
melos run analyze

# Run tests across all packages
melos run test

# Run tests for a specific package
cd callbundle && fvm flutter test
cd callbundle_android && fvm flutter test
cd callbundle_ios && fvm flutter test

# Build example app
cd example && fvm flutter build apk --debug    # Android
cd example && fvm flutter build ios --no-codesign  # iOS

License

MIT License — see LICENSE for details.

Built with reliability in mind by Ikolvi.

About

Call bundle package for flutter

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors