Skip to content

Repository files navigation

Magic 8-Ball Widget

Vibe Coded by George Keller

A 2x2 Android home-screen widget that answers your yes/no questions. Tap the ball and it spins over, a fortune floats up through the liquid window, holds for a few seconds, then rolls back to the resting "8". Every tap gives a fresh, uniformly random answer.

License: MIT minSdk 26 Kotlin Dependencies: none

Magic 8-Ball widget: the ball spins over, a fortune floats up, then it rolls back to the 8

Highlights

  • No third-party libraries. The widget uses only the Android framework and the Kotlin standard library. No AndroidX, no Material, no support libraries, so the APK stays tiny.
  • No bundled art. The glossy ball, the liquid window, and the floating fortune triangle are drawn at runtime on a Canvas with per-pixel shading. There are no images or GIFs in the app.
  • One quiet launcher icon. The app itself has no screen to browse. Its launcher icon simply offers to pin the widget to your home screen, then closes.
  • Offline and private. No network, no accounts, no analytics, no ads.

How the reveal works

A home-screen widget does not own its pixels. The launcher draws them from a RemoteViews description, so there is no place to run a normal animation loop. The reveal is therefore a short series of bitmaps pushed to the launcher, one pose at a time:

Concern Approach
The motion An 11-pose sequence: spin to reveal the window, float the fortune up, hold, roll back
Rendering Each frame is drawn on a Canvas, then pushed with setImageViewBitmap
IPC size Frames render at 384 px, which stays within the RemoteViews transaction limit
Reliability The sequence runs inside goAsync() so the process survives the four-second hold
Repeat taps A per-widget guard ignores taps that land while a reveal is playing
Feedback A short haptic tick fires the moment you tap

Build and install

Requires the Android SDK (API 35) and JDK 17.

git clone https://github.com/georgeckeller/magic-8-ball.git
cd magic-8-ball
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

Then add the widget one of two ways:

  • Tap the Magic 8-Ball app icon and accept the prompt to pin it, or
  • Long-press the home screen, choose Widgets, find Magic 8-Ball, and drop it on the grid.

Every push to main also builds the debug APK in GitHub Actions (see .github/workflows/build.yml), and the APK is attached to the run as an artifact.

Project structure

app/src/main/
├── java/com/vibe/magic8ball/
│   ├── Magic8BallWidgetProvider.kt   Taps, the reveal sequence, and the RemoteViews updates
│   ├── Magic8BallRenderer.kt         Draws the glossy ball, liquid window, and fortune on a Canvas
│   ├── PinWidgetActivity.kt          Launcher shim that offers to pin the widget
│   └── EightBallMessages.kt          The 20 answers and the random draw
├── res/
│   ├── layout/widget_magic8ball.xml  A single ImageView
│   ├── xml/magic8ball_widget_info.xml Widget metadata (2x2)
│   ├── drawable/ic_launcher.xml      Vector 8-ball icon and widget preview
│   └── values/strings.xml
└── AndroidManifest.xml               One activity (the pin shim) and one widget receiver
  • minSdk 26 (Android 8.0)
  • targetSdk / compileSdk 35

License

Released under the MIT License. See LICENSE.


Vibe Coded by George Keller

About

A tiny, dependency-free Android home-screen Magic 8-Ball widget, drawn on a Canvas in Kotlin.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages