Add contents:write permission and replace upload-artifact with an API call that creates/reuses the release for the tag and attaches the signed APK as a downloadable asset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PaperScan
Een lokale, privacy-bewuste documentscanner voor Android. Scant papieren documenten met de camera, detecteert automatisch de randen, corrigeert het perspectief en bundelt meerdere pagina's in één PDF. Die PDF kun je delen via Android of rechtstreeks uploaden naar je zelf-gehoste Paperless-ngx.
Alles gebeurt op het toestel. Camerabeelden, randdetectie (OpenCV) en PDF-creatie verlaten je telefoon niet. De enige netwerkverbinding is de optionele upload naar de Paperless-server die jij zelf configureert. Er is geen AI of cloud-verwerking.
Functies
- 📷 Camerapreview met multi-page vastleggen (pagina na pagina toevoegen)
- ✂️ Automatische randdetectie + perspectiefcorrectie (OpenCV), met handmatige hoekcorrectie
- 🎨 Filters per pagina: kleur, grijstinten, zwart-wit (documentmodus)
- 🔄 Pagina's draaien, herordenen en verwijderen
- 📄 Export naar multi-page PDF (A4 of originele grootte)
- ☁️ Directe upload naar Paperless-ngx of delen via het Android-deelmenu
- 🔐 API-token versleuteld opgeslagen (Android Keystore / EncryptedSharedPreferences)
Tech
Kotlin · Jetpack Compose · CameraX · OpenCV (org.opencv:opencv via Maven) ·
PdfDocument · OkHttp · DataStore. minSdk 26 (Android 8), target/compile SDK 35.
Lokaal bouwen
- Open het project in Android Studio (Ladybug of nieuwer). Dit genereert automatisch
de Gradle wrapper (
gradlew+gradle-wrapper.jar). - Sluit een toestel aan of start een emulator en druk op Run.
Of vanaf de command line (na gradle wrapper één keer):
./gradlew assembleDebug # debug-APK, geen signing nodig
./gradlew assembleRelease # release-APK, vereist signing (zie onder)
De release-APK verschijnt in app/build/outputs/apk/release/.
Signing key aanmaken
Nodig voor release-builds (en dus voor updates die elkaar kunnen overschrijven).
keytool -genkey -v -keystore release.jks -keyalg RSA -keysize 2048 \
-validity 10000 -alias paperscan
Bewaar release.jks veilig en buiten git (staat al in .gitignore).
Voor lokale release-builds maak je een keystore.properties in de projectroot
(zie keystore.properties.example):
storeFile=/pad/naar/release.jks
storePassword=...
keyAlias=paperscan
keyPassword=...
Bouwen via Gitea Actions
De workflow .gitea/workflows/build.yml bouwt een getekende release-APK bij elke
versietag (git tag v0.1.0 && git push --tags) of via een handmatige run.
Zet in je Gitea-repo onder Settings → Actions → Secrets deze secrets klaar:
| Secret | Inhoud |
|---|---|
SIGNING_KEYSTORE_BASE64 |
base64 -w0 release.jks (de keystore als base64) |
SIGNING_STORE_PASSWORD |
wachtwoord van de keystore |
SIGNING_KEY_ALIAS |
bv. paperscan |
SIGNING_KEY_PASSWORD |
wachtwoord van de sleutel |
De build gebruikt env-vars, dus er komt niets gevoeligs in de repo terecht. De APK
komt als artifact paperscan-release beschikbaar bij de workflow-run.
Zorg dat je Gitea Actions-runner Docker-images kan trekken (
mingc/android-build-box).
Paperless-ngx instellen (in de app)
- Maak in Paperless een API-token aan: Instellingen → profiel → API-token
(of via
/api/token/). - Open in PaperScan het tandwiel → vul server-URL (bv.
https://paperless.thuis.lan) en het token in → Verbinding testen → Opslaan.
Gebruik bij voorkeur https; bij http:// waarschuwt de app dat token en documenten
onversleuteld over het netwerk gaan.
Projectstructuur
app/src/main/java/eu/geyskens/pdfscan/
├── PaperScanApp.kt # Application; laadt OpenCV native libs
├── MainActivity.kt # Compose host + navigatie
├── ScanViewModel.kt # scan-sessie, rendering, export, upload
├── data/ # Page-model, ScanFilter, SettingsRepository
├── scan/ # EdgeDetector, ImageProcessor, BitmapIo (OpenCV)
├── pdf/ # PdfBuilder (multi-page PDF)
├── paperless/ # PaperlessClient (OkHttp REST)
└── ui/screens/ # Camera, Pages, Crop, Export, Settings
Roadmap / ideeën
- Live randdetectie-overlay tijdens het richten (nu bij vastleggen)
- OCR-tekstlaag (bv. Tesseract) volledig on-device
- Batch-import van bestaande foto's uit de galerij