
Observes whether device is on an active voice call, exposing a reactive callState stream; monitoring runs only while collectors are active. Best-effort VoIP detection; runtime permission may be needed.
Kotlin Multiplatform library that observes whether the device is on an active voice call (Android and iOS). Monitoring runs only while a collector is active on callState().
Maven: io.github.nsi-cyber:callstate
Latest: 1.0.0 on Maven Central
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.nsi-cyber:callstate:1.0.0")
}import io.github.nsicyber.callstate.CallState
import io.github.nsicyber.callstate.createCallMonitor
createCallMonitor(platformContext).callState().collect { state ->
when (state) {
CallState.OnCall -> { /* ... */ }
CallState.NotOnCall -> { /* ... */ }
}
}Android — pass applicationContext (or any Context). Request READ_PHONE_STATE at runtime for reliable telephony signals. The library merges the permission in its manifest; your app must still request it.
iOS — no context required:
createCallMonitor(null).callState().collect { /* ... */ }Cancel the coroutine scope (or stop collecting) to unregister listeners.
Detection is best effort, especially for third-party VoIP.
| Platform | Works well | Often missed |
|---|---|---|
| Android | Cellular; many calls via TelecomManager (API 31+) |
VoIP outside Telecom; no permission → always NotOnCall
|
| iOS | CallKit-visible calls (CXCallObserver) |
Non–CallKit VoIP; limited Simulator testing |
./gradlew :library:testAndroidHostTest
./gradlew :library:iosSimulatorArm64Test # macOS + XcodeReleases are published to Maven Central via GitHub Actions (.github/workflows/publish.yml) on GitHub Release or manual workflow dispatch.
Kotlin Multiplatform library that observes whether the device is on an active voice call (Android and iOS). Monitoring runs only while a collector is active on callState().
Maven: io.github.nsi-cyber:callstate
Latest: 1.0.0 on Maven Central
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.nsi-cyber:callstate:1.0.0")
}import io.github.nsicyber.callstate.CallState
import io.github.nsicyber.callstate.createCallMonitor
createCallMonitor(platformContext).callState().collect { state ->
when (state) {
CallState.OnCall -> { /* ... */ }
CallState.NotOnCall -> { /* ... */ }
}
}Android — pass applicationContext (or any Context). Request READ_PHONE_STATE at runtime for reliable telephony signals. The library merges the permission in its manifest; your app must still request it.
iOS — no context required:
createCallMonitor(null).callState().collect { /* ... */ }Cancel the coroutine scope (or stop collecting) to unregister listeners.
Detection is best effort, especially for third-party VoIP.
| Platform | Works well | Often missed |
|---|---|---|
| Android | Cellular; many calls via TelecomManager (API 31+) |
VoIP outside Telecom; no permission → always NotOnCall
|
| iOS | CallKit-visible calls (CXCallObserver) |
Non–CallKit VoIP; limited Simulator testing |
./gradlew :library:testAndroidHostTest
./gradlew :library:iosSimulatorArm64Test # macOS + XcodeReleases are published to Maven Central via GitHub Actions (.github/workflows/publish.yml) on GitHub Release or manual workflow dispatch.