The preferred development setup is VS Code plus Codex, backed by the shared
Android toolchain in E:\AndroidDev. Android Studio is installed and can be
used for Logcat, profiling, layout inspection, and SDK management, but it is not
required for day-to-day edits.
| Purpose | Path |
|---|---|
| Android Studio | E:\AndroidDev\android-studio |
| Gradle JDK | E:\AndroidDev\android-studio\jbr |
| Legacy JDK 17 | E:\AndroidDev\JDK\jdk-17.0.15+6 |
| Android SDK | E:\AndroidDev\SDK |
| Gradle user home | E:\AndroidDev\.gradle |
| Android user home | E:\AndroidDev\.android |
Project scripts source scripts/dev-env.ps1 so command-line builds, Codex
runs, and Android Studio use the same SDK and cache locations.
Current project toolchain:
- Android Gradle Plugin:
9.2.1(built-in Kotlin; no separate Kotlin Android plugin) - Gradle wrapper:
9.4.1 - Gradle runtime JDK: Android Studio bundled JBR 21 on
E:\AndroidDev - Compose compiler plugin:
2.2.20 - App source/target compatibility: Java 17
- Compile SDK: Android API 36 with extension 20
- Target SDK: 36
Repository order matters. settings.gradle.kts keeps official google() and
mavenCentral() before the Aliyun mirrors, limits google() to Android/Google
groups, and leaves the Aliyun public mirror last.
FFmpegKit local core: app/build.gradle.kts requires the self-built local AAR
below. There is no Maven fallback for FFmpegKit, and release CI verifies the
recorded SHA-256 instead of downloading a prebuilt third-party fork artifact.
app/libs/ffmpeg-kit-next-7.1.0.aar- source:
https://github.com/arthenica/ffmpeg-kit-next - tag:
v7.1.0 - commit:
1e64a8cdda1b045b014c0a54e9d395929c7b6ccc - build command: replacement build command must be recorded before a tagged release
- SHA-256:
d1f2512e806ac3ff99b2f4c3d2e36fcca8c5c0eec548d84da81cf94d054cf406 - ABI:
arm64-v8a - packaged license files include LAME, libiconv, libvpx, Opus, x264, x265, and cpu-features notices
- source:
The published APK is arm64-only to keep size down and match the Office2PDF native library.
app/libs/smart-exception-common-0.2.1.jar- source:
https://repo1.maven.org/maven2/com/arthenica/smart-exception-common/0.2.1/smart-exception-common-0.2.1.jar - SHA-256:
1cad0fb4dfa01755a014331b5ed199281d2c3fab5aca5c9d7abd0b41d0ec3f7b
- source:
app/libs/smart-exception-java-0.2.1.jar- source:
https://repo1.maven.org/maven2/com/arthenica/smart-exception-java/0.2.1/smart-exception-java-0.2.1.jar - SHA-256:
5b96aaa5f191dedbef72fb0c38f1a2b01807920afc0d92a75a2acd6e0cc7703c
- source:
The recorded FFmpegKitNext AAR is a checked-in release input so clean CI
checkouts can build without downloading a third-party fork artifact. Other
app/libs binaries, including optional smart-exception JAR caches, stay ignored
by git. If the FFmpegKitNext AAR is absent, Gradle fails during configuration
with a clear message.
MP3 output needs libmp3lame. The app probes FFmpeg's encoder list before MP3
export and shows a clear compatibility failure when the bundled package lacks
the encoder. MP3 export has been verified on a physical device.
The limited Office compatibility renderer is reproducible from
native/office2pdf-jni. It pins developer0hye/office2pdf at release commit
8f34766a1d1567b9d81d606e45ea690987a7c6ed (v0.6.7) and exposes
convertBytesWithFontPaths, which passes app-private CJK font directories
through ConvertOptions.font_paths.
For the server workflow, copy native/office2pdf-jni/ to
/root/zenconverter-office2pdf-build/office2pdf-jni/, then run:
bash build-arm64-v8a.shThe script writes the compiled shared library to
/root/zenconverter-office2pdf-build/built-jniLibs/arm64-v8a/libzen_office2pdf.so.
Copy that file over app/src/main/jniLibs/arm64-v8a/libzen_office2pdf.so.
Set ANDROID_NDK_HOME to the NDK root if it is not installed in a common
system path.
The checked-in August 21, 2026 rebuild is 32,823,808 bytes with SHA-256
2b36e907b772514cf8b5840de338dc21ffd6100b5e3e8f0487b6cd77b2958d5b and
exports convertBytesWithFontPaths. Do not validate the CJK fix with a
Kotlin-only build: an older shared library can still start through the legacy
convertBytes fallback, but it cannot pass the bundled CJK font directory.
Chinese text rendering has been manually verified on an arm64 physical device;
layout fidelity remains limited. Codex does not run this build or install step.
settings.gradle.kts resolves the com.android.application plugin id through
its normal pluginManagement repositories (official google() first, then
Maven Central and the Aliyun mirrors). If the AGP 9.x plugin marker ever fails
to resolve in this local setup, map it explicitly through
pluginManagement.resolutionStrategy to com.android.tools.build:gradle:<version>
and keep the official google() repository ahead of the mirrors.
Run commands from the project root:
powershell -ExecutionPolicy Bypass -File .\scripts\build-debug.ps1
powershell -ExecutionPolicy Bypass -File .\scripts\install-debug.ps1
powershell -ExecutionPolicy Bypass -File .\scripts\launch-debug.ps1Use build-debug.ps1 for a local smoke build, install-debug.ps1 for physical
device testing, and launch-debug.ps1 after the app is installed.
| Component | Estimated Size |
|---|---|
| JDK 17 or 21 | 0.3 to 0.6 GB |
| Android command-line tools | 0.3 to 0.5 GB |
| platform-tools / adb | 0.03 to 0.08 GB |
| build-tools | 0.08 to 0.15 GB |
| Android SDK platform | 0.15 to 0.3 GB |
| Gradle cache | 1.5 to 3.0 GB |
| Kotlin, AGP, Compose, AndroidX cache | 1.0 to 2.5 GB |
| Project build cache | 0.8 to 2.0 GB |
Expected practical minimum: 4 to 6 GB. Recommended breathing room: 8 to 10 GB.
Do not install the Android emulator or NDK until the project explicitly needs them. Self-building FFmpeg can raise the disk requirement to 20 to 40 GB. The July 12, 2026 FFmpegKitNext build succeeded on a 4 vCPU / 7.6 GiB RAM Ubuntu 24.04 server after adding a 12 GiB swap file; peak root filesystem usage was about 24 GB.
- Confirm
E:\AndroidDev\android-studio\jbr\bin\java.exe -versionworks. - Confirm
E:\AndroidDev\SDK\platform-tools\adb.exe devicessees the phone. - Run
powershell -ExecutionPolicy Bypass -File .\scripts\build-debug.ps1. - Run
powershell -ExecutionPolicy Bypass -File .\scripts\install-debug.ps1. - Launch from the phone or run
scripts\launch-debug.ps1.
Add dependencies one at a time. After adding each dependency:
- build the app,
- run on a physical device if it touches media or file access,
- record it in
third_party/THANKS.md, - update
docs/license-and-attribution.md.