Files
internaluploader/android
michal 4c6c897b10 app v1.1.0: delete-after-upload, duplicate status, clear history, open-with
- Delete the source file once an upload is confirmed (best-effort: SAF
  picks get a persisted read+write grant and are removed; read-only
  shared streams are left in place). Cache copy always removed. A removed
  source shows as 'removed from phone'.
- Distinguish duplicates: a HEAD (or the server's 200 existed) marks the
  item 'Duplicate · already on server' — content is never re-sent or
  overwritten, since the name IS the sha256. Different content = different
  hash = a new file, not a duplicate.
- 'Clear history' app-bar button clears finished/duplicate/failed rows.
- Register as an 'Open with' target (ACTION_VIEW, content/file) in
  addition to the existing share-sheet target.
- Room schema v2 (destructive fallback; queue is ephemeral).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-29 00:07:30 +01:00
..
2026-09-28 23:18:15 +01:00
2026-09-28 23:18:15 +01:00
2026-09-28 23:18:15 +01:00
2026-09-28 23:18:15 +01:00

InternalUploader — Android app

Native Kotlin app. Pair once (QR from the browser pairing page, or in-app SSO via a Custom Tab), then share anything to it — files upload in the background as <sha256>.<ext> and failed uploads retry until they land. No settings screen; the server address is baked in (BuildConfig.DEFAULT_SERVER_URL) and can be replaced only by what a pairing QR carries.

Building

JAVA_HOME=~/.jdks/jdk17 ./gradlew assembleRelease
  • Needs an Android SDK at the path in local.properties (not committed; sdk.dir=$HOME/Android/Sdk), platform android-36.
  • Gradle 8.14.3 (wrapper), AGP 8.11.1, Kotlin 2.1.21. The Gradle daemon needs JDK 17–24 — the system java (25) is too new, hence the explicit JAVA_HOME.
  • Output: app/build/outputs/apk/release/app-release.apk.

Release signing

app/build.gradle.kts reads ~/.internaluploader/signing.properties:

storeFile=/home/<you>/.internaluploader/release.p12
storePassword=…
keyAlias=internaluploader
keyPassword=…

The PKCS12 keystore was generated with:

keytool -genkeypair -keystore ~/.internaluploader/release.p12 -storetype PKCS12 \
  -alias internaluploader -keyalg RSA -keysize 4096 -validity 10000

The keystore never enters the repo. If signing.properties is missing, the release build is unsigned (fine for compile checks, not for F-Droid). Keep the keystore backed up: F-Droid clients pin the app signature, so a lost key means uninstall/reinstall on every device.

Publishing to the private F-Droid repo

thelab-kubernetes-pulumi/scripts/fdroid/publish.py add app/build/outputs/apk/release/app-release.apk

Bump versionCode/versionName in app/build.gradle.kts for every published build — F-Droid only offers updates on a higher versionCode.