I didn’t block YouTube.
I made Shorts physically impossible to open — in 16ms — using an Android Accessibility Service.
I have a confession: I am a Senior Engineer, and I have the attention span of a goldfish.
Last month, I sat down to watch a 10-minute tutorial on Go routines.
45 minutes later, I was watching a video of a guy pressure-washing a driveway.
I tried the standard "App Blockers." They are useless. They are Hammers. They see com.google.android.youtube and they smash the entire app. But I need YouTube for learning. I need LinkedIn for jobs. I just don't want the Brain Rot (Shorts, Reels, Feeds).
So, I stopped trying to use willpower.
I built a Scalpel.
I created Blokr: A database-driven, accessibility-layer interceptor that surgically removes parts of an app while keeping the rest alive.
Here is how I engineered my way out of dopamine addiction.
🏗️ The Architecture of a "Digital Scalpel"
Most blockers work at the OS Layer (checking usageStats).
I decided to go deeper. I went to the UI Layer.
To block a specific button inside an external app (like the "Shorts" tab in YouTube), you have to read the screen faster than the user can click.
The Stack
- Brain: Flutter (BLoC + Clean Arch)
- Muscle: Kotlin (Native Accessibility Services)
- Eyes: Recursive Node Traversal
- Memory: Isar DB (Local) + Firestore (Remote Config)
🧠 The Logic: Traversing the Node Tree
Every Android app is just a tree of AccessibilityNodeInfo.
When you open YouTube, the OS sees a hierarchy. Most developers use Accessibility Services to help blind users navigate. I used it to hunt down specific View IDs.
Here is the logic I wrote to detect intent:
- Listen: The Service waits for
TYPE_WINDOW_CONTENT_CHANGED. - Fetch: It pulls the "Blacklist Rules" from my local DB.
- Hunt: It traverses the UI tree looking for specific
resource-idorcontent-descriptiontags.
The "Kill Switch" Code (Kotlin)
This is the actual native code running on the metal. It’s recursive, it’s dangerous, and it’s beautiful.
fun scanTree(node: AccessibilityNodeInfo?, targetId: String): Boolean {
if (node == null) return false
// 1. Check if this specific node is the "Enemy" (e.g., Shorts Tab)
// We check viewIdResourceName OR contentDescription
if (node.viewIdResourceName?.contains(targetId) == true) {
return true // FOUND IT!
}
// 2. Recursive Search through children
for (i in 0 until node.childCount) {
if (scanTree(node.getChild(i), targetId)) {
return true
}
}
return false
}
If scanTree returns true, Blokr immediately triggers a Global Back Action and overlays a Neo-Brutalist "Access Denied" screen.
It happens in 16ms. You literally cannot open the Shorts tab. The code is faster than your thumb.
🚀 The "Live" Database (Why this is cool)
Here is the problem: Instagram changes their View IDs every week. If I hardcoded id/reel_tab, the app would break next Tuesday.
The Solution: I made Blokr Database Driven. I have a remote database of "Block Definitions."
{
"app_name": "Instagram",
"package": "com.instagram.android",
"features": [
{
"name": "Reels Tab",
"target_id": "com.instagram.android:id/tab_clips",
"action": "BLOCK"
},
{
"name": "Direct Messages",
"target_id": "com.instagram.android:id/action_bar_inbox",
"action": "ALLOW"
}
]
}
When Instagram updates their app, I don't need to push a release to the Play Store. I just update the JSON in my DB, and BOOM—every user's Blokr app instantly learns the new layout.
🎨 Design: Neo-Brutalism or Nothing
I didn't want a "calm" UI. I wanted a UI that yells at you.
I used a Dark Mode Neo-Brutalist aesthetic.
- Hard Shadows
- #000000 Backgrounds
- Neon Accents
When Blokr stops you, it doesn't say "Please close this." It looks like a system error. It breaks the immersion immediately.
🎮 Can you spot the memory leak?
I initially ran the recursive scan on every scroll event. My battery died in 3 hours.
Here is the fix I implemented:
// The Bug (Battery Killer) 💀
- accessibilityService.on('TYPE_VIEW_SCROLLED', scanNodeTree);
// The Fix (Debounced) ✅
+ accessibilityService.on('TYPE_WINDOW_STATE_CHANGED', debounce(scanNodeTree, 300));
🧪 The "Strict Mode" (No Escape)
I know you. You're a dev. You'll just Force Stop the app.
That’s why I implemented Device Admin Privileges.
When you enter "Deep Work Mode" in Blokr, I disable the ability to uninstall the app or kill the service until the timer runs out.
I effectively turn your $1,000 Samsung S24 into a Nokia 3310 for 2 hours. It’s terrifying. It’s effective.
🔥 The Community Challenge
I am currently mapping the "View IDs" for every major distracting app. But I can't do it alone.
I need your help to build the ultimate blacklist.
👇 Comment below with the ONE specific feature you hate.
- Is it the LinkedIn "News" feed?
- Is it the Twitter "For You" tab?
- Is it the Facebook "Marketplace" notification?
Tell me the app and the feature. I will reverse-engineer it, find the ID, and add it to the global database this weekend.
Let's reclaim our brains from the algorithms.

Top comments (1)
I just tried to advance the blocking logic to run under new coroutine which can improve performance.
Any idea how i can improve performance and scanning.