Modern Android library that renders a customizable Qibla compass using Kotlin and Jetpack Compose. It provides lifecycle-aware sensor and location helpers together with a ready-to-use compass composable that you can drop into your app.
- 100% Kotlin + Jetpack Compose implementation; no legacy activities or XML views.
- Lifecycle-aware sensor reader with graceful fallbacks when rotation-vector sensors are missing.
- Location helper with permission-aware updates and automatic last-known-location fallback.
- Highly customizable UI: dial/indicator painters, color tints, info overlays, marker visibility, and animation duration.
- Sample app demonstrating permission flow, dual compass styles, and live status cards.
Make sure your project is using Android Gradle Plugin 8.2+, Kotlin 1.9+, and has Compose enabled.
// settings.gradle
pluginManagement {
repositories {
google()
mavenCentral()
}
}// build.gradle (project)
allprojects {
repositories {
google()
mavenCentral()
}
}// module-level build.gradle(.kts)
dependencies {
implementation("io.github.hassaanjamil:qiblaCompass:1.0.0")
}
⚠️ The library is built with Compose. Ensure your module hasbuildFeatures { compose = true }and the appropriatecomposeOptionsconfigured.
The helper rememberLocationState expects that at least coarse or fine location permission has been granted. Handle the runtime permission flow in your composable or activity.
@Composable
fun QiblaScreen() {
val context = LocalContext.current
var hasLocationPermission by remember { mutableStateOf(context.hasLocationPermission()) }
val permissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
hasLocationPermission = result[Manifest.permission.ACCESS_FINE_LOCATION] == true ||
result[Manifest.permission.ACCESS_COARSE_LOCATION] == true
}
val azimuthState = rememberCompassAzimuth()
val locationState = rememberLocationState(hasLocationPermission)
val qiblaDirection = rememberQiblaDirection(locationState.value).value
QiblaCompass(
azimuthDegrees = azimuthState.value,
qiblaDirectionDegrees = qiblaDirection,
location = locationState.value,
animationDurationMillis = 260,
dialTint = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f),
indicatorTint = MaterialTheme.colorScheme.secondary
)
}QiblaCompass exposes several parameters so you can brand the experience:
dialPainter/indicatorPainter: Replace default resources with your ownPainterinstances.dialTint,indicatorTint,backgroundColor,borderColor,markerColor,markerContentColor.animationDurationMillis: Control how fast the indicator reacts to sensor updates.showNorthMarker: Toggle the top “N” badge.infoContent: Provide custom overlay content; the default shows heading, Qibla direction, bearing difference, and coordinates.showInfoPanel: Hide or show the overlay entirely.
For location helpers:
rememberLocationStatelets you configure min update time/distance and providers list.
The app module contains a Compose-based sample that demonstrates permission handling and two styling approaches. Launch it to see the compass in action.
./gradlew :app:assembleDebugPull requests and issues are welcome! Please open a discussion if you have suggestions for new customization points or sensor improvements.
Apache License 2.0 – see LICENSE for details.


