8 Commits

Author SHA1 Message Date
Michachatz 06962a32ed Merge pull request #2 from Michatec/renovate/configure
Configure Renovate
2026-05-26 00:02:30 +02:00
renovate[bot] 7f5d27f656 Add renovate.json 2026-04-15 21:35:13 +00:00
Michatec 7b561fe428 Merge branch 'master' of https://github.com/Michatec/michas-droid 2026-04-09 14:27:07 +02:00
Michatec 688d03ba8b - Migrate build system to Kotlin DSL (build.gradle.kts, settings.gradle.kts)
- Upgrade `compileSdk` and `targetSdk` to 36
- Add German (`de`) localization and string resources
- Add Michachatz F-Droid repository to default list
- Update dependencies and plugins in `libs.versions.toml`
- Remove manual signing configuration from README.md
- Refactor code to use non-deprecated `alpha` property and context-based string retrieval
- Clean up `buildConfig` and locale filtering logic
2026-04-09 13:34:45 +02:00
Michachatz fb06922278 Remove version badge from README
Removed a version badge from the README.
2026-03-30 00:22:31 +02:00
Michachatz 821d847ce2 Update license link in README.md 2026-03-30 00:22:19 +02:00
Michachatz 5a76773ae3 Enhance README with project badges
Added badges for version, downloads, issues, contributors, and license.
2026-03-29 23:55:39 +02:00
Michachatz f303844e28 Add warning about Google identity requirements
Added a warning about upcoming Google requirements for apps on certified Android devices.
2026-03-25 07:37:58 +01:00
14 changed files with 306 additions and 140 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
/*
!/.gitignore
!/build.gradle
!/settings.gradle
!/build.gradle.kts
!/settings.gradle.kts
!/COPYING
!/extra
!/gradle
+13 -9
View File
@@ -1,9 +1,22 @@
# Michas Droid
<p align="center">
<a href="https://github.com/michatec/michas-droid/releases"><img src="https://img.shields.io/github/downloads/michatec/michas-droid/total.svg?style=flat-square" /></a>
<a href="https://github.com/michatec/michas-droid/issues"><img src="https://img.shields.io/github/issues-raw/michatec/michas-droid.svg?style=flat-square&label=issues" /></a>
<a href="https://github.com/michatec/michas-droid/graphs/contributors"><img src="https://img.shields.io/github/contributors/michatec/michas-droid?style=flat-square" /></a>
<a href="https://github.com/michatec/michas-droid/blob/master/COPYING"><img src="https://img.shields.io/github/license/michatec/michas-droid?style=flat-square" /></a>
</p>
Yet another F-Droid client.
[![Release](https://img.shields.io/github/v/release/michatec/michas-droid)](https://github.com/michatec/michas-droid/releases/latest)
## Warning ⚠️
Google has announced that, starting in 2026/2027, all apps on certified Android devices will require the developer to submit personal identity details directly to Google.
Since the developers of this app do not agree to this requirement, this app will no longer work on certified Android devices after that time.
## Description
Unofficial F-Droid client in the style of the classic one.
@@ -34,15 +47,6 @@ or sharing local repositories nearby.
Specify your Android SDK path either using the `ANDROID_HOME` environment variable, or by filling out the `sdk.dir`
property in `local.properties`.
Signing can be done automatically using `keystore.properties` as follows:
```properties
store.file=/path/to/keystore
store.password=key-store-password
key.alias=key-alias
key.password=key-password
```
Run `./gradlew assembleRelease` to build the package, which can be installed using the Android package manager.
## License
-113
View File
@@ -1,113 +0,0 @@
buildscript {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath libs.gradle
classpath libs.kotlin.gradle.plugin
}
}
apply plugin: 'com.android.application'
android {
namespace 'com.michatec.store'
compileSdk 36
defaultConfig {
applicationId 'com.michatec.store'
minSdk 30
targetSdk 36
versionCode 17
versionName '1.7'
def languages = [ 'en' ]
buildConfigField 'String[]', 'LANGUAGES', '{ "' + languages.join('", "') + '" }'
resConfigs languages
}
buildFeatures {
buildConfig = true
}
sourceSets {
main {
java.srcDirs += 'src/main/kotlin'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
flavorDimensions "distributor"
productFlavors {
michas {
dimension "distributor"
buildConfigField "boolean", "FLAVOR_FDROID", "false"
}
fdroid {
dimension "distributor"
buildConfigField "boolean", "FLAVOR_FDROID", "true"
}
}
buildTypes {
debug {
minifyEnabled false
shrinkResources false
}
release {
minifyEnabled true
shrinkResources false
}
}
def keystorePropertiesFile = rootProject.file('keystore.properties')
if (keystorePropertiesFile.exists()) {
def keystoreProperties = new Properties()
keystoreProperties.load(keystorePropertiesFile.newDataInputStream())
def signing = [
storeFile: keystoreProperties['store.file'],
storePassword: keystoreProperties['store.password'],
keyAlias: keystoreProperties['key.alias'],
keyPassword: keystoreProperties['key.password']
]
if (!signing.any { _, v -> v == null }) {
signingConfigs {
primary {
storeFile file(signing.storeFile)
storePassword signing.storePassword
keyAlias signing.keyAlias
keyPassword signing.keyPassword
enableV2Signing false
}
}
}
}
}
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
implementation libs.kotlin.stdlib
implementation libs.fragment.ktx
implementation libs.viewpager2
implementation libs.vectordrawable
implementation libs.okhttp
implementation libs.rxjava
implementation libs.rxandroid
implementation libs.jackson.core
implementation libs.picasso
implementation libs.freedroidwarn
}
+80
View File
@@ -0,0 +1,80 @@
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.michatec.store"
compileSdk = 36
defaultConfig {
applicationId = "com.michatec.store"
minSdk = 30
targetSdk = 36
versionCode = 18
versionName = "1.8"
val languages = listOf("en", "de")
buildConfigField("String[]", "LANGUAGES", "{ \"${languages.joinToString("\", \"")}\" }")
@Suppress("UnstableApiUsage")
androidResources {
localeFilters += languages
}
}
buildFeatures {
buildConfig = true
}
sourceSets {
getByName("main") {
kotlin.directories += "src/main/kotlin"
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
flavorDimensions += "distributor"
productFlavors {
create("michas") {
dimension = "distributor"
buildConfigField("boolean", "FLAVOR_FDROID", "false")
}
create("fdroid") {
dimension = "distributor"
buildConfigField("boolean", "FLAVOR_FDROID", "true")
}
}
buildTypes {
getByName("debug") {
isMinifyEnabled = false
isShrinkResources = false
}
getByName("release") {
isMinifyEnabled = true
isShrinkResources = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard.pro"
)
}
}
}
dependencies {
implementation(libs.kotlin.stdlib)
implementation(libs.core.ktx)
implementation(libs.fragment.ktx)
implementation(libs.viewpager2)
implementation(libs.vectordrawable)
implementation(libs.okhttp)
implementation(libs.rxjava)
implementation(libs.rxandroid)
implementation(libs.jackson.core)
implementation(libs.picasso)
implementation(libs.freedroidwarn)
}
+3 -4
View File
@@ -1,8 +1,8 @@
[versions]
core-ktx = "1.18.0"
fragment-ktx = "1.8.9"
freedroidwarn = "V1.10"
gradle = "9.1.0"
gradle-toolchains-foojay-resolver-convention = "1.0.0"
jackson-core = "2.21.2"
kotlin = "2.3.20"
okhttp = "5.3.2"
@@ -13,11 +13,10 @@ vectordrawable = "1.2.0"
viewpager2 = "1.1.0"
[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragment-ktx" }
freedroidwarn = { group = "com.github.woheller69", name = "FreeDroidWarn", version.ref = "freedroidwarn" }
gradle = { group = "com.android.tools.build", name = "gradle", version.ref = "gradle" }
jackson-core = { group = "com.fasterxml.jackson.core", name = "jackson-core", version.ref = "jackson-core" }
kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
picasso = { group = "com.squareup.picasso", name = "picasso", version.ref = "picasso" }
@@ -27,4 +26,4 @@ vectordrawable = { group = "androidx.vectordrawable", name = "vectordrawable", v
viewpager2 = { group = "androidx.viewpager2", name = "viewpager2", version.ref = "viewpager2" }
[plugins]
foojay = { id = "org.gradle.toolchains.foojay-resolver-convention", version.ref = "gradle-toolchains-foojay-resolver-convention" }
android-application = { id = "com.android.application", version.ref = "gradle" }
+6
View File
@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}
-5
View File
@@ -1,5 +0,0 @@
plugins {
id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0"
}
rootProject.name = "michas-droid"
include ':'
+24
View File
@@ -0,0 +1,24 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
rootProject.name = "michas-droid"
include(":")
@@ -89,6 +89,12 @@ data class Repository(
"Michachatz official repository. Everything in this repository is always built from the source code.",
21, true, "3546DCBDD900F280EE2161CC163C1156BE2C2F3EB810415115039E0C7D3242C0", ""
),
if (isFdroid) null else defaultRepository(
"https://repo.dgplayser.duckdns.org/fdroid/archive",
"Michachatz F-Droid Repo",
"Michachatz official repository. Everything in this repository is always built from the source code.",
21, true, "3546DCBDD900F280EE2161CC163C1156BE2C2F3EB810415115039E0C7D3242C0 ", ""
),
defaultRepository(
"https://f-droid.org/repo",
"F-Droid",
@@ -39,7 +39,7 @@ open class DrawableWrapper(val drawable: Drawable): Drawable() {
}
override fun getAlpha(): Int {
return DrawableCompat.getAlpha(drawable)
return drawable.alpha
}
override fun setAlpha(alpha: Int) {
@@ -35,6 +35,7 @@ import android.widget.ProgressBar
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat.getString
import androidx.core.graphics.ColorUtils
import androidx.core.text.HtmlCompat
import androidx.core.text.util.LinkifyCompat
@@ -373,7 +374,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}
@SuppressLint("SetTextI18n")
private class LinkViewHolder(itemView: View): OverlappingViewHolder(itemView) {
companion object {
private val measurement = Measurement<Int>()
@@ -385,7 +385,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
init {
val margin = measurement.invalidate(itemView.resources) {
text.text = "measure"
text.text = itemView.context.getString(R.string.measure)
link.visibility = View.GONE
measurement.measure(itemView)
((itemView.measuredHeight - icon.measuredHeight) / 2f).roundToInt()
@@ -397,7 +397,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}
@SuppressLint("SetTextI18n")
private class PermissionsViewHolder(itemView: View): OverlappingViewHolder(itemView) {
companion object {
private val measurement = Measurement<Int>()
@@ -408,7 +407,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
init {
val margin = measurement.invalidate(itemView.resources) {
text.text = "measure"
text.text = itemView.context.getString(R.string.measure)
measurement.measure(itemView)
((itemView.measuredHeight - icon.measuredHeight) / 2f).roundToInt()
}
@@ -75,8 +75,9 @@ object Utils {
.filter { it.language in supportedLanguages }
.let { it.ifEmpty { listOf(Locale.US) } }
Locale.setDefault(compatibleLocales.first())
val newConfiguration = Configuration(configuration)
newConfiguration.setLocales(LocaleList(*compatibleLocales.toTypedArray()))
val newConfiguration = Configuration(configuration).apply {
setLocales(LocaleList(*compatibleLocales.toTypedArray()))
}
return context.createConfigurationContext(newConfiguration)
}
+164
View File
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_failed">Aktion fehlgeschlagen</string>
<string name="add_repository">Repository hinzufügen</string>
<string name="address">Adresse</string>
<string name="all_applications">Alle Anwendungen</string>
<string name="all_applications_up_to_date">Alle Anwendungen sind aktuell</string>
<string name="already_exists">Existiert bereits</string>
<string name="always">Immer</string>
<string name="anti_features">Anti-Funktionen</string>
<string name="application">Anwendung</string>
<string name="application_not_found">Anwendung nicht gefunden</string>
<string name="author_email">E-Mail des Autors</string>
<string name="author_website">Website des Autors</string>
<string name="available">Verfügbar</string>
<string name="bug_tracker">Fehlerverfolgung</string>
<string name="cancel">Abbrechen</string>
<string name="cant_edit_sync_DESC">Repository kann nicht bearbeitet werden, da es gerade synchronisiert wird.</string>
<string name="changelog">Änderungsprotokoll</string>
<string name="changes">Änderungen</string>
<string name="checking_repository">Repository wird überprüft</string>
<string name="compiled_for_debugging">Für Debugging kompiliert</string>
<string name="confirmation">Bestätigung</string>
<string name="connecting">Verbinden</string>
<string name="contains_non_free_media">Enthält nicht-freie Medien</string>
<string name="could_not_download_FORMAT">Konnte %s nicht herunterladen</string>
<string name="could_not_sync_FORMAT">Konnte %s nicht synchronisieren</string>
<string name="could_not_validate_FORMAT">Konnte %s nicht validieren</string>
<string name="dark">Dunkel</string>
<string name="date_added">Hinzugefügt am</string>
<string name="delete">Löschen</string>
<string name="delete_repository_DESC">Möchtest du das Repository wirklich löschen?</string>
<string name="description">Beschreibung</string>
<string name="details">Details</string>
<string name="donate">Spenden</string>
<string name="downloaded_FORMAT">Heruntergeladen: %s</string>
<string name="downloading">Wird heruntergeladen</string>
<string name="downloading_FORMAT">Lade %s herunter</string>
<string name="edit_repository">Repository bearbeiten</string>
<string name="file_format_error_DESC">Ungültiges Dateiformat.</string>
<string name="fingerprint">Fingerabdruck</string>
<string name="has_advertising">Enthält Werbung</string>
<string name="has_non_free_dependencies">Hat nicht-freie Abhängigkeiten</string>
<string name="has_security_vulnerabilities">Hat Sicherheitslücken</string>
<string name="http_error_DESC">Ungültige Serverantwort.</string>
<string name="http_proxy">HTTP-Proxy</string>
<string name="ignore_all_updates">Alle Updates ignorieren</string>
<string name="ignore_this_update">Dieses Update ignorieren</string>
<string name="incompatible_api_DESC_FORMAT">Dein %1$s (API-Version %2$d) wird nicht unterstützt. %3$s</string>
<string name="incompatible_api_max_DESC_FORMAT">Maximale API-Version ist %d.</string>
<string name="incompatible_api_min_DESC_FORMAT">Minimale API-Version ist %d.</string>
<string name="incompatible_features_DESC">Fehlende Funktionen.</string>
<string name="incompatible_older_DESC">Diese Version ist älter als die auf deinem Gerät installierte. Bitte deinstalliere diese zuerst.</string>
<string name="incompatible_platforms_DESC_FORMAT">Deine %1$s-Plattform wird nicht unterstützt. Unterstützte Plattformen: %2$s.</string>
<string name="incompatible_signature_DESC">Diese Version wurde mit einem anderen Zertifikat signiert als die auf deinem Gerät installierte. Bitte deinstalliere diese zuerst.</string>
<string name="incompatible_version">Inkompatible Version</string>
<string name="incompatible_versions">Inkompatible Versionen</string>
<string name="incompatible_versions_summary">Zeige Versionen, die nicht mit dem Gerät kompatibel sind</string>
<string name="incompatible_with_FORMAT">Nicht kompatibel mit %s</string>
<string name="install">Installieren</string>
<string name="installed">Installiert</string>
<string name="integrity_check_error_DESC">Integrität konnte nicht überprüft werden.</string>
<string name="invalid_address">Ungültige Adresse</string>
<string name="invalid_fingerprint_format">Ungültiges Fingerabdruckformat</string>
<string name="invalid_metadata_error_DESC">Ungültige Metadaten.</string>
<string name="invalid_permissions_error_DESC">Ungültige Berechtigungen.</string>
<string name="invalid_signature_error_DESC">Ungültige Signatur.</string>
<string name="invalid_username_format">Ungültiges Benutzername-Format</string>
<string name="last_update">Letztes Update</string>
<string name="launch">Starten</string>
<string name="license">Lizenz</string>
<string name="license_FORMAT">Lizenz %s</string>
<string name="light">Hell</string>
<string name="link_copied_to_clipboard">Link in die Zwischenablage kopiert</string>
<string name="links">Links</string>
<string name="merging_FORMAT">Füge %s zusammen</string>
<string name="name">Name</string>
<string name="network_error_DESC">Netzwerkfehler.</string>
<string name="never">Nie</string>
<string name="new_updates_available">Neue Updates verfügbar</string>
<plurals name="new_updates_DESC_FORMAT">
<item quantity="one">%d neues Update.</item>
<item quantity="other">%d neue Updates.</item>
</plurals>
<string name="no_applications_available">Keine Anwendungen verfügbar</string>
<string name="no_applications_installed">Keine Anwendungen installiert</string>
<string name="no_description_available_DESC">Keine Beschreibung verfügbar.</string>
<string name="no_matching_applications_found">Keine passenden Anwendungen gefunden</string>
<string name="no_proxy">Kein Proxy</string>
<string name="notify_about_updates">Über Updates benachrichtigen</string>
<string name="notify_about_updates_summary">Benachrichtigung anzeigen, wenn Updates verfügbar sind</string>
<string name="number_of_applications">Anzahl der Anwendungen</string>
<string name="ok">OK</string>
<string name="only_compatible_with_FORMAT">Nur kompatibel mit %s</string>
<string name="only_on_wifi">Nur über WLAN</string>
<string name="open_DESC_FORMAT">%s öffnen?</string>
<string name="other">Andere</string>
<string name="parsing_index_error_DESC">Indexdatei konnte nicht verarbeitet werden.</string>
<string name="password">Passwort</string>
<string name="password_missing">Passwort fehlt</string>
<string name="permissions">Berechtigungen</string>
<string name="plus_more_FORMAT">+%d mehr</string>
<string name="preferences">Einstellungen</string>
<string name="processing_FORMAT">Verarbeite %1$s</string>
<string name="project_website">Projekt-Website</string>
<string name="promotes_non_free_network_services">Fördert nicht-freie Netzwerkdienste</string>
<string name="promotes_non_free_software">Fördert nicht-freie Software</string>
<string name="provided_by_FORMAT">Bereitgestellt von %s</string>
<string name="proxy">Proxy</string>
<string name="proxy_host">Proxy-Host</string>
<string name="proxy_port">Proxy-Port</string>
<string name="proxy_type">Proxy-Typ</string>
<string name="repositories">Repositories</string>
<string name="repository">Repository</string>
<string name="repository_not_used_DESC">Dieses Repository wurde noch nicht verwendet. Du musst es aktivieren, um die Anwendungen zu sehen.</string>
<string name="repository_unsigned_DESC">Nicht signiert. Die Anwendungsliste konnte nicht verifiziert werden. Sei vorsichtig beim Herunterladen.</string>
<string name="requires_FORMAT">Benötigt %s</string>
<string name="save">Speichern</string>
<string name="saving_details">Speichere Details</string>
<string name="screenshots">Screenshots</string>
<string name="search">Suchen</string>
<string name="select_mirror">Mirror auswählen</string>
<string name="show_more">Mehr anzeigen</string>
<string name="show_older_versions">Ältere Versionen anzeigen</string>
<string name="signature_FORMAT">Signatur %s</string>
<string name="signed_using_unsafe_algorithm">Mit unsicherem Algorithmus signiert</string>
<string name="skip">Überspringen</string>
<string name="socks_proxy">SOCKS-Proxy</string>
<string name="sorting_order">Sortierreihenfolge</string>
<string name="source_code">Quellcode</string>
<string name="source_code_no_longer_available">Quellcode nicht mehr verfügbar</string>
<string name="suggested">Empfohlen</string>
<string name="sync_repositories">Repositories synchronisieren</string>
<string name="sync_repositories_automatically">Repositories automatisch synchronisieren</string>
<string name="syncing">Synchronisiere</string>
<string name="syncing_FORMAT">Synchronisiere %s</string>
<string name="system">System</string>
<string name="tap_to_install_DESC">Tippen zum Installieren.</string>
<string name="theme">Design</string>
<string name="tracks_or_reports_your_activity">Verfolgt oder meldet deine Aktivitäten</string>
<string name="uninstall">Deinstallieren</string>
<string name="unknown">Unbekannt</string>
<string name="unknown_error_DESC">Unbekannter Fehler.</string>
<string name="unknown_FORMAT">Unbekannt: %s</string>
<string name="unsigned">Nicht signiert</string>
<string name="unstable_updates">Instabile Updates</string>
<string name="unstable_updates_summary">Instabile Versionen vorschlagen</string>
<string name="unverified">Nicht verifiziert</string>
<string name="update">Aktualisieren</string>
<string name="updates">Updates</string>
<string name="upstream_source_code_is_not_free">Quellcode ist nicht frei verfügbar</string>
<string name="username">Benutzername</string>
<string name="username_missing">Benutzername fehlt</string>
<string name="validation_index_error_DESC">Index konnte nicht validiert werden.</string>
<string name="version_FORMAT">Version %s</string>
<string name="versions">Versionen</string>
<string name="waiting_to_start_download">Warte auf Start des Downloads</string>
<string name="website">Website</string>
<string name="address_redirect_FORMAT">Die Repository-Adresse wurde zu %s weitergeleitet. Möchtest du diese verwenden?</string>
<string name="credits">Credits an Michatec</string>
<string name="credits_to_fork">Dies ist ein Fork von github.com/kitsunyan/foxy-droid.</string>
</resources>
+1
View File
@@ -166,5 +166,6 @@
<string name="address_redirect_FORMAT">The repository address was redirected to %s. Do you want to use it instead?</string>
<string name="credits">Credits to Michatec</string>
<string name="credits_to_fork">This is a fork from github.com/kitsunyan/foxy-droid.</string>
<string name="measure" translatable="false">measure</string>
</resources>