yshalsager/SuntimesPrayerTimesAddon
Prayer times, prohibited (makruh) windows, and night portions as a SuntimesWidget Android app addon.
Suntimes Prayer Times Addon
Prayer times, prohibited (makruh) windows, and night portions as a SuntimesWidget addon and Suntimes Calendars source.
This project intentionally avoids implementing astronomical algorithms: it delegates solar/shadow calculations to the installed SuntimesWidget app via its exported ContentProviders.
Caution
Disclaimer: This project was developed with heavy use of AI assistance. Most of the code was generated or edited with OpenAI's Codex 5.3 model.
Screenshots
| English | Arabic (RTL) |
|---|---|
|
Home (today timeline)
|
Home (خط اليوم)
|
|
Days (month cards)
|
Days (بطاقات الشهر)
|
|
Settings (Material 3)
|
Settings (الإعدادات)
|
What This App Does
- Shows a timeline on Home with infinite left/right day paging and a month/day-card list (Days/Calendar).
- Exposes events to SuntimesWidget Alarms:
- prayers (Fajr, Duha, Dhuhr/Jumu'ah, Asr, Maghrib, Isha)
- prohibited (makruh) boundaries and windows
- night portions (midpoint, last third, last sixth)
- Exposes three read-only calendars to Suntimes calendar clients:
prayersmakruhnight
- Tap a prayer/night item on Home to open the host alarm editor prefilled for that event (event-based alarms automatically track changing prayer times; offsets like +/-30m are supported by the host UI).
- Uses distinct makruh levels in UI (light: dawn/after-asr, heavy: sunrise/zawal/sunset) across timeline, calendar cards, and widget labels.
- Provides an Android home-screen widget ("Prayer Times (Today)") with the same day-card model.
- Provides app shortcuts for Days and Settings via
prayertimes://shortcuts/...deep links. - Supports English + Arabic and RTL.
- Supports theme mode (System/Light/Dark) + palette selection:
- Parchment / Sapphire / Rose
- Dynamic colors on Android 12+ (Compose + widget backgrounds/accent)
Requirements
- Android
minSdk 23(Marshmallow) - SuntimesWidget installed (stable/nightly/legacy supported)
- Host permissions granted (SuntimesWidget protects its providers with
suntimes.*.permission.*)
Architecture (Host Delegation)
The app is split into:
core/*: host discovery, provider contracts, event-id mapping, and small derived calculations (night portions, Hijri date)provider/*: addonContentProviderimplementations for alarms and calendar feedsui/*andui/compose/*: Compose UI (Home/Days/Settings/Event Picker)widget/*: RemoteViews widget and update scheduling
Data Flow
+-------------------+
| SuntimesWidget |
|-------------------|
| event.provider | content://<host>.event.provider/eventCalc/<eventId>
| calculator.provider| content://<host>.calculator.provider/sun/<millis>
+---------^---------+
|
| queries (delegation)
|
+---------------------+----------------------+
| PrayerTimesAddon (this app) |
|-------------------------------------------|
| UI (Compose) |
| - Home/Days/Settings/EventPicker |
| - mostly queries host providers directly |
| |
| Addon Provider (exported) |
| - content://...event.provider/eventCalc |
| - used by SuntimesWidget alarms |
| - also used by widget for eventCalc |
| |
| Calendar Provider (exported) |
| - content://...calendar.provider/... |
| - used by Suntimes calendar discovery |
| - exposes prayers/makruh/night feeds |
| |
| Widget (RemoteViews) |
| - reads prefs + provider results |
+-------------------------------------------+
“No Reinvention” Policy
We treat the host app as the source of truth for all solar/shadow events:
- Prayer times are resolved by translating settings into host event ids and asking the host to compute
eventCalc/<eventId>. - Calculator provider is used for "bulk" sun times (noon/sunrise/sunset) to reduce query volume and to support past-day computations.
The only non-host math intentionally left is a compatibility fallback for Asr when the host does not expose a shadow-ratio event:
- It uses host declination + latitude to translate the juristic factor into an equivalent sun-elevation event id, then still delegates the final time lookup back to the host.
Host Integration (Addon Contracts)
Suntimes discovers this app through two exported addon surfaces:
- alarm/event discovery via
suntimes.action.ADDON_EVENT - calendar discovery via
suntimes.action.ADD_CALENDAR
This project provides:
AddonRegistrationActivity(discovery stub)PrayerTimesProvider(exported) implementing the same event-provider contract SuntimesWidget expectsEventPickerActivityforsuntimes.action.PICK_EVENTCalendarDiscoveryAliasfor Suntimes calendar discoveryPrayerTimesCalendarProvider(exported) exposing prayer/makruh/night calendars
Authorities and internal app actions are derived from ${applicationId}, so debug and release variants can be installed side by side without authority/action collisions.
Event Provider
Authority:
${applicationId}.event.provider
Paths:
content://.../eventTypescontent://.../eventInfo/<eventId>content://.../eventCalc/<eventId>
Calendar Provider
Authority:
${applicationId}.calendar.provider
Discovery references:
content://.../calendar.provider/prayers/content://.../calendar.provider/makruh/content://.../calendar.provider/night/
Supported paths:
content://.../<source>/calendarInfocontent://.../<source>/calendarContent/<windowStart>-<windowEnd>content://.../<source>/calendarTemplateStringscontent://.../<source>/calendarTemplateFlags
Calendar behavior:
prayersexports point events for Fajr, Duha, Dhuhr/Jumu'ah, Asr, Maghrib, and Ishamakruhexports range events for dawn, sunrise, zawal, after-Asr, and sunset windowsnightexports point events for midpoint, last third, and last sixth
Exposed Events
Prayers:
PRAYER_FAJRPRAYER_DUHAPRAYER_DHUHR(displayed as Jumu'ah on Friday)PRAYER_ASRPRAYER_MAGHRIBPRAYER_ISHA
Night:
NIGHT_MIDPOINTNIGHT_LAST_THIRDNIGHT_LAST_SIXTH
Makruh boundaries:
MAKRUH_DAWN_START/MAKRUH_DAWN_ENDMAKRUH_SUNRISE_START/MAKRUH_SUNRISE_ENDMAKRUH_ZAWAL_START/MAKRUH_ZAWAL_ENDMAKRUH_AFTER_ASR_START/MAKRUH_AFTER_ASR_ENDMAKRUH_SUNSET_START/MAKRUH_SUNSET_END
Settings Model (High-Level)
- Host selection:
- Auto-detect stable/nightly/legacy installs.
- Persist the selected event-provider authority.
- Open the host location picker UI from Settings (so you can choose from the host's saved locations without duplicating a location database in the addon).
- Open the host alarms screen from Settings.
- Prayer method:
- Presets + custom
- Fajr angle
- Isha mode (angle / fixed minutes)
- Asr factor (Shafi=1 / Hanafi=2)
- Maghrib offset
- Makruh:
- Presets (Shafi/Hanafi) + custom angle + zawal minutes
- Sunrise prohibited end as fixed minutes after sunrise (
10/15/20)
- Hijri:
- Variant: Umm al-Qura / Diyanet
- Day offset: -2..+2 (manual correction)
- Calendar:
- Month basis: Gregorian / Hijri
- Gregorian date format: Card / Medium / Long
- Toggle prohibited row
- Toggle night row
- Widget:
- Toggle prohibited row
- Toggle night row
- Uses separate toggles from Calendar (not shared)
- Alarms & backup:
- Export a host-importable prayer alarm preset file (includes Duha)
- Export/import addon settings as JSON backup
- UI:
- Language: system / English / Arabic
- Theme mode: system / light / dark
- Palette: parchment / dynamic (Android 12+) / sapphire / rose
Widget
Widget name:
- "Prayer Times (Today)"
Notes:
- Widgets use RemoteViews, so theming is applied by setting background resources + text colors at update time.
- Update scheduling is “best effort”: we update on app settings changes and schedule an alarm for the next meaningful boundary (next prayer / prohibited boundary / midnight rollover).
Tooling
This repo is intended to be built with:
- Gradle Wrapper (
./gradlew) misefor tool/version management (optional but recommended)- Release builds enable R8 shrinking/optimization (
minifyEnabled,shrinkResources, optimized ProGuard rules) - Release automation is available via GitHub Actions (
.github/workflows/release.yml) with dry-run, tag/release flow, signed APK validation, and generated release notes
Useful commands:
# Build debug APK
mise x java -- ./gradlew :app:assembleDebug
# Build release APK
mise x java -- ./gradlew :app:assembleRelease
# Run unit tests
mise x java -- ./gradlew :app:testDebugUnitTest
# Run instrumentation screenshots on a connected emulator/device
mise x java -- ./gradlew :app:connectedDebugAndroidTestProject Layout
app/src/main/java/com/yshalsager/suntimes/prayertimesaddon/
core/ # contracts, mapping, prefs, Hijri, delegation helpers
provider/ # exported addon provider for SuntimesWidget
ui/ # Activities + ViewModels
ui/compose/ # Compose screens and shared components
widget/ # AppWidgetProvider + update glue
Credits
- SuntimesWidget by Forrest Guice (host app and addon APIs):
forrestguice/SuntimesWidget - Time4J (Hijri calendar variants):
MenoData/Time4J - Jetpack Compose / Material 3:
AndroidX Compose
Material 3
License
GPL-3.0-only. See LICENSE.





