Inspiration
Sometimes you want to leave your phone on a desk, table, charger, or other temporary location and know if it gets moved.
I built MotionGuard around a deliberately simple interaction: explicitly arm the phone, let it settle, and have it sound an alarm when meaningful movement is detected. Pro users can also monitor for charger removal.
The goal was not to build a theft-prevention system or make security guarantees. MotionGuard is a user-armed local alerting utility designed to make movement monitoring quick, understandable, and easy to stop.
What it does
MotionGuard uses the phone's motion sensors during an explicitly armed session.
The basic flow is:
- Choose your monitoring settings.
- Tap Arm.
- Let the phone settle.
- MotionGuard monitors for meaningful movement.
- If the configured trigger is detected, the phone sounds an alarm and explains why it triggered.
- Disarm immediately from the phone, notification, or paired Wear OS companion.
The free version includes the core motion alarm, Normal sensitivity, settling controls, testing and compatibility flows, trigger history, and alarm/disarm controls.
Pro adds:
- Low and High sensitivity options
- Charger-removal monitoring
- Best-effort immediate trigger alerts on a paired Wear OS watch
The phone remains authoritative for the monitoring session. The Wear OS companion mirrors status, provides a read-only Tile, and can send a disarm request back to the phone.
A monetization model that does not interrupt the product
One of the main experiments I wanted to try during Shipaton was whether advertising could be integrated without making a utility app annoying.
MotionGuard therefore has no banner ads, interstitial ads, app-open ads, forced ads, or Wear OS ads.
Instead, users have two ways to activate the same RevenueCat pro entitlement:
Advanced Guard Pass
A user can explicitly choose to watch one rewarded ad to receive Pro access for 8 hours.
The ad is only requested after the user asks for it, and MotionGuard will not load or show a rewarded ad while an armed monitoring session is active.
RevenueCat's AdMob integration tracks the rewarded flow, and server-side reward verification is used before the app treats the temporary Pro entitlement as active.
Lifetime Pro
Users who do not want to use rewarded ads can instead purchase Lifetime Pro through Google Play.
There are no subscriptions.
This creates a deliberate tradeoff: occasional users can temporarily unlock advanced functionality without paying, while frequent users can permanently unlock it with a one-time purchase.
How I built it
MotionGuard is a native Android and Wear OS project written in Kotlin.
The phone application uses Jetpack Compose with a single-activity architecture, coroutines and StateFlow, Hilt dependency injection, Room for trigger history, DataStore for settings and recovery metadata, and a user-visible foreground service during active monitoring.
The motion-detection pipeline is separated into pure Kotlin domain logic so sensor traces and state transitions can be tested deterministically.
A central session coordinator owns the transition between DISARMED, SETTLING, ARMED, and TRIGGERED states. Sensor callbacks cannot directly start the alarm. They produce events that are evaluated against the current session so stale or duplicate events cannot trigger a newer session.
The Wear OS companion communicates through the Wear Data Layer while keeping the phone authoritative.
For monetization I replaced app-owned billing state with RevenueCat as the entitlement authority. RevenueCat handles the Google Play purchase state and maps both Lifetime Pro and temporary rewarded access onto the same pro entitlement.
The rewarded path uses RevenueCat's AdMob adapter together with Google Mobile Ads and Google's User Messaging Platform for consent handling.
Challenges
Making ads compatible with an armed utility
The hardest monetization decision was determining where an ad could exist without interfering with the reason someone opened MotionGuard.
Showing an ad during arming, triggering, or disarming would be a bad experience and could interfere with an important control.
I therefore treated advertising as a separate entitlement-acquisition workflow. Rewarded ads are only available while MotionGuard is fully disarmed, require an explicit user action, and cannot grant access from a local ad callback alone.
Separating entitlement state from monitoring state
An armed session should not unexpectedly change because temporary Pro access expires or a network request fails.
MotionGuard freezes the effective configuration when a session is admitted. Entitlement changes affect future sessions rather than rewriting a session that is already running.
Disarm also never depends on billing, advertising, or network availability.
Building reliable sensor behavior
Motion sensors are noisy, Android background execution has strict constraints, and different devices can behave differently.
I separated the detector from Android-specific code, built deterministic trace testing around it, and kept active sensor monitoring tied to a visible foreground-service session initiated by the user.
Physical-device calibration and OEM testing remain an important part of continuing to improve the detector.
What I learned
The most interesting lesson from MotionGuard has been that monetization does not have to be layered on top of an application after the product is designed.
It can be part of the product architecture.
RevenueCat allowed both a Google Play lifetime purchase and a temporary rewarded-ad path to resolve to the same entitlement instead of creating two unrelated access systems.
That made it possible to design the monetization boundary around a simple rule:
The free alarm must always remain useful, and monetization must never interfere with an active monitoring or disarm flow.
It also gave me a practical reason to experiment with rewarded advertising in a utility where traditional banner or interstitial ads would be particularly intrusive.
What's next
My next steps are to use real-world feedback and physical-device testing to continue tuning motion sensitivity, validate behavior across more Android devices, and measure how users respond to the choice between an eight-hour rewarded Pro pass and Lifetime Pro.
I am particularly interested in whether temporary rewarded access acts as a useful product trial that ultimately improves Lifetime Pro conversion without degrading the core experience.
Built With
- ai
- android
- android-studio
- compose
- kotlin
Log in or sign up for Devpost to join the conversation.