Skip to main content
Nimaz provides comprehensive notification settings for prayer times, including customizable adhan sounds, per-prayer toggles, pre-prayer reminders, and battery optimization guidance.

Notification settings

Global notification toggle

Users can enable or disable all prayer notifications with a master switch:
PreferencesDataStore.kt:289-297
val prayerNotificationsEnabled: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.PRAYER_NOTIFICATIONS_ENABLED] ?: true
}

suspend fun setPrayerNotificationsEnabled(enabled: Boolean) {
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.PRAYER_NOTIFICATIONS_ENABLED] = enabled
    }
}

Per-prayer notifications

Each of the five daily prayers plus sunrise can be individually enabled or disabled:
  • Fajr - Enabled by default
  • Sunrise - Disabled by default (optional alert)
  • Dhuhr - Enabled by default
  • Asr - Enabled by default
  • Maghrib - Enabled by default
  • Isha - Enabled by default
PreferencesDataStore.kt:317-337
val fajrNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.FAJR_NOTIFICATION_ENABLED] ?: true }
val sunriseNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.SUNRISE_NOTIFICATION_ENABLED] ?: false }
val dhuhrNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.DHUHR_NOTIFICATION_ENABLED] ?: true }
val asrNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.ASR_NOTIFICATION_ENABLED] ?: true }
val maghribNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.MAGHRIB_NOTIFICATION_ENABLED] ?: true }
val ishaNotificationEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.ISHA_NOTIFICATION_ENABLED] ?: true }

suspend fun setPrayerNotificationEnabled(prayer: String, enabled: Boolean) {
    dataStore.edit { prefs ->
        val key = when (prayer.lowercase()) {
            "fajr" -> PreferencesKeys.FAJR_NOTIFICATION_ENABLED
            "sunrise" -> PreferencesKeys.SUNRISE_NOTIFICATION_ENABLED
            "dhuhr" -> PreferencesKeys.DHUHR_NOTIFICATION_ENABLED
            "asr" -> PreferencesKeys.ASR_NOTIFICATION_ENABLED
            "maghrib" -> PreferencesKeys.MAGHRIB_NOTIFICATION_ENABLED
            "isha" -> PreferencesKeys.ISHA_NOTIFICATION_ENABLED
            else -> return@edit
        }
        prefs[key] = enabled
    }
}

Adhan sounds

Global adhan toggle

Users can enable full adhan playback for prayer notifications:
PreferencesDataStore.kt:299-307
val adhanEnabled: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.ADHAN_ENABLED] ?: false
}

suspend fun setAdhanEnabled(enabled: Boolean) {
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.ADHAN_ENABLED] = enabled
    }
}
Adhan is disabled by default to respect user preferences and privacy.

Available muezzins

Nimaz offers multiple adhan recordings from renowned muezzins:
AdhanSound.kt:15-50
enum class AdhanSound(
    val displayName: String,
    val origin: String,
    val fileName: String,
    val fajrFileName: String,
    val downloadUrl: String,
    val fajrDownloadUrl: String
) {
    MISHARY(
        displayName = "Mishary Rashid Alafasy",
        origin = "Kuwait",
        fileName = "adhan_mishary.mp3",
        fajrFileName = "adhan_mishary_fajr.mp3",
        downloadUrl = "https://archive.org/download/AdhanMisharyRashid/Adhan%20Mishary%20Rashid.mp3",
        fajrDownloadUrl = "https://archive.org/download/AdhanFajrAndDuaBySyeikhMisharyRashidAlAfasy/..."
    ),
    ABDUL_BASIT(
        displayName = "Abdul Basit Abdul Samad",
        origin = "Egypt",
        // ...
    ),
    MAKKAH(
        displayName = "Makkah (Masjid al-Haram)",
        origin = "Saudi Arabia",
        // ...
    ),
    SIMPLE_BEEP(
        displayName = "Simple Beep",
        origin = "System sound",
        // ...
    )
}
Fajr adhan includes the additional phrase “الصلاة خير من النوم” (Prayer is better than sleep).

Per-prayer adhan control

Each prayer can have adhan individually toggled, even when global adhan is enabled:
PreferencesDataStore.kt:340-358
val fajrAdhanEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.FAJR_ADHAN_ENABLED] ?: true }
val dhuhrAdhanEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.DHUHR_ADHAN_ENABLED] ?: true }
val asrAdhanEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.ASR_ADHAN_ENABLED] ?: true }
val maghribAdhanEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.MAGHRIB_ADHAN_ENABLED] ?: true }
val ishaAdhanEnabled: Flow<Boolean> = dataStore.data.map { it[PreferencesKeys.ISHA_ADHAN_ENABLED] ?: true }

suspend fun setPrayerAdhanEnabled(prayer: String, enabled: Boolean) {
    dataStore.edit { prefs ->
        val key = when (prayer.lowercase()) {
            "fajr" -> PreferencesKeys.FAJR_ADHAN_ENABLED
            "dhuhr" -> PreferencesKeys.DHUHR_ADHAN_ENABLED
            "asr" -> PreferencesKeys.ASR_ADHAN_ENABLED
            "maghrib" -> PreferencesKeys.MAGHRIB_ADHAN_ENABLED
            "isha" -> PreferencesKeys.ISHA_ADHAN_ENABLED
            else -> return@edit
        }
        prefs[key] = enabled
    }
}
Sunrise always uses a simple beep and never plays full adhan.

Additional alerts

Pre-prayer reminders

Users can enable notifications before prayer time:
PreferencesDataStore.kt:392-406
val notificationReminderMinutes: Flow<Int> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.NOTIFICATION_REMINDER_MINUTES] ?: 15
}

val showReminderBefore: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.SHOW_REMINDER_BEFORE] ?: true
}
The default reminder is 15 minutes before prayer time and is enabled by default.

Notification behavior

Additional notification settings include:
  • Vibration - Vibrate on prayer notifications (default: enabled)
  • Respect Do Not Disturb - Honor system DND mode for adhan playback (default: enabled)
  • Persistent notification - Show ongoing notification (default: disabled)
PreferencesDataStore.kt:376-390
val adhanRespectDnd: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.ADHAN_RESPECT_DND] ?: true
}

val notificationVibration: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.NOTIFICATION_VIBRATION] ?: true
}

val persistentNotification: Flow<Boolean> = dataStore.data.map { preferences ->
    preferences[PreferencesKeys.PERSISTENT_NOTIFICATION] ?: false
}

Notification scheduling

The PrayerNotificationScheduler handles all notification timing using Android’s AlarmManager:
PrayerNotificationScheduler.kt:107-175
fun scheduleTodaysPrayerNotifications(
    latitude: Double,
    longitude: Double,
    notificationsEnabled: Boolean,
    enabledPrayers: Set<PrayerType>? = null,
    preReminderEnabled: Boolean = false,
    preReminderMinutes: Int = 15,
    calculationMethod: CalculationMethod = CalculationMethod.MUSLIM_WORLD_LEAGUE,
    asrCalculation: AsrCalculation = AsrCalculation.STANDARD,
    highLatitudeRule: HighLatitudeRule? = null,
    adjustments: Map<PrayerType, Int> = emptyMap()
)
Notifications are automatically rescheduled:
  • At device boot via BootReceiver
  • At midnight for the next day’s prayers
  • When settings change
Use the “Test Notification” and “Test All Notifications” buttons in settings to verify notification permissions and scheduling.

Battery optimization

The notification settings screen includes guidance for disabling battery optimization to ensure reliable prayer notifications:
NotificationSettingsScreen.kt:454-513
val powerManager = context.getSystemService(android.content.Context.POWER_SERVICE) as PowerManager
val isExempted = powerManager.isIgnoringBatteryOptimizations(context.packageName)

// Shows warning banner and button to open battery settings if not exempted
This ensures the app can wake the device for prayer notifications even in Doze mode.

Build docs developers (and LLMs) love