Skip to content

fayyaztech/dialer-core

Repository files navigation

Dialer Core

License API

A reusable Android library module that provides core telephony/dialer functionality for building custom dialer applications.

Overview

dialer-core handles all the complex Android Telecom framework integration, call management, and in-call UI, allowing you to focus on building custom contacts, call history, and dialpad screens for your dialer app. This module is designed to make it incredibly easy to build professional dialer applications with minimal effort.

Roadmap πŸš€

  • Flutter implementation (Planned)

What's Included

  • βœ… Complete InCallService implementation with Android 12+ CallStyle
  • βœ… Modern Jetpack Compose in-call UI with Material3
  • βœ… Multi-call support (hold, swap with selection menu, merge fallback)
  • βœ… Audio routing (earpiece, speaker, bluetooth)
  • βœ… Call screening framework
  • βœ… Lock screen support with full-screen incoming call UI
  • βœ… DTMF keypad for tone dialing
  • βœ… Proximity sensor integration
  • βœ… OEM compatibility workarounds

Quick Start

Installation

Add to your settings.gradle.kts:

include(":dialer-core")

Add dependency in app/build.gradle.kts:

dependencies {
    implementation(project(":dialer-core"))
}

Basic Setup

  1. Request Default Dialer Role:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    val roleManager = getSystemService(RoleManager::class.java)
    val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER)
    startActivityForResult(intent, REQUEST_CODE)
}
  1. Add Dialer Intent Filters to your MainActivity:
<intent-filter>
    <action android:name="android.intent.action.DIAL" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
  1. Make Calls:
val intent = Intent(Intent.ACTION_CALL, Uri.parse("tel:1234567890"))
startActivity(intent)

That's it! The module handles incoming calls, in-call UI, audio routing, and call management automatically.

Features

Call Management

  • Automatic incoming call detection and UI display
  • Full-screen lock screen notifications
  • Active call state management
  • Call audio routing (earpiece/speaker/bluetooth)
  • Microphone mute/unmute

Multi-Call Operations

  • Hold and resume calls
  • Swap between multiple calls with a selection menu
  • Intelligent merge/conference with automatic state recovery
  • "Add Call" with automatic focus and state management

In-Call UI

  • Beautiful Material3 Compose design
  • Real-time call duration timer
  • Contact name resolution
  • Interactive DTMF keypad
  • Audio route selector (phone/speaker/bluetooth)
  • Visual call state indicators

Services

  • DefaultInCallService - Core Telecom integration
  • CallScreeningService - Spam detection framework
  • CallStateObserverService - Background monitoring
  • CallActionReceiver - Notification actions
  • IncomingCallReceiver - Phone state handling

Architecture

YourDialerApp/
β”œβ”€β”€ app/                          # Your custom UI
β”‚   β”œβ”€β”€ MainActivity.kt          # Tabs, navigation
β”‚   β”œβ”€β”€ ui/
β”‚   β”‚   β”œβ”€β”€ dialpad/            # Custom dialpad
β”‚   β”‚   β”œβ”€β”€ contacts/           # Contact list
β”‚   β”‚   └── history/            # Call history
β”‚   └── data/                   # ViewModels, repos
β”‚
└── dialer-core/                 # This module
    β”œβ”€β”€ services/
    β”‚   β”œβ”€β”€ DefaultInCallService.kt
    β”‚   β”œβ”€β”€ CallScreeningService.kt
    β”‚   └── ...
    └── ui/
        └── call/
            └── CallScreenActivity.kt  # In-call screen

Requirements

  • Min SDK: 24 (Android 7.0)
  • Target SDK: 36 (Android 15+)
  • Kotlin: 1.9+
  • Compose: BOM 2024.01.00+

Documentation

Customization

Custom Theme

import com.fayyaztech.dialer_core.ui.theme.DefaultDialerTheme

// Use your own theme instead
YourCustomTheme {
    // Your app content
}

Extend Services

class CustomInCallService : DefaultInCallService() {
    override fun onCallAdded(call: Call?) {
        super.onCallAdded(call)
        // Your custom logic
    }
}

Permissions

All required permissions are declared in the module manifest and automatically merged:

  • CALL_PHONE, READ_PHONE_STATE, READ_CALL_LOG, WRITE_CALL_LOG
  • READ_CONTACTS, ANSWER_PHONE_CALLS, RECORD_AUDIO
  • FOREGROUND_SERVICE, POST_NOTIFICATIONS

You must still request runtime permissions in your app for Android 6.0+.

API Reference

DefaultInCallService

// Access current call
DefaultInCallService.currentCall: Call?

// Control audio
DefaultInCallService.muteCall(isMuted: Boolean)
DefaultInCallService.setSpeaker(enable: Boolean)

// Multi-call info
DefaultInCallService.getActiveCallCount(): Int
DefaultInCallService.getAllCalls(): List<Call>

Testing

Emulator

# Simulate incoming call
adb emu gsm call 5551234567

# Simulate call end
adb emu gsm cancel 5551234567

Testing Checklist

  • Make outgoing call
  • Receive incoming call
  • Answer from lock screen
  • Hold/resume
  • Mute/unmute
  • Switch audio routes
  • Multi-call operations
  • DTMF tones

Building

./gradlew :dialer-core:assemble
./gradlew :dialer-core:test

Contributing

Contributions welcome! Please submit PRs with:

  • Clear description
  • Tests for new features
  • Documentation updates

License

Copyright 2025 Fayyaz Tech

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

See LICENSE for full details.

Support

Related Projects


Made with ❀️ by FayyazTech

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages