Ein eigenes Android-App-Repsitory (F-Droid) auf dem Uberspace

Vorbemerkungen

Ein Android-Smartphone ist erst mit zusätzlichen Apps so wirklich nützlich. Wenn auf dem Gerät ein Cyanogenmod (oder ein anderes Betriebssystem ohne die Google-Apps wie den Play Store) läuft und man aus Prinzip keine Abhängigkeit zu Google schaffen möchte, dann muss man sich eine andere App-Quelle suchen. Amazon (oder ähnliche) ist da auch keine echte Alternative. Die gibt es allerdings in F-Droid. Das Projekt betreibt nicht nur einen eigenen Katalog von Apps (nur Open Source, keine Anmeldung nötig) und stellt den dazugehörigen Client bereit, sondern ebenfalls die Server-Software. Im Client kann man außer dem Standard-Repository auch weitere hinzufügen, z.B. Öffi oder GuardianProject. Oder eben sein eigenes wenn man eins hat. Darum, sein eigenes F-Droid-Repository aufzusetzen, und zwar bei uberspace, soll es in diesem Eintrag gehen.

Doch warum sollte man das tun wollen? Im „offiziellen“ F-Droid-Repository gibt es doch schon alle möglichen Apps? Eine schöne Zusammenstellung der „besten“ Apps findet man z.B. bei Droid-Break:

  1. Manche Apps sind leider nicht Open Source und daher auch nicht bei F-Droid zu finden (z.B. QuickPic, die Uni-App, die Olympus-Kamera-App etc.). Man kann sie z.B. über einen App-Downloader auch ohne Google-Konto herunterladen (in der letzten Zeit klappt es nicht mehr richtig), aber der noch etwas bessere Weg könnte ein Kommandozeilen-Play-Store-Client, evtl. auch zusammen mit Weboberfläche sein. Das könnten der 3. und 4. Schritt werden…
  2. Wenn man Android-Apps selbst entwickelt oder vorhandene verändert/erweitert kann es helfen, diese als Entwickler-Versionen per Repository auch an mehrere Leute/Geräte verteilen zu können, bevor sie es in den offiziellen Store schaffen. Konsequenterweise würde man evtl. sogar alle Apps lieber selbst automatisch und regelmäßig aus dem aktuellen Quellcode kompilieren, dazu wäre eine Art Build- oder Continuous Integration-Server wie Jenkins praktisch (Schritt 2).

Zunächst mal ist das Ziel (der 1. Schritt) aber ein „einfaches“, sogenanntes „Simple Binary Repository“, das einfach vorkompilierte (z.B. auf dem Entwicklungs-Laptop) .apk-App-Dateien verteilt.

Man könnte auf den Gedanken kommen, soetwas einfach im heimischen Netzwerk auf einem Raspberry einzurichten. Leider geht das aber nicht, da im Raspberry ein ARM-Prozessor läuft und es das Android-SDK aus irgendwelchen skurrilen Gründen nicht für ARM gibt. Skurril deshalb, weil immerhin die meisten Smartphones selber einen ARM-Prozessor haben. Apps muss man daher auf einer x86-Plattform Cross-compilen. Das Android-SDK wiederum braucht der F-Droid-Server, um die Meta-Daten aus den APK-Dateien auszulesen und im Repository bereitzustellen.

Zunächst noch zum Setup: Das Paket „fdroidserver“ ist hauptsächlich in Python geschrieben und nutzt das Java-SDK (JRE reicht nicht) und das Android-SDK als Abhängigkeiten.

Die Python-Skripte generieren die notwendigen Ordner- und Datei-Strukturen, die dann aus dem normalen Webroot eines üblichen Web-Servers wie NGinx (oder, im Falle von uberspace) Apache ausgeliefert werden.

Die anderen Anleitungen zum Einrichten des Servers gehen (wie so häufig) von root-Rechten auf dem Server aus, die hat man aber bei uberspace natürlich nicht zur Verfügung. Ein „apt install fdroidserver“ klappt also nicht, man muss ein paar Anpassungen vornehmen.

Die Dokus, die mich auf dem bisherigen Weg begleitet haben, gibt es hier:

Leider sind die nicht alle ganz konsistent, widersperchen sich ein wenig oder ergänzen jeweils nur einige kleine Hinweise. Ich habe auch auf den „virtualenv„-Aspekt verzichtet, weil er mich beim Testen eher verwirrt hat und ich keinen schlagenden Vorteil sehe.

Nun also per Hand, von Anfang an:

Ein Arbeitsverzeichnis anlegen und dahin wechseln:

$ mkdir -p ~/projekte/android && cd ~/projekte/android

Java

Das Java-SDK ist bei Uberspace nicht installiert, für diesen Anwendungsfall (Entwicklungsumgebung und Laufzeitumgebung für kleine Kommandozeilenprogramme) kann man es aber – auf eigene Quota – nachziehen.

Die Methode (Oracle macht es etwas umständlich) hat sich zwischenzeitlich schon wieder ein wenig verändert und man muss bei Oracle auf der Website zuvor die aktuelle Version nachschauen (Dateiname anpassen) :

$ wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u92-b14/jdk-8u92-linux-x64.tar.gz

Für das OpenJDK scheint es leider keinen offiziellen Tarball zu geben, sondern nur fertige Plattform-Pakete (wiesu denn blus?), die man per Paket-Verwaltung installieren müsste.

(Nebenbei: Die Uberspace-Server haben – kaum überraschend – Prozessor und Kernel mit 64 Bit Wortbreite, das kann man auch auf der Kommandozeile herausfinden)

$ tar xvfz jdk-8u92-linux-x64.tar.gz
$ rm jdk-8u92-linux-x64.tar.gz
$ mv jdk1.8.0_92 jdk

Android

Auf der offiziellen Website ganz unten den Pfad zum aktuellen SDK besorgen und herunterladen (Version anpassen):

$ wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
$ tar xvfz android-sdk_r24.4.1-linux.tgz
$ rm android-sdk_r24.4.1-linux.tgz
$ mv android-sdk-linux android-sdk

Jetzt müssen ein paar Umgebungsvariablen angepasst werden:

$ nano ~/.bash_profile

und folgende Zeilen einfügen:

export JAVA_HOME=$HOME/projekte/android/jdk
export PATH=$JAVA_HOME/bin:$PATH
export ANDROID_HOME=$HOME/projekte/android/android-sdk

Nach dem Speichern (Strg+O, Strg+X) die Variablenänderungen neu einlesen mittels

$ source ~/.bash_profile

dann mit Hilfe des SDK Managers die zusätzlichen Tools und Plattformen herunterladen:

$ android-sdk/tools/android list sdk --no-ui -a

Dort die Nummern merken für die SDK Tools, die Platform-tools, die Build-tools (jeweils nur die höchste Version/Revision, abgesehen von RCs) und die SDK Platforms API 20 und 22 und diese dann an den folgenden Filter-Parameter übergeben:

$ android-sdk/tools/android update sdk --no-ui -a --filter 1,3,6,31,33

(etwas mehr Information dazu und noch vertiefende Anmerkungen)

64 Bit Build-Tools

Jetzt kommt der große Trick an diesem Setup: Zu diesem Zeitpunkt würde ein

$ ~/projekte/android/fdroid/fdroidserver/fdroid update --create-metadata

im Repository-Verzeichnis (s.u.) zum Scheitern führen:

CRITICAL: OSError while trying to execute /home/$USER/projekte/android/android-sdk/build-tools/23.0.3/aapt dump badging repo/de.danoeh.antennapod_1050200.apk: [Errno 2] No such file or directory: '/home/$USER/projekte/android/android-sdk/build-tools/23.0.3/aapt'

Das Programm aapt liegt zwar am angegebenen Ort, gibt aber bei direktem Aufrufen folgende Rückgabe:

-bash: /home/$USER/projekte/android/android-sdk/build-tools/23.0.3/aapt: /lib/ld-linux.so.2: bad ELF interpreter: Datei oder Verzeichnis nicht gefunden

Das liegt wohl daran, dass es für dieses Programm keine (offizielle) 64-Bit-Version gibt. ?!?! 32 Bit ist schon seit einer gefühlten Ewigkeit obsolet (um mal die Jungs von Uberspace zu zitieren), aber die entsprechende Issue bei Android/Google steht auf „WorkingAsIntended“. Hier ist also wenig schnelle Abhilfe zu erwarten.

Theoretisch könnte man zwar Kompatibilitäts-Bibliotheken (mit Dropdown oben rechts zu Linux wechseln) auf dem Server installieren:

sudo yum install zlib.i686 ncurses-libs.i686 bzip2-libs.i686

Aber auch mit Hundeblick ließen sich die Uberspace-Admins nicht ausnahmsweise erweichen. Was ich verstehen kann, denn man möchte sich sein Setup ja nicht mit altem Kram zukleistern, „der einen riesigen Ratenschwanz an Abhängigkeiten mit sich bringt“ (erneutes Support-Zitat). Naja, ’n Versuch war’s wert aber Prinzipien sind gut und müssen sein! 🙂

Außerdem erhöht das den Leidensdruck auf den User, die Sache doch noch irgendwie anders hinzubekommen. Da war doch beim Suchen irgendwo ein Link aufgetaucht…?

Ja! Tatsächlich gibt es ein Github-Repository, in dem sich jemand die Mühe gemacht hat, die Original Android-Build Tools so vorzubereiten, dass sie auf einem 64 Bit-System kompilieren. Welche Arbeit und Veränderungen genau das bedeutet hat, ist zwar nicht direkt ersichtlich, und die Grundlage sind die Android 4.1.2-Quellen, aber das sollte doch eigentlich keine Rolle spielen. Also los (wir befinden uns weiterhin in ~/projekte/android/):

$ git clone https://github.com/cjacker/android-utils.git
$ cd android-utils
$ ./configure
$ make

Jetzt braucht es einen kleinen Moment, bis alles fertig kompiliert ist. Danach liegt das fertige 64 Bit-aapt in seinem Ordner. Kurzer Test:

$ aapt/aapt

spuckt keine Fehlermeldung, sondern den Hilfetext aus. Juhu!

Dann packen wir es mal in das SDK-Verzeichnis:

$ cd ../android-sdk/build-tools/23.0.3/
$ mv aapt aapt-original
$ cp ../../../android-utils/aapt/aapt ./
$ cd ../../../

F-Droid Server

Und nun endlich auf zum Endspurt:

$ mkdir fdroid && cd fdroid
$ git clone https://gitlab.com/fdroid/fdroidserver.git
$ cd fdroidserver
$ pip3 install -e . --user

Dabei wird das offizielle Git-Repository geklont und mit dem Python-Paketmanager pip in Version 3 die Abhängigkeiten aufgelöst/heruntergeladen. Wichtig ist der –user-Schalter damit nicht versucht wird, die Pakete im schreibgeschützten globalen Pfad abzulegen. Nach ein bisschen warten und in der Konsolenausgabe sollte am Ende sowas stehen wie

Successfully installed ... fdroidserver ...

Also weiter mit

$ python3 setup.py install --user

das endet nach etwas Arbeiten und Ausgabe zwar mit

error: could not create '/package/host/localhost/python-3/share/doc': Permission denied

aber wer braucht schon Doku? 🙂 Offenbar beachtet hier leider das Install-Script nicht die –user -Option.

Legen wir nun im virtuellen WebRoot ein Verzeichnis „fdroid“ (eine Konvention) an, begeben uns dorthin und initialisieren ein F-Droid-Repository:

$ cd /var/www/virtual/$USER/html
$ mkdir fdroid && cd fdroid
$ ~/projekte/android/fdroid/fdroidserver/fdroid init

Es gibt zwar wieder einmal eine Fehlermeldung

CRITICAL: Unknown exception found!
[...]
KeyError: 'keytool'

aber das Wesentliche wurde erledigt, wie $ ls -lah  zeigt. Und den Fehler und seine Auswirkungen beheben wir gleich.

Repository

Jetzt legen wir zum Testen eine vorhandene .apk-Datei in das Repository

$ cd repo/
$ wget https://f-droid.org/repo/de.danoeh.antennapod_1050200.apk
$ cd ..

Dann muss eine kleine Anpassung an der config.py vorgenommen werden, damit F-Droid das JDK findet. Diese Stelle hat mich am meisten Zeit und Nerven gekostet, weil sie gut versteckt und mäßig dokumentiert ist. Macht man es nicht, bekommt man

CRITICAL: Java JDK not found! Install in standard location or set java_paths!

Also weiter:

$ nano config.py

Hier müssen oben einige Zeilen einkommentiert und verändert werden (achtet auf die richtige Zahl, nicht ‚1.8‘, das ist eine fiese Falle)

java_paths = {
     '8': "/home/$USER/projekte/android/jdk",
}

Einbiegen auf die Zielgerade, das Repository erzeugen/aktualisieren:

$ ~/projekte/android/fdroid/fdroidserver/fdroid update --create-metadata

sagt uns leider noch

CRITICAL: 'keystore.jks' does not exist!

Da ist ja der Fehler von vorhin, aber da das Repository nun fertig konfiguriert ist und das JDK findet, funktioniert die vorgeschlagene Abhilfe:

$ fdroid update --create-key

es wird ein neuer Signing Key und ein passendes Zertifikat erzeugt. Das sind Sachen, die man in Zukunft ruhig nochmal anpassen könnte, aber für’s Erste geht das schon in Ordnung. Der zweite Versuch mit

$ ~/projekte/android/fdroid/fdroidserver/fdroid update --create-metadata

bringt uns

INFO: Finished.

Das war’s! Es funktioniert. Auf dem Smartphone muss jetzt in F-Droid unter „Paketquellen“ eine neue Quelle eingerichtet werden. Als Adresse gibt man

https://$USER.$SERVER.uberspace.de/fdroid/repo

ein, aktiviert es, deaktiviert alle anderen und aktualisiert einmal die Quellen. Dann taucht es in der Liste als „My First F-Droid-Repo Demo“ auf und in der App-Liste wird die eine App (im Beispiel AntennaPod) aufgeführt.

Screenshot_20160422-132354 Screenshot_20160422-135023

Nutzung

Die Nutzung wird nun darin bestehen, fertige .apk-Dateien unter

/var/www/virtual/$USER/html/fdroid/repo

abzulegen und dann in

/var/www/virtual/$USER/html/fdroid/

das Kommando

$ ~/projekte/android/fdroid/fdroidserver/fdroid update

aufzurufen.

Weitere Konfiguration

In der Datei

/var/www/virtual/$USER/html/fdroid/config.py

sind jetzt noch einige Konfigurationsoptionen, an denen man schrauben kann, die Sache mit den Keys sollte man sich durchaus nochmal anschauen (die Apps werden neu mit einem einheitlichen Repository-Key signiert) und auch das metadata/ -Verzeichnis bietet Ansatz-Punkte.

Dazu bietet es sich an, die oben verlinkten Artikel/Handbücher zu studieren, aber das ist ab jetzt dann nur noch „Standard“. Wahrscheinlich ist es auch nicht verkehrt, von Zeit zu Zeit ein Update der fdroidserver-Skripte, des Java- und des Android-SDK zu machen.

Viel Spaß mit euren eigenen F-Droid-Repositories und der neu gewonnenen Unabhängigkeit! Sollte dies hier jemandem genützt haben, freue ich mich sehr über einen Kommentar.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert