Releases: MuhammadZainIqbal/blink-control-scroller
Release list
Initial Release
Blink Control Scroller
Stop touching your screen. Let your eyes do the work.
Doom-scroll TikTok, Instagram Reels, and YouTube Shorts completely hands-free. Just blink. That's it.
🧠 Under the Hood
┌──────────────────────────────────────────────────────────────────┐
│ MainActivity │
│ (Jetpack Compose UI) │
└─────────────────────────────┬────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────┐
│ MainViewModel │
│ (StateFlow + Coroutines) │
└─────────────────────────────┬────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────┐
│ BlinkDetectionService │
│ (Foreground Service + Overlay) │
│ │ │
│ ┌───────────────────────▼───────────────────────┐ │
│ │ CameraManager │ │
│ │ (CameraX 1.4 Pipeline) │ │
│ └───────────────────────┬───────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────┐ │
│ │ FaceDetectionAnalyzer │ │
│ │ (ML Kit + Blink State Machine) │ │
│ └───────────────────────┬───────────────────────┘ │
└──────────────────────────────┼───────────────────────────────────┘
│ Broadcast Intent
┌──────────────────────────────▼───────────────────────────────────┐
│ BlinkAccessibilityService │
│ (GestureDescription API → System Swipe) │
└──────────────────────────────────────────────────────────────────┘
Data Flow: Camera Frame → ML Kit → Blink Event → Broadcast → Accessibility Gesture → Next Reel
✅ Features
- ✅ Blink-to-Scroll — Close both eyes for 400ms to scroll to next video
- ✅ Works Everywhere — Injects gestures system-wide via Accessibility Services
- ✅ Smart Cooldowns — 1-second cooldown prevents accidental rapid scrolling
- ✅ Battery Saver — Auto-shutdown after 10 minutes of inactivity + screen lock
- ✅ 100% On-Device — Zero network calls, zero data collection, zero tracking
- ✅ Real-time Face Tracking — ML Kit with configurable sensitivity thresholds
- ✅ Background Operation — Invisible overlay keeps detection running in any app
🛠 Tech Stack
| Layer | Technology |
|---|---|
| Language | Kotlin 2.0 + Coroutines/Flow |
| UI | Jetpack Compose + Material Design 3 |
| Camera | CameraX 1.4 |
| ML/Vision | Google ML Kit Face Detection |
| Architecture | MVVM + Unidirectional Data Flow |
| System Integration | Android Accessibility Service API |
| Background | Foreground Service + WindowManager Overlay |
| Build | Gradle Kotlin DSL + Version Catalogs |
| Target | Android 8.0 (API 26) → Android 15 (API 35) |
📲 The Sideloading Survival Guide
This app is distributed via APK (not Play Store). Android will throw some warnings at you. Here's how to handle them like a pro.
Download
👉 Download the latest APK from Releases
Step 1: Install the APK
Download the APK and open it. If you see "App Not Installed" or a security warning, that's expected.
🛡️ Play Protect Warning
Google Play Protect may block installation of apps outside the Play Store.
Fix:
- Open Google Play Store
- Tap your Profile Icon → Play Protect
- Tap the ⚙️ Settings gear
- Toggle OFF "Scan apps with Play Protect"
- Install the APK
- Re-enable Play Protect after installation (recommended)
❌ "App Not Installed" Error
This happens when Android thinks it's a debug/test build.
For users: Try the Play Protect fix above first.
For developers building from source: Add this to your gradle.properties:
android.injected.testOnly=falseThis marks the APK as a release build that can be manually installed.
Step 2: Grant Permissions (The Tricky Part)
After installation, the app needs 3 permissions:
| # | Permission | How to Grant |
|---|---|---|
| 1️⃣ | Camera | Grant when prompted |
| 2️⃣ | Display Over Other Apps | Settings → Apps → Special Access → Display Over Other Apps → Enable |
| 3️⃣ | Accessibility Service | Settings → Accessibility → Blink Control Scroller → Enable |
Step 3: The Android 13+ "Restricted Settings" Block
If you're on Android 13 or newer, you'll hit a wall when trying to enable Accessibility. Android blocks sideloaded apps from using "sensitive" permissions.
🔓 How to Bypass "Restricted Settings"
- Go to Settings → Apps → Blink Control Scroller
- Tap the ⋮ (three dots) in the top-right corner
- Select "Allow Restricted Settings"
- Now go back to Accessibility Settings and enable the service
This is a one-time setup. Android remembers your choice.
⚙️ Configuration
Tune detection sensitivity in BlinkEvent.kt:
data class BlinkDetectionConfig(
val eyeOpenThreshold: Float = 0.3f, // Lower = more sensitive
val bothEyesMinDurationMs: Long = 400L, // Blink hold time
val blinkCooldownMs: Long = 1000L, // Prevents spam
val maxBlinkDurationMs: Long = 3000L // Ignores "stuck" blinks
)🔒 Privacy
Your face never leaves your device. Period.
- Local inference only — ML Kit runs 100% on-device
- No storage — Frames processed in memory, then discarded
- No network — App has no internet permission
- No telemetry — Zero analytics, zero third-party SDKs
📁 Project Structure
app/src/main/java/com/instablinkcontrol/
├── MainActivity.kt
├── data/
│ ├── BlinkEvent.kt # Events + detection config
│ └── EyeState.kt
├── detection/
│ ├── BlinkDetectionManager.kt
│ ├── BlinkDetectionSettings.kt
│ ├── CameraManager.kt # CameraX lifecycle
│ └── FaceDetectionAnalyzer.kt # ML Kit processor
├── service/
│ ├── BlinkAccessibilityService.kt # Gesture injection
│ ├── BlinkDetectionService.kt # Foreground service
│ └── BlinkOverlayService.kt
├── ui/
│ └── screen/MainScreenWorkingFixed.kt
└── viewmodel/
└── MainViewModel.kt
🤝 Contributing
- Fork it
- Branch it:
git checkout -b feature/cool-idea - Commit it:
git commit -m "Add cool idea" - Push it:
git push origin feature/cool-idea - PR it
📄 License
MIT — do whatever you want, just don't sue me.
Built with Kotlin, ML Kit, and the power of not touching your phone.