Alarmee
A Kotlin/Compose Multiplatform library to schedule alarms, display local notifications, and handle push notifications on Android and iOS.
Install / Use
/learn @Tweener/AlarmeeREADME
Alarmee
Alarmee is a Kotlin/Compose Multiplatform library designed to simplify scheduling alarms and notifications on both Android and iOS platforms. With Alarmee, you can schedule one-time or repeating alarms, display platform-specific notifications, and now supports push notifications using Firebase Cloud Messaging (Android) and Apple Push Notification service (iOS).
<br>[!WARNING] Upgrading from v1.x?
Check out the Migration Guide to update your code for version 2.0.
Be sure to show your support by starring ⭐️ this repository, and feel free to contribute if you're interested!
🌟 Features
- 📅 One-off alarm: Schedule an alarm to trigger at a specific date and time.
- 🔁 Repeating alarm: Schedule recurring alarms with intervals: hourly, daily, weekly, monthly, yearly or custom (providing a duration).
- ⚡️ Instant notifications: Send notifications immediately without scheduling them.
- ☁️ Push notifications: Handle remote notifications via FCM/APNs.
- 🔘 Action buttons: Add interactive action buttons to notifications (Android & iOS).
- 🎨 Extensible Configuration: Customize alarms and notifications with platform-specific settings.
🚀 Used in production
Alarmee powers notifications in real-world apps:
- KMPShip: a Kotlin Multiplatform boilerplate / starter-kit to build mobile apps faster.
- Snappit: a daily video journaling app.
- Bloomeo: a personal finance app.
🛠️ Installation
- In your
settings.gradle.ktsfile, add Maven Central to your repositories:
repositories {
mavenCentral()
}
- Then add Alarmee dependency to your module.
- For local notifications only, use
alarmeedependency. - For both local and push notifications, use
alarmee-pushdependency.
Open libs.versions.toml:
[versions]
alarmee = "2.4.0" // Check latest version
[libraries]
alarmee = { group = "io.github.tweener", name = "alarmee", version.ref = "alarmee" } // For local notifications only
alarmee = { group = "io.github.tweener", name = "alarmee-push", version.ref = "alarmee" } // For both local & push notifications
Then in your module build.gradle.kts add:
dependencies {
// Only one of these is needed, depending on your use case
implementation(libs.alarmee)
implementation(libs.alarmee.push)
}
</details>
<details>
<summary>Without version catalog:</summary>
In your module build.gradle.kts add:
dependencies {
val alarmee_version = "2.4.0" // Check latest version
// Only one of these is needed, depending on your use case
implementation("io.github.tweener:alarmee:$alarmee_version") // For local notifications only
implementation("io.github.tweener:alarmee-push:$alarmee_version") // For both local & push notifications
}
</details>
🔧 Configuration
To get started with Alarmee, you need to provide a platform-specific configuration for Android and iOS. Follow these steps.
1. Declare an expect function in commonMain
In your commonMain source set, declare the following function to provide platform-specific configuration:
expect fun createAlarmeePlatformConfiguration(): AlarmeePlatformConfiguration
2. Provide the actual implementation in androidMain
In the androidMain source set, implement the actual function and return an AlarmeeAndroidPlatformConfiguration:
actual fun createAlarmeePlatformConfiguration(): AlarmeePlatformConfiguration =
AlarmeeAndroidPlatformConfiguration(
notificationIconResId = R.drawable.ic_notification,
notificationIconColor = androidx.compose.ui.graphics.Color.Red, // Defaults to Color.Transparent is not specified
useExactScheduling = true, // Enable exact alarm scheduling for more precise timing (Android 12+, requires SCHEDULE_EXACT_ALARM permission)
notificationChannels = listOf(
AlarmeeNotificationChannel(
id = "dailyNewsChannelId",
name = "Daily news notifications",
importance = NotificationManager.IMPORTANCE_HIGH,
soundFilename = "notifications_sound",
),
AlarmeeNotificationChannel(
id = "breakingNewsChannelId",
name = "Breaking news notifications",
importance = NotificationManager.IMPORTANCE_LOW,
),
// List all the notification channels you need here
)
)
3. Provide the actual implementation in iosMain
In the iosMain source set, implement the actual function and return an AlarmeeIosPlatformConfiguration:
val platformConfiguration: AlarmeePlatformConfiguration = AlarmeeIosPlatformConfiguration
4. Initialize AlarmeeService
There are multiple ways to initialize Alarmee depending on your setup.
✅ For all targets (Android, iOS, desktop, etc.)
With Compose:
val alarmService: AlarmeeService = rememberAlarmeeService(
platformConfiguration = createAlarmeePlatformConfiguration()
)
Without Compose:
val alarmeeService = createAlarmeeService()
alarmeeService.initialize(platformConfiguration = createAlarmeePlatformConfiguration())
📱 For mobile targets only (Android & iOS)
Alarmee also supports push notifications on mobile via Firebase (Android) or APNs (iOS). If you're already using Firebase in your app, you can pass your own Firebase instance to avoid initializing it twice.
With Compose:
- If you're not using Firebase yet:
val alarmService: MobileAlarmeeService = rememberAlarmeeMobileService(
platformConfiguration = createAlarmeePlatformConfiguration()
)
- If you're already using Firebase elsewhere in your app:
val alarmService: MobileAlarmeeService = rememberAlarmeeMobileService(
platformConfiguration = createAlarmeePlatformConfiguration(),
firebase = Firebase
)
Without Compose:
- If you're not using Firebase yet:
val alarmeeService = createAlarmeeMobileService()
alarmeeService.initialize(platformConfiguration = createAlarmeePlatformConfiguration())
- If you're already using Firebase:
val alarmeeService = createAlarmeeMobileService()
alarmeeService.initialize(
platformConfiguration = createAlarmeePlatformConfiguration(),
firebase = Firebase
)
You can then use this instance to schedule or cancel alarms from your shared code.
🧑💻 Usage
[!IMPORTANT] Before using Alarmee, make sure the Notifications permission is granted on the target platform (Android official documentation, iOS official documentation).
Alternativally, you can use
moko-permissionsto easily handle permissions for you.
After initializing AlarmeeService, you can access the notification services:
Local Notifications (all platforms)
To send local notifications, use the local service:
val localService = alarmService.local
localService.schedule(...) // For instance
This is available on all targets (Android, iOS, desktop, web, etc.).
Push Notifications (mobile only)
To access push notifications (e.g. Firebase):
val pushService = alarmService.push
This is only available on Android and iOS. On non-mobile targets, pushService will be null.
Local Notification Service
1. Scheduling a one-off alarm
You can schedule an alarm to be triggered at a specific time of the day, using AlarmeeService#schedule(...). When the alarm is triggered, a notification will be displayed.
For instance, to schedule an alarm on January 12th, 2025, at 5 PM:
localService.schedule(
alarmee = Alarmee(
uuid = "myAlarmId",
notificationTitle = "🎉 Congratulations! You've scheduled an Alarmee!",
notificationBody = "This is the notification that will be displayed at the specified date and time.",
scheduledDateTime = LocalDateTime(year = 2025, month = Month.JANUARY, dayOfMonth = 12, hour = 17, minute = 0),
deepLinkUri = "https://www.example.com", // A deep link URI to be retrieved in MainActivity#onNewIntent() on Android and in AppDelegate#userNotificationCenter()
