From 7e04941bccb2683f8a6e3ee38a99c50129234dd1 Mon Sep 17 00:00:00 2001 From: Lena Date: Thu, 1 Jan 2026 00:00:00 +0000 Subject: rsend: push phone folders to a home SSH host over rsync A small Android app for one-way folder backup, a KISS alternative to Syncthing. It bundles rsync (built from pinned source via the NDK) and a pure-Go SSH transport, both shipped in the APK as lib*.so and run from the native library directory. rsend pins the host key, stores the ed25519 identity Keystore-encrypted, pushes each folder additively or as a mirror, and runs on demand or on a WiFi-only schedule. The build is self-contained and reproducible: make setup provisions the toolchain, make builds rsync, rsh, and the APK. --- app/build.gradle | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 app/build.gradle (limited to 'app/build.gradle') diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..56036ab --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,88 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +// Release signing is configured only if a local keystore.properties exists +// (gitignored). Otherwise the release build is unsigned, which is what F-Droid +// and reproducible-build verification want. +def keystoreProps = rootProject.file('keystore.properties') + +android { + namespace 'invalid.lena.rsend' + compileSdk 35 + + defaultConfig { + applicationId 'invalid.lena.rsend' + minSdk 30 + targetSdk 35 + versionCode 1 + versionName '0.1.0' + // Ship only the ABIs we build native libs for. + ndk { abiFilters 'arm64-v8a', 'x86_64' } + } + + signingConfigs { + if (keystoreProps.exists()) { + def props = new Properties() + keystoreProps.withInputStream { props.load(it) } + release { + storeFile rootProject.file(props['storeFile']) + storePassword props['storePassword'] + keyAlias props['keyAlias'] + keyPassword props['keyPassword'] + // Include v1 (JAR) signing too; some sideload installers + // (Samsung One UI on Android 11/12) reject v2-only APKs with + // "problem parsing the package". + enableV1Signing true + enableV2Signing true + enableV3Signing true + } + } + } + + buildTypes { + release { + minifyEnabled false + if (keystoreProps.exists()) { + signingConfig signingConfigs.release + } + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } + + buildFeatures { + buildConfig true + } + + // Native executables ship as lib*.so and must be extracted so we can exec + // them from nativeLibraryDir (useLegacyPackaging => extractNativeLibs=true). + packaging { + jniLibs { + useLegacyPackaging true + } + } + + // Reproducible / F-Droid: do not embed the Google dependency metadata block. + dependenciesInfo { + includeInApk false + includeInBundle false + } +} + +dependencies { + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'androidx.work:work-runtime-ktx:2.10.0' + + // The real org.json shadows the android.jar stub so JSON tests run on the JVM. + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.json:json:20240303' +} -- cgit v1.2.3