Inspiration
Short-form video is engineered to win the next 15 seconds. Calendars, sleep, and the work you actually meant to do do not get the same fight.
We were tired of “wellness” apps that only show a chart after the damage is done. Unscrolled started from a simpler idea: interrupt the Reel in the moment, then use the rest of the phone. Health Connect, usage stats, calendar to coach you back into the day you already planned.
The name is the product: leave the infinite scroll, and get unscrolled.
What it does
Unscrolled is an Android focus app that blocks Instagram Reels and YouTube Shorts in real time, then helps you stay in your real day.
- Focus protection: an Accessibility service watches Instagram and YouTube. When the Reels or Shorts player is actually on screen, it sends you Back and logs the block. Stories and normal videos are left alone.
- Today dashboard: steps, unproductive screen time, block count, last night’s sleep, and today’s calendar — refreshed when you open the app.
- Insights: 7- and 30-day trends so you can see whether the week is getting better or slipping.
- Voice roast: optional Gemini one-liner, spoken by ElevenLabs, grounded in this block (which app, how many times today).
- AI Coach (Foxtrot): a Backboard-powered coach that sees a local snapshot of your last 7 days, today’s events, and your goals — not a generic productivity chatbot.
Health, calendar, and usage data stay on-device in Room. The coach only gets a compact JSON snapshot when you start a chat. Screen structure never leaves the phone.
How we built it
Native Kotlin / Android (Views, Material 3, Room, coroutines).
| Layer | Stack |
|---|---|
| Detection | AccessibilityService + view-ID heuristics (clips_viewer_view_pager, reel_player_page_container) plus tab-label fallback |
| Local data | Room: blocks, usage, Health Connect rollups, sleep sessions, calendar |
| Sync | UsageStatsManager, Health Connect, CalendarContract — on app open, not background polling |
| Coach | Backboard (Gemini) + on-device snapshot builder + durable-goal memory (stats are not stored as memories) |
| Voice | Gemini roast line → ElevenLabs TTS, with device TTS fallback |
| UI | Custom bar/line charts, Today / Coach / Insights, permission empty states |
Challenges we ran into
False positives. Instagram keeps a zero-size clips viewer in the tree even when you are not watching Reels. We had to require isVisibleToUser and non-zero bounds, and treat Stories as a different ID family so they never match.
Sideload + Accessibility. On modern Android, a sideloaded blocker cannot enable the service until the user allows restricted settings. That is a product problem, not just a docs footnote — we had to explain it in-app.
Grounded AI, not vibes. A coach that invents meetings or recites step counts as “goals” is worse than no coach. We separated device facts (JSON, once per thread) from user intent (memory prompts that refuse to store metrics).
Health numbers vs Google Health. Health Connect aggregates are the source of truth; they will not always match the Google Health UI. We chose honesty over fake parity.
Voice without stacking roasts. Blocks can fire in bursts. Roast generation is single-flight, with a cooldown on the Back action so the phone does not yell at you five times in a second.
Accomplishments that we're proud of
- A blocker that hits the player, not the whole app — you can still message, search, and watch long-form.
- A Today screen that feels like a day, not a debug dump: hero metrics, schedule, sleep, and a path into the coach.
- A coach that names real calendar events and treats doomscrolling as an earned, time-boxed treat after work — not the default.
- Optional voice that is actually contextual, plus a silent path if keys or TTS fail.
- Privacy defaults we can stand behind: local Room store, scoped Accessibility packages, no screenshot pipeline.
What we learned
Attention is a systems problem. Charts without interruption are theater; interruption without context is nagging. The interesting product sits in the join: detect the feed, then reattach the person to their calendar and body.
We also learned that Android’s most powerful APIs (Accessibility, Usage Stats, Health Connect) are also the ones users are right to fear. Clear permission empty states and “data stays here” is part of the UX, not a legal appendix.
On the model side: narrow persona + private JSON + strict memory beats a bigger prompt. Foxtrot is useful because it is not allowed to be a search engine or a therapist.
What's next for Unscrolled
- Broader short-form coverage (TikTok, in-app vertical players) without turning into a blunt app blocker.
- Smarter schedules: protect focus during events, allow a bounded scroll after them.
- Stronger week coaching from longer health history, still on-device first.
- A cleaner first-run for Accessibility on sideloaded builds.
- Optional cloud sync later only if it stays an opt-in, not the default.
Unscrolled should disappear into a better day. The win is not more time in our app. The win is fewer Reels between you and the next thing on your calendar.
Built With
- kotlin
Log in or sign up for Devpost to join the conversation.