Welcome to Akimeji – an open source Android project that brings desktop-style mascots to mobile. It supports two systems side-by-side:
- Shimeji (T1): classic shimejis
- Akimeji / Padoru (T2): festive padorus
Both systems share a similar architecture (network → decode → Room DB → overlay service) while keeping their code and data separate.
- UI: Jetpack Compose (Kotlin)
MainActivityrenders:- Padorus (T2) list from GitHub JSON
- Packs (T1) list from akimeji.com
- Downloaded Shimejis (T1) from Room (live)
- Downloaded Padorus (T2) from Room (live)
- Start/Stop buttons for each overlay service
- Network: Retrofit (two clients)
- Shimeji client base:
https://akimeji.com/ - Akimeji/Padoru client base:
https://hushino.github.io/ ApiServiceprovides:getPacks(@Url)for T1 packsdownloadImage(@Url)for arbitrary JSON/binary
- Shimeji client base:
- Data / Persistence
- T1 (Shimeji):
AppDatabase- Tables:
mascots,shimeji - Repos:
MascotRepository,ShimejiRepository - DAO:
MascotsDao,ShimejiDao
- Tables:
- T2 (Akimeji/Padoru):
Akimejit2Database- Tables:
pets, frames table - Repo:
PetRepository(suspend inserts on Dispatchers.IO) - DAO:
PetsDao,AkimejiDao
- Tables:
- T1 (Shimeji):
- Overlay services
ShimejiServicewithShimejiViewAkimejiServicewithAkimejiView- Each ticks and updates
WindowManager.LayoutParamsx/y/width/height
- Preferences
- T1:
Helper+AppConstants - T2:
HelperT2+AkimejiT2Constants
- T1:
We use clear prefixes to distinguish systems:
- T1 (Shimeji): classes and folders under
shimejiordataAkimejiT1 - T2 (Akimeji/Padoru): classes and folders under
akimejiordataAkimejiT2 - “Packs” → T1 content (akimeji.com); “Padorus” → T2 content (GitHub)
Examples:
- T1 DB:
AppDatabase,Mascots,ShimejiDao,ShimejiRepository - T2 DB:
Akimejit2Database,Pets,PetsDao,PetRepository - T1 service/view:
ShimejiService,ShimejiView - T2 service/view:
AkimejiService,AkimejiView
Retrofit instances in di/ServiceLocator.kt:
apiServiceShimeji→ basehttps://akimeji.com/- Packs JSON:
https://akimeji.com/packs/packv3.json
- Packs JSON:
apiServiceAkimeji→ basehttps://hushino.github.io/- Padorus list JSON:
${AppConstants.SERVER_BASE_PATH}akimejiT2/listThumbs2T2.json - Padoru download:
${AppConstants.SERVER_BASE_PATH}akimejiT2/thumb/{id}
- Padorus list JSON:
Notes:
getPacks(@Url)takes a full URL for flexibilitydownloadImage(@Url)used for both JSON text and binary assets
-
T1 Packs (Shimeji):
PacksViewModel.loadPacks()→ loads packs viaapiServiceShimeji- On Download: fetch asset stream, decode frames, save via T1 DAOs
-
T2 Padorus (Akimeji):
PacksViewModel.loadAkimejiThumbs()→ loads from GitHub; JSON may be a raw array or{ "shimejis": [...] }- On Download: fetch
thumb/{id}; if zip → unzip and decode frames; else decode single image - Save via
PetRepository.addMascotToDatabase(...)(Dispatchers.IO)
Live updates
- T1:
MascotRepository.getLiveDataOfMascotsInDb() - T2:
PetRepository.getLiveDataOfMascotsInDb()
Observed in MainActivity to power both “Downloaded” sections.
Declared in AndroidManifest.xml:
com.redbox.shimeji.live.shimejilife.system.shimeji.displayservice.ShimejiServicecom.redbox.shimeji.live.shimejilife.system.akimeji.displayservice.AkimejiService
Both are foreground services and require overlay permission.
UI controls in MainActivity:
- Start → launches service (initializes, builds views, starts ticking)
- Stop → stops service
- If no active selections, a hint prompts to add one first
Overlay permission:
- Checked with
Settings.canDrawOverlays(context)and requested via the system settings intent
ShimejiView/AkimejiView:- Pull frames from sprite services
- Draw at ~60 FPS (16 ms handler)
- Update window layout position every tick
- Support drag; fling optional per system
- Facing direction: bitmaps flip horizontally when moving left so sprites face travel direction
MainActivity is a single vertically scrollable screen containing:
- Downloaded Shimejis (image + name + Add/Remove)
- Downloaded Padorus (image + name + Add/Remove)
- Padorus (T2) list with Download buttons
- Packs (T1) list with banner + navigation to shimejis
PacksViewModel tracks loading and per-item states to disable buttons while downloading.
- All DB writes off the main thread (Dispatchers.IO)
- LiveData observed via
observeAsState()in Compose - Avoid synchronous Room calls from UI
Prereqs
- Android Studio (Giraffe or newer)
- JDK 11
Build
./gradlew assembleDebugRun
- Open in Android Studio → Run on device/emulator (Android 9+)
- Grant overlay permission when prompted
Contributions are welcome!
- Fork and create feature branches from
main - Follow naming and folder conventions (
shimeji/T1 vsakimeji/T2) - Use coroutines for IO; keep Room off the main thread
- Keep UI state in ViewModels
- Test services (start/stop/motion/drag) before submitting PRs
MIT (or repository license). See LICENSE if present.