A reusable Android library module that provides core telephony/dialer functionality for building custom dialer applications.
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.
- Flutter implementation (Planned)
- β
Complete
InCallServiceimplementation 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
Add to your settings.gradle.kts:
include(":dialer-core")Add dependency in app/build.gradle.kts:
dependencies {
implementation(project(":dialer-core"))
}- 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)
}- 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>- 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.
- 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
- 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
- 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
DefaultInCallService- Core Telecom integrationCallScreeningService- Spam detection frameworkCallStateObserverService- Background monitoringCallActionReceiver- Notification actionsIncomingCallReceiver- Phone state handling
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
- Min SDK: 24 (Android 7.0)
- Target SDK: 36 (Android 15+)
- Kotlin: 1.9+
- Compose: BOM 2024.01.00+
import com.fayyaztech.dialer_core.ui.theme.DefaultDialerTheme
// Use your own theme instead
YourCustomTheme {
// Your app content
}class CustomInCallService : DefaultInCallService() {
override fun onCallAdded(call: Call?) {
super.onCallAdded(call)
// Your custom logic
}
}All required permissions are declared in the module manifest and automatically merged:
CALL_PHONE,READ_PHONE_STATE,READ_CALL_LOG,WRITE_CALL_LOGREAD_CONTACTS,ANSWER_PHONE_CALLS,RECORD_AUDIOFOREGROUND_SERVICE,POST_NOTIFICATIONS
You must still request runtime permissions in your app for Android 6.0+.
// 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># Simulate incoming call
adb emu gsm call 5551234567
# Simulate call end
adb emu gsm cancel 5551234567- Make outgoing call
- Receive incoming call
- Answer from lock screen
- Hold/resume
- Mute/unmute
- Switch audio routes
- Multi-call operations
- DTMF tones
./gradlew :dialer-core:assemble
./gradlew :dialer-core:testContributions welcome! Please submit PRs with:
- Clear description
- Tests for new features
- Documentation updates
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.
- Github: fayyaztech
- Issues: GitHub Issues
- Email: support@fayyaztech.com
- DefaultDialer - Example implementation
Made with β€οΈ by FayyazTech