An offline Muslim prayer-times, qibla, and Hijri-date app for Android, built with Jetpack Compose and Material 3 Expressive.
Free, no ads, no accounts, no analytics.
./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 21 — adhan2-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.
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.
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 bumpTwo 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 restoreand that enum name literals survive R8 settings and the adhan2 method bridge are both persisted and resolved by name.


