Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ScrollMind

A Flutter + Kotlin Android app that auto-scrolls any app at your natural reading pace — hands-free.

ScrollMind learns how fast you read by watching you scroll through a sample article. It then drives the screen at exactly that pace using Android's Accessibility Service gesture API, so you can read without touching the screen.


Features

  • Reading speed training — scroll a sample article naturally; the app measures your pace across multiple read-pause-scroll cycles and computes a median rate
  • Per-direction control — train Up and Down independently; the active direction is selectable from the home screen
  • Video mode — auto-detects when the foreground app is playing audio and switches to a fixed swipe interval (default 15 s, configurable per app)
  • Per-app video intervals — set a custom swipe timer (5–120 s) for specific apps like YouTube Shorts or Instagram Reels
  • Floating overlay — translucent AssistiveTouch-style button while scrolling; tap to open pause/close menu, drag to reposition
  • Quick Settings tile — toggle auto-scroll directly from the notification shade
  • Automatic restart — overlay and scrolling restart automatically when you switch to a supported app

How it works

Flutter UI (Riverpod state)
    ↓  MethodChannel
MainActivity (Kotlin)
    ↓  SharedPreferences  ←─────────────────────────┐
AutoScrollAccessibilityService                      │
    ├─ polls config every 250 ms                    │
    ├─ dispatches GestureDescription swipes         │
    └─ starts / stops FloatingOverlayService ───────┘
                ↓
        User sees pause button floating over app

Scroll gesture

  • Swipe covers 44% of the screen dimension (height for Up/Down)
  • Fixed 300 ms gesture duration — natural feel
  • Interval between gestures = distance / readingSpeed × 1000 (clamped 400 ms – 20 s)

Training algorithm

  1. User scrolls through a long article naturally
  2. Each time the finger lifts for > 500 ms, a new drag segment begins
  3. Completion requires: ≥ 1 200 physical px scrolled AND ≥ 4 segments
  4. Per-cycle rate: pixels[i] / (segmentStart[i+1] − segmentStart[i]) (px/ms)
  5. Final speed = median of all cycle rates × 1 000 (px/s), bounded [10–2 000]

Using the median makes the measurement robust to a single distraction pause or unusually fast swipe.


Permissions

Permission Why
Accessibility service Detect foreground app; dispatch scroll gestures
Display over other apps Render the floating pause button
Foreground service Keep the scroll loop alive in the background
Ignore battery optimizations Prevent Android from killing the service
Query all packages Populate the app-selection list

All sensitive permissions must be granted manually by the user through system settings. The home screen shows a banner for each missing permission with a direct link.


Screens

Screen Purpose
Home Trained speeds, permission banners, master on/off toggle, quick actions
Training Scroll an article at your natural pace to calibrate speed
App Selection Pick which apps trigger auto-scroll; set per-app video intervals
Settings Permission management, reset training, about

Project structure

lib/
├── main.dart
├── router/app_router.dart
├── core/
│   ├── constants/app_constants.dart   # thresholds, route names
│   └── theme/app_theme.dart
├── data/
│   ├── models/scroll_config.dart      # data model + JSON serialisation
│   └── repositories/settings_repository.dart   # SharedPreferences + MethodChannel
└── presentation/
    ├── providers/scroll_provider.dart  # Riverpod notifiers
    ├── screens/                        # home, training, app_selection, settings
    └── widgets/                        # luxury_card, direction_speed_card

android/app/src/main/kotlin/com/autoscroll/scrollmind/
├── MainActivity.kt                    # MethodChannel bridge
├── AutoScrollAccessibilityService.kt  # scroll loop + gesture dispatch
├── FloatingOverlayService.kt          # floating pause/close button
└── AutoScrollTileService.kt           # Quick Settings tile

Tech stack

Layer Technology
UI Flutter 3.41
State Riverpod 3 (AsyncNotifier)
Navigation GoRouter
Persistence SharedPreferences
Native bridge MethodChannel
Background scroll Android AccessibilityService + GestureDescription
Overlay WindowManager TYPE_APPLICATION_OVERLAY
Min SDK 24 (Android 7.0)
Target SDK 35 (Android 15)

Build & install

# Install dependencies
flutter pub get

# Run debug on connected device
flutter run

# Build release APK
flutter build apk --release

# Build release AAB (Play Store)
flutter build appbundle --release

For production signing, add android/key.properties and a keystore file (excluded by android/.gitignore):

storePassword=YOUR_STORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=YOUR_KEY_ALIAS
storeFile=autoscrollr-release.jks

The CI pipeline (.github/workflows/) runs flutter analyze + flutter test on every PR, and builds a release APK on every v*.*.* tag push.


Setup after install

  1. Open ScrollMind
  2. Tap Enable → grant Accessibility service
  3. Tap Grant → grant overlay permission
  4. Tap Fix → exempt from battery optimisation
  5. Tap 📱 Select Apps → choose which apps to scroll
  6. Tap a speed card → scroll the article at your natural reading pace
  7. Flip the master toggle — done

The floating button will appear over the selected app and auto-scroll will begin.


CI/CD

Two GitHub Actions workflows are included:

  • ci.yml — runs on every PR/push to main: flutter analyze --fatal-infos + flutter test
  • release.yml — runs on v*.*.* tags: builds release APK, uploads as artifact named scrollmind-<version>.apk

To cut a release:

git tag v1.0.0
git push origin v1.0.0

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages