karol 96a6f8c344
Build and Release APK / Build APK (push) Successful in 4m3s
docs: standardize fork README and disclose AI-assisted development
2026-10-24 12:56:42 +02:00
2026-01-11 19:36:52 -08:00
2026-09-18 14:34:43 +02:00
2025-06-28 19:25:24 +00:00
2025-06-28 19:25:24 +00:00
2026-08-01 15:04:26 -04:00
2017-05-25 22:20:04 -04:00
2017-05-25 22:20:04 -04:00
2017-05-24 21:33:47 -04:00
2025-03-01 00:03:35 -05:00
2019-12-29 18:09:56 -05:00
2026-09-18 14:34:43 +02:00
2026-09-18 14:34:43 +02:00

QUIK — Remotrix Matrix bridge fork

An Android SMS messenger based on QUIK, with an integrated Remotrix service that bridges SMS messages to Matrix.

Upstream: octoshrimpy/quik. Fork repository: karol/quik.

Fork purpose · Changes from upstream · Requirements · Getting started · Configuration · Usage · Development · Upstream maintenance · Documentation · Credits · License

Fork purpose

The original Remotrix project was a standalone background bridge that required a separate, default SMS handler application. By deeply integrating Remotrix directly into Quik, we created a single, unified SMS application that offers a beautiful Material Design UI on the phone, while silently syncing all messages to your Matrix account (via Trixnity) in the background.

Changes from upstream

  • Native Matrix Background Sync: SMS messages sent or received on the phone are instantly bridged to your Matrix account.
  • Two-way Communication: Messages sent from Matrix are instantly forwarded as standard SMS messages from the phone.
  • Coroutines Deadlock Fix: Upgraded Room database dependencies to resolve fatal SQLiteConnectionPool deadlocks during the cryptographic key generation phases.
  • Enhanced Visual Formatting: Matrix messages now use intuitive prefixes (🟢 for outgoing, 🔴 for incoming) to clearly distinguish participants without requiring AppService double puppeting.
  • Gitea Actions CI/CD: Includes automated builds and automatic upstream fetching from the original Quik repository.

Requirements

  • An Android device with SMS support for sending and receiving messages.
  • A Matrix homeserver, bridge account, and Manager ID for Matrix integration.
  • JDK 17 and the Android SDK for local builds.
  • A persistent signing key for Release builds; Debug builds do not need release credentials.

Getting started

Download APKs from this fork's Gitea releases. For local development, run:

./gradlew assembleDebug

Debug APKs are written to presentation/build/outputs/apk/debug/. Debug builds use a separate application ID. Upstream download links in README.upstream.md distribute QUIK without this fork's Matrix integration.

Configuration

In QUIK settings, open the Matrix login dialog, sign in with the bridge account, and set your Manager ID. For release signing configuration, see Development.

Usage

Management room

When you log into the application with your Matrix bot account (@remotrix:yourserver.com) and specify a Manager ID (@you:yourserver.com), the bot creates a dedicated Management Room and invites you. From there, you can issue commands:

  • !new <phone_number> - Opens a new Matrix room dedicated to chatting with that phone number.
  • !close - Deletes a chat room.
  • !ping - Checks bot latency.
  • !reload - Restarts the background service.

Any non-command text sent in a dedicated phone number room will be sent as an SMS to that contact.

Reset Matrix

In Quik settings, open the Matrix login dialog and select Reset Matrix. Confirm the reset, remove the old rooms on your Matrix server, then sign in again. The reset removes local Matrix accounts, room mappings, encryption stores and bridge logs; SMS messages, Quik settings, the Manager ID and the backfill limit are preserved. New rooms use contact names from Android, and SMS history is copied again up to the configured limit.

History import

History import retries a failed message before advancing, with retry delays up to one minute. Synapse room-creation limits still apply. There is no fixed delay after each successful message. Progress is stored by native message type and ID, so identical SMS texts remain separate messages and saved progress is skipped when an unfinished import resumes. Reset Matrix clears this progress. The completion flag means all selected messages were handed to the persistent Matrix outbox (or intentionally excluded by forwarding settings); outbox delivery remains managed by Trixnity. Logcat reports progress and retry positions without logging SMS bodies or phone numbers.

Upgrading preserves an existing completed-import flag. It does not automatically replay old history: older versions did not retain per-message progress, so replaying that history could create duplicates. Checkpoint storage and the Matrix outbox use separate databases; an abrupt process/device failure between enqueueing a message and saving its checkpoint can still replay that last message.

Development

Persistent release signing

Release APKs require the permanent signing key. Missing signing configuration fails the build; release builds never fall back to a generated debug key. Pull requests build and test Debug without release secrets and do not publish releases.

Gitea repository Settings → Actions → Secrets must contain:

  • ANDROID_KEYSTORE_BASE64: base64-encoded permanent PKCS12 keystore.
  • ANDROID_KEYSTORE_PASSWORD: keystore password.
  • ANDROID_KEY_ALIAS: signing key alias.
  • ANDROID_KEY_PASSWORD: private key password.

The public certificate and its SHA-256 fingerprint are tracked in .gitea/release-signing.crt and .gitea/release-signing.sha256. CI checks the restored key and the finished Release APK against this fingerprint before publishing. The temporary CI key is removed even after failure. Do not regenerate the signing key between builds; back up the key and passwords securely. The initial local backup is .secrets/quik-release.p12 with credentials in .secrets/release-signing.json. These private files are ignored by Git and must not be committed.

For a local Release build, set ANDROID_KEYSTORE_PATH, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS and ANDROID_KEY_PASSWORD. Existing local .gradle/.gradlerc properties and the legacy CI environment names are also supported. Debug APKs use a separate application ID and are intended for development.

The former builds 50 and 51 used different disposable debug certificates. The new permanent key cannot update either installation in place; migrating once to the new certificate requires a reinstall. Subsequent Release updates keep the same signature.

Builds and releases

The project uses Gitea Actions for CI/CD:

  • build.yml: Runs tests and builds Debug APKs for pull requests to master. Pushes to master and v* tags also build signed Release APKs and publish a Gitea release after verification.
  • sync.yml: Runs weekly to automatically fetch changes from the original quik upstream repository and merge them into our fork.

To build manually:

./gradlew assembleDebug

The APK will be available in presentation/build/outputs/apk/debug/.

Automated release checks

The workflow pins JDK 17 so test and build tools use the same Java runtime. Before building or publishing APKs, Gitea Actions runs Robolectric tests against the actual InjectionWorkerFactory. They construct every worker type used by Quik and the Matrix bridge, verify SMS/MMS dependency injection, and exercise the Matrix watcher's service-start intent. These tests use simulated Android services and mocked repositories, without sending SMS or connecting to Matrix. Matrix room creation, client shutdown, reset and history import also have regression tests. Signing checks run separately.

Run the same runtime gate locally with JDK 17 and the Android SDK:

./gradlew :presentation:cleanTestDebugUnitTest :remotrix-sync:cleanTestDebugUnitTest :presentation:testDebugUnitTest :remotrix-sync:testDebugUnitTest
python3 .gitea/scripts/check_test_results.py

The gate rejects failures, missing required suites, and skipped critical tests. A failed gate stops the workflow before publication. These tests cover known regression scenarios; they do not replace testing the installed Release APK on Android devices.

Upstream maintenance

The sync workflow runs weekly and on manual dispatch, merging master from the configured Gitea upstream mirror. Merge or sync failures are reported by the workflow.

After each upstream merge, review SMS/Matrix forwarding, reset and history import behavior, and signing configuration. Run the regression checks described above. Keep this fork's README separate from the inherited documentation; refresh README.upstream.md from upstream when needed and retain its credits and license notices.

Documentation

README style guide.

Credits

Development of the changes maintained in this fork was carried out to a significant extent with assistance from AI coding agents, in collaboration with the repository owner.

QUIK continues QKSMS and includes work by the QUIK, Remotrix, and android-smsmms contributors. See upstream acknowledgments. Fork-specific issues belong in this fork's issue tracker.

License

GNU General Public License v3.0; see LICENSE. Upstream code and notices retain their original attribution.

S
Description
No description provided
Readme GPL-3.0 18 MiB
2026-10-24 13:01:48 +02:00
Languages
Kotlin 50%
Java 49.3%
Python 0.4%
CSS 0.2%