StepSafe is an assistive Android application that helps people in the early stages of Alzheimer's disease by providing active cognitive assistance. Instead of only passively tracking, StepSafe detects when a user leaves a configured "Safe Zone" and immediately triggers an emergency flow: a foreground alert for the patient (lock‑screen bypass + TTS) and an emergency SMS to a caregiver.
This repository contains a Kotlin/Jetpack Compose implementation using modern Android architecture and best practices (Room, DataStore, Dagger Hilt, Coroutines, StateFlow).
- Architecture
- User interface & navigation
- Core services and background processing
- Data persistence
- Security, permissions & UX
- Testing & quality assurance
- How to build & run (quick)
- Demo videos
- Screenshots — App flow
- Diagrams
- License & contact
- How to Install StepSafe APK
- Minimum Supported OS
StepSafe follows MVVM with Clean Architecture principles:
- UI layer: Jetpack Compose, driven by StateFlow exposed by ViewModels.
- Presentation (ViewModel) layer: business logic and bridging UI <-> data.
- Data layer: Room for structured relational data + DataStore for lightweight preferences.
- DI: Dagger Hilt for providing database instances, DAOs, repositories, and services.
This separation keeps code testable and modular.
The dashboard is intended for caregivers to configure the app:
- Map preview via
maps-compose(Google Maps) to set home location by tapping or postcode lookup. - Safe zone radius slider (50m–500m).
- A "Set Geofence" action which debounces repeated clicks by using an
isRegisteringGeofencestate. When registering, the button shows a spinner and is disabled.
Example snippet (Compose pseudocode):
Button(onClick = { haptic.performHapticFeedback(HapticFeedbackType.LongPress); onSetGeofence() },
enabled = !isRegisteringGeofence) {
if (isRegisteringGeofence) {
CircularProgressIndicator(modifier = Modifier.size(18.dp), color = Color.White)
Text("Saving...", fontWeight = FontWeight.Bold)
} else {
Text("Set Geofence", fontWeight = FontWeight.Bold)
}
}When a geofence EXIT is detected, AlertActivity is launched using a full-screen intent so it can wake the device and bypass the lock screen. The UI is intentionally minimal: a single prominent action ("Navigate Home") and optional TTS prompting to reduce cognitive load for the patient.
Android 14+ places stricter limits on background work. To keep geofencing reliable we use a foreground service and follow OS guidance for long‑running location tasks.
- Registers geofences with Google Location Services API.
- Runs as a foreground service with a non-dismissible notification of type
FOREGROUND_SERVICE_TYPE_LOCATIONon newer Android releases.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)
}- Receives
GEOFENCE_TRANSITION_EXITevents and acts as the emergency trigger. - Uses Coroutines (
Dispatchers.IO) to query theCaregiverContactDaoand send an SMS viaSmsManager. - Launches
AlertActivityand posts a high priority notification. - We persist an
ExitEventto Room on exit (so the database contains clear pre/post evidence rows for Appendix B).
- On device boot, the receiver checks DataStore to determine if monitoring was active before reboot and re-schedules the
GeofencingServiceif needed.
-
Room (
AppDatabase) stores structured entities:HomeLocation— latitude, longitude, address.CaregiverContact— name, phone number.ExitEvent— timestamp, lat/lng, eventType, optional note (added to support Appendix evidence exports).
-
Jetpack DataStore (
SettingsRepository) stores preferences such assafeZoneRadiusandmonitoringActiveas Flows.
- Permission sequencing is managed via an Accompanist
PermissionProvidercomposable. - We request Fine/Coarse Location and SMS permissions, and (with a clear explanation) request Background Location when required so geofences work reliably.
- Foreground service notification explains why location is needed and provides a quick way for a caregiver to stop monitoring.
- Unit testing stack: JUnit 4, MockK, Turbine, and Robolectric.
- Tests include:
- ViewModel tests verifying state transitions.
- DAO tests using in-memory Room databases.
- BootReceiver tests ensuring reboot persistence behaviour.
From the project root:
# Build the debug APK
./gradlew :app:assembleDebug
# Install to connected device (adb must be authorized)
adb install -r app/build/outputs/apk/debug/app-debug.apkNotes:
- For DB exports and Appendix evidence capture, I included a small script under
scripts/collect_appendix_b.shthat automates logcat capture, screenshots and (when possible) pulls the app's Room DB viarun-as. - For reliable DB pulls, install the debug APK (so
run-asworks). The script can also exportexit_eventrows to CSV ifsqlite3is installed on your host machine.
1. StepSafe — Starting app, granting permission, setting up home, and starting monitoring
StepSafe-in-action-starting-app-granting-permission-setting-up-home-and-start-monitoring.mp4
2. StepSafe — Stepping outside the geofencing area
(🔊 Unmute to hear the guidance)
StepSafe-in-action-when-stepping-outside-of-geofencing-area.mp4
Below is an ordered sequence of screenshots from project-screenshots/ that follow the app's runtime flow (install/permission → configure home → start monitoring → background monitoring → exit alert → caregiver notification → navigation):
-
App installed on home screen
-
First-run: notification permission prompt
-
First-run: device location permission prompt
-
First-run: background location information / request
-
First-run: SMS permission prompt
-
First-run: explanation about sending SMS in background
-
Main dashboard (caregiver/home screen)
-
Setting home location (map / select location)
-
Increase / adjust geofencing radius
-
Saving geofence (in-progress)
- Geofence saved (confirmation)
- Start monitoring (foreground service)
- Foreground notification shown when app sent to background
- Background service continues running after app closed
- User steps outside the geofence — alert screen shown on device
- Caregiver receives SMS message
- App notification launches Google Navigation
- Google Maps — navigation started (walk mode)
- Google Maps — zoomed-in navigation view
- After pressing "Navigate Home" - navigation launches (alternative view)
Architecture and flow diagrams are included in projectFile/.
This project is provided for academic/educational purposes. For questions or to request additional exports or build assistance, please reply in this issue or contact the repository owner.
You can install the StepSafe app directly on any compatible Android device (Android 13, API 33 and above; this app targets Android 13/14, API 33/36). The APK is provided for direct installation:
Download APK: StepSafe.apk
-
Download the APK
- Download the APK file from the link above to your Android device (or transfer it via USB, email, or cloud storage).
-
Enable Installation from Unknown Sources
- Go to your device's Settings > Security (or Apps & notifications > Special app access > Install unknown apps).
- Find your browser or file manager app and enable Allow from this source.
- On some devices, you may be prompted to allow installation when you open the APK file.
-
Install the APK
- Open your file manager and locate the downloaded
StepSafe.apkfile. - Tap the file and follow the prompts to install.
- If prompted, confirm installation and accept any warnings about unknown sources.
- Open your file manager and locate the downloaded
-
Launch the App
- Once installed, you can find StepSafe in your app drawer. Open it and grant any requested permissions (location, SMS, notifications) for full functionality.
Note:
- This APK is for testing and demonstration purposes. For production use, install only from trusted sources (e.g., Google Play Store).
- If you encounter issues, ensure your device meets the minimum SDK requirement (Android 13, API 33+).
StepSafe requires Android 13 (API level 33) or higher. Devices running older versions of Android are not supported. This is enforced by the minSdk = 33 setting in the build configuration.














