The last launcher you'll ever need. A one-page Android home screen that learns your habits and puts the right app under your thumb before you even look for it.
No app drawers to organize, no pages to swipe through, no widgets to babysit. Just a clock, the three apps you're most likely to want right now, and a command bar where typing two letters launches anything.
LastLauncher keeps a small on-device memory of when you open what: the hour, the day, the app you came from, and what your phone was doing (Bluetooth just connected? headphones plugged in? charger attached?). From that it predicts your next app:
- Plug in your headphones β your music app glows in the center.
- Connect to your car's Bluetooth β navigation is one tap away.
- Every evening you open the same reader after the same messenger β it's already waiting.
The most likely app is the big glowing button; two runners-up flank it. Everything is computed on your phone with a few milliseconds of math over a tiny SQLite table. Nothing ever leaves your device.
- π§ Launcher memory β on-device prediction from time of day, weekday rhythm, app-to-app sequences, and context triggers (Bluetooth, headphones, charging)
- β¨οΈ Command bar with modes β the wheel on its left cycles Smart Β· Apps Β· Settings Β· Ask. Smart mode launches apps and jumps to settings by name (
wifiβ WiβFi settings, no prefix), does quick math (12*7β tap to copy) and opens URLs; a>prefix forces the quick-action palette. Long or question-like text routes to the assistant β no web search. App search even matches package keywords (musicfinds Spotify). - ποΈ Configurable edge gestures β one- and two-finger swipes on each side (
>,>>,<,<<in the launcher's CLI notation), each mappable to any action or app. Monospace hints on the screen edges travel the way you should swipe, fading in and out as they cycle. - ποΈ Wheel app drawers β create several named drawers (each with its own apps) and bind any of them to an edge swipe. Background-less and non-modal: apps trace a half-circle arc (first and last hugging the edge, the middle one bulging toward the screen center) that always fills the drawer's height β few apps spread out, many roll like a wheel on vertical drags. Opening rolls the icons in from the bottom. Both edges can be open at once, and the clock, command bar and gestures stay usable while they are. Close with a tap on empty space, a swipe toward the edge, or back.
- π― Notification-aware suggestions β apps with unread notifications get a capped boost in the guessed trio, so what demands attention is one tap away without drowning your habits.
- π€οΈ Weather by the clock (opt-in) β a tap-to-open weather chip, beside the clock or under the date, configurable in units (Β°C/Β°F) and what it shows (icon, temperature, or both). An optional living clock tints the clock's glow with the sky β golden sun, steel-blue rain, violet storms β as a static effect with zero battery cost. Uses your approximate last-known location and a key-less service (Open-Meteo), refreshed hourly; off by default.
- π§ Transparent brain β Settings β How suggestions work shows a live terminal-style report of the engine: its signal weights, how much data it keeps (and the database's size on disk, also available as a status-line field), the current context, and the live top-10 ranking. Long-press any app to boost it in the suggestions; long-press a home-screen element to jump straight to its settings.
- π Notification bubbles & message ticker (opt-in) β a count bubble on app icons for unread notifications, and an optional ticker under the clock that cycles your unread messages one at a time, fading between them. Reads notifications on-device only; nothing is stored or sent.
- π₯οΈ Customizable CLI status line β an optional terminal-style readout under the date; pick which fields show (battery, network, next alarm, apps launched today, free storage).
- π
Agenda stream β your next calendar events as quiet terminal lines under the status line: the next one leads in the accent color with a live countdown, later days get a
β tomorrowseparator, and the whole stream scrolls through the days ahead (3/7/14, configurable). Tap an event to unfold it in place β the location is one tap from navigation β or long-press to open it in your calendar app. Choose which calendars appear, or flip on Show only on gesture and bind Agenda to an edge swipe to summon it on demand. Read-only; events never leave the phone. - π Double-tap to lock the screen (tiny accessibility service, never reads screen content)
- π² One page, zero friction β swipe up for all apps (keyboard opens with it), swipe down for notifications, long-press for settings
- β¦ Assistant button β summons Gemini / Google Assistant from the command bar
- πΆοΈ Futuristic glass UI over your wallpaper β accent colors, wallpaper dimming, subtle animations (all optional)
- π Starter picks β on first run, choose your go-to apps (smart guesses pre-checked); they fill the suggestion slots until the launcher has learned your habits, and become a static-favorites mode if you turn predictions off
- π Clock tap opens the clock app β or any app you choose in settings
- π«₯ Hidden apps, app info / uninstall on long-press, web-search fallback when nothing matches
- π Auto-updates straight from GitHub releases β checked once a day, downloaded on Wi-Fi, installed after your tap
- πͺΆ Lightweight & battery-friendly β a single ~1.8 MB APK, no background services, no wakelocks, no trackers, no network calls except the update check
- On your phone, open the latest release and download
LastLauncher.apk. - Open the downloaded file. If Android asks, allow your browser to install unknown apps (Settings does this in two taps β it's the normal flow for apps outside the Play Store).
- Open LastLauncher, long-press an empty area β Settings β Set as default launcher.
- Optional but recommended: enable double-tap to lock β the app guides you to the accessibility toggle it needs.
That's it. Give it a few days of normal use and the suggestions start feeling telepathic. Updates arrive by themselves.
- Privacy: launch history stays in a local database. You can wipe it anytime (Settings β Forget everything learned) or turn predictions off entirely.
- The Bluetooth permission is only used to notice "a device just connected" as a prediction signal. Deny it and everything else still works.
- Requires Android 8.0 (API 26) or newer.
git clone https://github.com/Purgator/LastLauncher.git
cd LastLauncher
# point local.properties at your Android SDK (API 34), e.g.:
echo "sdk.dir=/path/to/android-sdk" > local.properties
./gradlew assembleDebug # debug APK
./gradlew testDebugUnitTest # unit tests
./gradlew lintDebug # lintRequirements: JDK 17, Android SDK platform 34 + build-tools 34.0.0. Gradle 8.7 / AGP 8.5.2 / Kotlin 1.9.24 come via the wrapper.
assembleRelease signs automatically when a keystore.properties file exists at the repo root (it is gitignored):
storeFile=release.keystore
storePassword=...
keyAlias=...
keyPassword=...Without it, the release build is unsigned. Auto-update relies on Android's same-signature rule, so released APKs must always be signed with the same key.
| Package | Role |
|---|---|
apps/ |
AppRepository β in-memory app catalog, icon cache warm-up, fuzzy search |
predict/ |
The launcher memory: UsageDb (pruned SQLite log), PredictionEngine (recency-decayed frequency Γ time affinity Γ transitions Γ context triggers), ContextSignals (Bluetooth / headset / charger receivers) |
lock/ |
LockService β accessibility service for lock-screen & notification-shade global actions |
update/ |
UpdateManager (GitHub releases check, throttled, Wi-Fi-only download) + ApkInstaller (PackageInstaller session with installer-intent fallback) |
settings/ |
Prefs + SettingsActivity (PreferenceFragmentCompat) |
| root | MainActivity β the one-page home screen; LauncherApp β wiring |
Design rules: everything heavier than a map lookup runs off the main thread; the UI thread only reads immutable snapshots. No coroutines, no DI framework, no Compose β plain Views keep the APK under 2 MB and cold start instant.
- Bump
versionCodeandversionNameinapp/build.gradle.kts. ./gradlew assembleRelease- Publish the APK as a release asset named exactly
LastLauncher.apkwith tagvX.Y.Z:Installed apps pick it up within a day (checks are throttled to daily and downloads happen on unmetered networks).cp app/build/outputs/apk/release/app-release.apk LastLauncher.apk gh release create vX.Y.Z LastLauncher.apk --title "..." --notes "..."