# KeepOrg for Android A KDBX synchronization adapter with no third-party dependencies: the server is reached with `java.net.HttpURLConnection`, JSON is parsed with the platform's `org.json`, and the two screens are built in code. The release APK is about 650 KB. ## How a KeePass application sees it `KeepOrgProvider` is a `DocumentsProvider`, so the mirrored databases appear in every file picker under "KeepOrg". KeePassDX and Keepass2Android open them like any other document. When the application closes a file it had opened for writing, the provider triggers a synchronization pass, which is how a save reaches the server. `SyncService` is a foreground service that holds the server's event stream open, so a change pushed by a colleague arrives without opening the app. The user turns it on from the main screen; it is not started at boot. Nothing the app holds may leave the device in a backup or a device transfer: `res/xml/data_extraction_rules.xml` and `res/xml/backup_rules.xml` exclude every domain. The session token authenticates as the user, and the mirrored files are the organization's password databases. The merge policy in `Mirror.decide` is the same table as the desktop client's `internal/client/decide.go`. **Keep the two in step.** ## Building Requirements: a JDK 17 installed (Gradle 8.9 or newer runs its daemon on it whatever JDK launches Gradle, per `gradle/gradle-daemon-jvm.properties`: AGP 8.7's lint, which every release build runs, fails on newer JDKs), and an Android SDK with `platforms;android-35` and `build-tools;35.0.0`. ```sh export ANDROID_HOME=$HOME/android-sdk make android # unsigned release APK, named for the F-Droid repository make android-lint # lint; the project is kept at zero findings make android-publish ``` The Gradle wrapper is not committed, so the Makefile calls whichever `gradle` is on `PATH`. Generate a wrapper if you prefer one: `gradle wrapper --gradle-version 8.10.2`. The release build is deliberately unsigned: the private F-Droid repository signs what it publishes. ### Building on an arm64 Linux host Google ships `aapt2` for linux-x86_64 only, so an aarch64 build host needs to be able to run it. Debian's own arm64 `aapt2` is too old to read the API 35 `android.jar`, so run the official one through QEMU instead: ```sh sudo dpkg --add-architecture amd64 sudo apt update sudo apt install qemu-user-static libc6:amd64 libstdc++6:amd64 zlib1g:amd64 ``` After that `aapt2` runs transparently and the build needs no further flags. Everything else in the Android toolchain (R8, the resource merger, zipflinger, apksig) is Java and architecture-independent. ## What is verified and what is not The APK builds clean and lint reports no issues, and the packaged DEX contains every class the manifest names. The app has **not** been exercised on a device or emulator: there was none available. The first real run is where to confirm the picker integration, the save-triggered sync and the notification.