Skip to content

Repository files navigation

Material Prayer Times

An offline Muslim prayer-times, qibla, and Hijri-date app for Android, built with Jetpack Compose and Material 3 Expressive.

Play Store title: Material Prayer Times · package app.waqt · free, no ads, no accounts, no analytics.

Today screen showing the next prayer countdown and the day's prayer times Qibla compass showing the direction and distance to Makkah Settings screen with calculation method and appearance options

What it does

  • Today — the five prayers plus sunrise, in one of two layouts: Madar (the day's orbit — a band of wavy prayer windows above the hero countdown) or Rawdah (the shape garden — larger prayer glyphs and a quick-actions menu).
  • Qibla — a compass dial with true-north declination correction, degrading to a plain bearing on devices with no magnetometer.
  • Widget — a Glance home-screen widget showing the next prayer and the shape of the day.
  • Notifications — per prayer, four modes (Alarm / Chime / Silent / Off), plus an optional persistent countdown that uses Android 16's segmented progress style where available.
  • Calculation — 11 methods, both Asr madhabs, four high-latitude rules, per-prayer minute adjustments to match your local mosque, and a Hijri offset.

Everything is computed on-device with adhan2. There is no backend.

Building

./gradlew :app:assembleDebug          # debug APK
./gradlew :app:testDebugUnitTest      # unit tests
./gradlew :app:lintVitalRelease       # the lint pass that gates a release build
./gradlew :app:bundleRelease          # signed release .aab (needs keystore.properties)

Requires a JDK 17 toolchain to build. Unit tests run on JDK 21adhan2-jvm is published as class-file 65, so running them on 17 fails with UnsupportedClassVersionError before any assertion executes. The foojay resolver in settings.gradle.kts provisions that JDK automatically.

Release signing

bundleRelease needs a keystore.properties in the repo root, which is gitignored and must never be committed:

storeFile=upload-keystore.p12
storePassword=…
keyAlias=upload
keyPassword=…

Without it the build still configures and runs, it just produces an unsigned artifact. The .p12 is the upload key, not the app signing key — Google holds the latter under Play App Signing. Back both the keystore file and its password up somewhere off this machine.

Verifying a release artifact

AAB=app/build/outputs/bundle/release/app-release.aab
unzip -l "$AAB" | grep -E 'META-INF/.*\.(RSA|SF)$'    # must be signed
java -jar bundletool.jar dump config --bundle="$AAB" | grep alignment
# PAGE_ALIGNMENT_16K expected — re-check after every dependency bump

Two things worth re-checking after a dependency bump, because both fail silently rather than at build time:

grep INSTANCE app/build/outputs/mapping/release/seeds.txt   # nav3 back-stack restore

and that enum name literals survive R8 — settings and the adhan2 method bridge are both persisted and resolved by name.

Layout

app/src/main/java/app/waqt/
  data/          repositories: settings + location DataStores, adhan2 wrapper
  domain/        Prayer, PrayerDay, the timeline walk (computeUpcoming)
  notifications/ alarm chain, channels, prayer + ongoing notifications
  ui/            Compose screens: home, qibla, settings, about, onboarding
  widget/        Glance app widget and its refresh worker

The alarm design is a one-alarm chain: only the next marker is ever scheduled. When it fires, the receiver re-arms the following one first, then does its rendering work. WidgetUpdateWorker also re-arms on every run, so a receiver killed mid-flight self-heals rather than leaving the app permanently silent.

Privacy

See PRIVACY.md. The short version: no servers, no accounts, no analytics. The one thing that does touch the network is Android's Geocoder when you search for a city — the app is explicit about this in Settings, in the policy, and in its Play Data safety declaration, and all three say the same thing.

Attribution

See ATTRIBUTION.md for bundled assets and their licences. The in-app Open Source Licences screen reproduces the notices the dependencies require.

Licence

The source code is licensed under the Apache License 2.0.

That covers the code in this repository only. Bundled assets carry their own terms and are not relicensed by it:

  • Prayer time calculation uses adhan2, MIT.
  • Cairo (the Arabic display face in app/src/main/res/font/) is under the SIL Open Font License 1.1.

See ATTRIBUTION.md for the full notices, including what was modified and why.

Releases

Packages

Contributors

Languages