No description
Find a file
ltadeu6 e4e960024d
Bump version to 0.1.1
Fix push notifications: PUSH_GATEWAY_URL was empty in v0.1.0 because
it was externalized to BuildConfig before android-signing-env exported it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:04:42 -03:00
app Bump version to 0.1.1 2026-05-25 17:04:42 -03:00
gateway Add push notifications via local sync loop and FCM 2026-05-17 19:55:59 -03:00
gradle Add push notifications via local sync loop and FCM 2026-05-17 19:55:59 -03:00
.gitignore Add push notifications via local sync loop and FCM 2026-05-17 19:55:59 -03:00
AGENTS.md Add chat UX improvements and fix DM naming sync 2026-05-16 16:24:32 -03:00
build.gradle.kts Add push notifications via local sync loop and FCM 2026-05-17 19:55:59 -03:00
CLAUDE.md Initial commit 2026-05-14 23:22:06 -03:00
flake.lock Add Nix shell and local 16KB-aligned Olm build 2026-05-16 15:59:41 -03:00
flake.nix Add push notifications via local sync loop and FCM 2026-05-17 19:55:59 -03:00
gradle.properties Initial commit 2026-05-14 23:22:06 -03:00
gradlew Add Nix shell and local 16KB-aligned Olm build 2026-05-16 15:59:41 -03:00
gradlew.bat Add Nix shell and local 16KB-aligned Olm build 2026-05-16 15:59:41 -03:00
README.md Add release signing, fix release build, update README 2026-05-25 16:21:07 -03:00
settings.gradle.kts Initial commit 2026-05-14 23:22:06 -03:00
settings.json Initial commit 2026-05-14 23:22:06 -03:00
state.md Add emulator and device connection notes to state.md 2026-05-17 16:09:46 -03:00

matrix-android

A minimal Android Matrix chat client with a terminal aesthetic — dark background, green monospace text, < / > message prefixes — inspired by the matrix-message living-room terminal app.

Features

  • Browser-based SSO login (Custom Tabs — no password stored by the app)
  • Password login fallback
  • Room list after login
  • Text-only chat (no images, no avatars)
  • Real-time sync via Matrix /sync long-polling
  • Persistent session (survives app restart)
  • End-to-end encryption (E2EE) via libolm / Megolm
  • SAS device verification
  • Push notifications (foreground via sync loop; background via FCM + Cloudflare Worker)

Download

Pre-built APKs are available on the releases page.

Screenshots / UI description

> MATRIX LOGIN          (login screen)
────────────────────────
homeserver: matrix.org
[ LOGIN WITH BROWSER (SSO) ]
──── or password login ────
username: @user:matrix.org
password: ••••••••
[ LOGIN ]

> ROOMS                 (room list)
────────────────────────────────────────
> My Room
  !abc123:matrix.org
> Family chat
  !xyz456:example.com
[logout]

< back          My Room (chat screen)
──────────────────────────────────────
< alice
  hello!
                         > hey there >
< alice
  how are you?
──────────────────────────────────────
> message...

Requirements

  • Android Studio Ladybug (2024.2) or later
  • Android SDK 35
  • minSdk 26 (Android 8.0)

Build

  1. Clone the repo
  2. Open the matrix-android/ folder in Android Studio
  3. Let Gradle sync (it downloads all dependencies automatically)
  4. Run on a device or emulator

If you prefer the command line, first generate the Gradle wrapper:

cd matrix-android
gradle wrapper --gradle-version 8.9
./gradlew assembleDebug

The APK is at app/build/outputs/apk/debug/app-debug.apk.

NixOS / CLI build

This repo includes a flake.nix dev shell with:

  • JDK 17
  • Gradle
  • Android SDK 35 + Build Tools 35.0.0

Enter the shell and build:

cd matrix-android
nix develop
gradle wrapper --gradle-version 8.9
./gradlew assembleDebug

The shell exports ANDROID_HOME / ANDROID_SDK_ROOT and rewrites local.properties to the Nix SDK path so Gradle uses the packaged Android SDK instead of a user-specific installation.

Login

  1. Enter your homeserver (default: matrix.org)
  2. Tap LOGIN WITH BROWSER (SSO)
  3. A browser tab opens to the homeserver's login/SSO page
  4. After authenticating, you are redirected back to the app automatically

The app registers the matrixandroid://sso URI scheme for this redirect.

Password

Enter your full Matrix username (@user:homeserver.tld) and password directly.

Architecture

app/src/main/java/com/ltadeu6/matrix/
├── MainActivity.kt              — single Activity; handles SSO deep link
├── navigation/
│   └── AppNavigation.kt         — Compose NavHost (Login → Rooms → Chat)
├── auth/
│   ├── LoginScreen.kt           — login UI
│   └── LoginViewModel.kt        — SSO URL builder, login calls
├── rooms/
│   └── RoomListScreen.kt        — joined rooms list
├── chat/
│   ├── ChatScreen.kt            — message list + input bar
│   └── ChatViewModel.kt         — sends messages, maps sync state
├── matrix/
│   ├── MatrixApi.kt             — Retrofit interface (Matrix REST v3)
│   ├── MatrixModels.kt          — serialization data classes + local models
│   ├── MatrixSession.kt         — singleton: auth, sync loop, state flows
│   ├── CryptoService.kt         — E2EE: Olm/Megolm, OTK management
│   ├── VerificationService.kt   — SAS device verification
│   ├── NotificationHelper.kt    — notification channel + posting
│   └── MatrixFirebaseMessagingService.kt — FCM push (app killed)
├── verification/
│   └── VerificationScreen.kt    — verification UI
└── ui/theme/
    └── Theme.kt                 — terminal color scheme (green on black)

State flow: MatrixSession owns a syncState: StateFlow<SyncState> that all screens observe. The background sync loop continuously updates it via /sync long-polling.

Push notifications

When the app is in the foreground or background, notifications are fired directly from the sync loop. When the app is killed, push is delivered via FCM through a self-hosted Cloudflare Worker (gateway/) that acts as a Matrix push gateway.

Dependencies

Library Purpose
Jetpack Compose + Material3 UI
Navigation Compose Screen routing
Retrofit 2 + OkHttp Matrix HTTP API
kotlinx.serialization JSON parsing
retrofit2-kotlinx-serialization-converter Retrofit ↔ kotlinx bridge
kotlinx.coroutines Async / sync loop
androidx.browser (Custom Tabs) SSO browser login
libolm (native) E2EE: Olm/Megolm encryption
Firebase Messaging FCM push notifications

Known limitations

  • No media/file messages (text only)
  • Room list is not paginated (loads whatever /sync returns on first sync)