Linux, User Management

Ich beginne hier mit dem Titelgebenden Thema. Es geht darum wer den eigentlich der sogenannte root und die anderen user sind. Als Szenario habe ich mir dabei vorgestellt, dass man sich gerade ein Linuxoides System auf seinem Rechner Installiert hat. Die Beispiel habe ich mit Linux Mint getestet.

Was wir lernen:

  • Den eigenen user identifizieren. Gruppenzugehörigkeit ermitteln.
  • Den aktuellen user wechseln.
  • Vorübergehende root- Rechte für den eigenen user erlangen.
  • Ein neues root– Password nach der Erstinstallation des Systems anlegen und selbst zum root werden.
Weiterlesen

Life Cycles

Eine Activity oder ein Fragment reagiert auf Änderungen im Life- Cycle einer Android App , indem die entsprechenden Call- Back Methoden aufgerufen werden (onCreate(), onStart(),onResume() etc…).

Dabei kann es aber unter Anderem passieren das, während der Code der in onStart() ausgeführt wird – nehmen wir an es findet der Verbindungsaufbau zu einem Bluetooth Gerät statt – onStop() vom System aufgerufen wird. wenn man nun dort die Bluetooth– Verbindung über diese Änderung informieren möchte, dann wird es zu einem Fehler kommen weil es ja noch keine Verbindung gibt (am ehestens bekommt man eine null pointer exception wenn man beispielsweise mit dem connectedThread– Objekt kommunizieren möchte).

Das oben beschriebene Fehlverhalten kann vermieden werden, indem man jene Komponenten einer Activity oder eines Fragmentes (also zum Beispiel das oben erwähnte bluetoothConnectedThread– Objekt – selbst auf die Änderungen im Life- Cycle reagieren läßt. Dabei ist die Activity oder das Fragment immer der Life- Cycle Owner. Die jeweilige Komponente ist der sogenannte Observer der über die Änderungen entsprechend informiert wird und darauf reagieren kann.

Neben dem Vorteil der Fehlervermeidung wird der Code lesbarer. Wenn man mehrere Komponenten hat die Life- Cycle abhängig sind, dann hat man in jeder Komponente den kompletten Code stehen und nicht teilweise in der jeweiligen Call- Back Methode der Activity oder des Fragemntes.

Parent Layout füllen

Klar, der Parameter match-parent hat den gewünschten, namensgebenden Effekt. Aber, wenn ich mehrere view– Elemente in einem parent darstelle und ich möchte, dass das am unteren Bildschirmrand steht genau die Größe hat, die noch zur Verfügung steht, was dann? Vor allem wenn es sich bei diesem Element um eine list- view handelt is das ein bisschen problematisch. eine Lösung steht hier.

  <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fragment_fav_covid_data_view"
        app:layout_constraintBottom_toTopOf="@+id/nav_view"
        app:navGraph="@navigation/mobile_navigation" />

Entscheidend ist hier: Man setzte die Höhe auf null und den constraint auf den Kopf des folgenden Elements, das die Höhe einschränken soll (deswegen heist das auch constraint 😉

Singleton Pattern

Ist eine Klasse von der – während der Laufzeit eines Programms – nur ein Objekt abgeleitet werden kann.

Wird oft in Verbindung mit Datenbank- Zugriffen genannt und anhand solcher Beispiele auch erklärt. Ich persönlich habe noch keinen Fall gehabt, wo ich das gebraucht hätte. Ich beschränke mich deshalb erst einmal darauf das Pattern zu zeigen:

class SingletonExample {

// private field that refers to the object
   private static SingletonExample singleObject;

   private SingletonExample() {
      // constructor of the SingletonExample class
   }

   public static SingletonExample getInstance() {
      // write code that allows us to create only one object
      // access the object as per our need
   }
}

Das Code- Beispiel stammt aus der unter [1] verlinkten Quelle.

Man beachte: Der Leere Konstruktor ist als privat deklariert. Das bedeutet, neue Objekte können nicht außerhalb der eigenen Klasse erzeugt werden. Über die getInstance() Methode besorgt man sich eine Instanz dieser Klasse. Diese Instanz kann nur einmal erzeugt werden, wenn man sicherstellt, dass es nicht schon eine gibt. Beispiel:

 public static ThreadGetCovidData getInstance(getCovidDataInterface g,String sK,String sQ){
        if (getCovidData==null) {
            gC=g;
            apiAddressStadtkreise=sK;
            searchQuery=sQ;
            getCovidData = new ThreadGetCovidData();
        }
        return getCovidData;
    }

Das war es auch schon. Wenn ich mit eigenen Worten, ein Beispiel beschreiben kann, in dem es notwendig war ein Objekt genau einmal zu erzeugen und nicht etwa einfach eine statische Klasse zu verwenden, dann schreibe ich das hier hin.

[1] Prgrammiz.com: Singleton

Android App, Update prüfen

Ich beschreibe hier, wie man es schafft, die Nutzer einer in der Play- Store veröffentlichten App über Updates zu informieren.

Grundsätzlich habe ich mir zwei Varianten angeschaut. Die erste funktioniert indem man sich der Play Core Library bedient. Die Zweite Methode funktioniert über den Abgleich der aktuellen Versionsnummer der App auf dem Android Gerät mit der in der Play Store veröffentlichen Variante.

Play Core Library

Unter [1] findet man den Link zur offiziellen Dokumentation von Goggle.

Ich habe zunächst einmal nur ein Stück Code getestet, dass prüft ob ein Update verfügbar ist.

//
        // Play core library
        //
        AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(getApplicationContext());

        // Returns an intent object that you use to check for an update.
        Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

        appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
            @Override
            public void onSuccess(AppUpdateInfo result) {
                if (result.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
                    Toast.makeText(getApplicationContext(), "Update available.....", Toast.LENGTH_LONG).show();
                    Log.v("UPDATEUPDATE:", result.availableVersionCode() + "");
                }else
                    Log.v("UPDATEUPDATE:","No Update");
            }
        });

Ich habe den Code mit meiner App „Beam Calc“ getestet (Verlinkt unter [2]). Ob das funktioniert wäre noch zu prüfen. Ich werde berichten, wenn ich es getestet habe, also, spätestens nach dem nächsten Update der App.

Wenn ein neues Update da ist, dann kann man den Update Prozess direkt aus der App heraus starten.

Abgleich über die Versionsnummern im Play- Store und der App die auf dem Android Gerät läuft

Die hier gezeigte Lösung ist nichts anderes als Copy- Paste. Der zugrundeliegende Artikel findet sich unter [3]. Der hier abgebildete Code ist daraus entnommen.

Eine wichtige Voraussetzung ist: Wenn man einen neuen Release erzeugt, dann muss man unbedingt dafür sorgen, dass keine älteren APK’s dem neuen Release beigefügt werden. Ansonsten wird bei der Angabe der Versions- Nummer im Play Store (im übrigen gilt das auch für die verfügbaren Bildschirm Auflösungen) „Variiert ja nach Gerät“ angezeigt.

Der Code bedient sich der Jsoup- Library, einem HTML– Parser für Java. Den Link findet man unter [4]. Am schnellsten geht die Integration in das eigene Projekt über Gradle (das unten stehende in die build.gradle auf Modul- Ebene einfügen):

 // jsoup HTML parser library @ https://jsoup.org/
    implementation 'org.jsoup:jsoup:1.13.1'

Der eigentliche Versions- Checker schaut so aus:

import android.os.AsyncTask;
import org.jsoup.Jsoup;
import java.io.IOException;

/**
 * Version checker.
 *
 * Retrieves the version of this app from the Google Play- Store.
 *
 * Source: https://stackoverflow.com/questions/34309564/how-to-get-app-market-version-information-from-google-play-store
 */
public class VersionChecker extends AsyncTask<String, String, String> {

    String newVersion;

    @Override
    protected String doInBackground(String... params) {

        try {
            newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + "berthold.beamcalc" + "&hl=de")
                    .timeout(30000)
                    .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
                    .referrer("http://www.google.com")
                    .get()
                    .select("div.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
                    .first()
                    .ownText();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return newVersion;
    }
}

Der Aufruf wird so erledigt:

 //
        // Version checker
        //
        VersionChecker vc=new VersionChecker();
        try {
            String latest = vc.execute().get();
            Toast.makeText(getApplicationContext(), "Latest Version Code:"+latest, Toast.LENGTH_LONG).show();
        } catch (Exception e){}
    }

Ich werde an dieser Stelle weiter über die Ergebnisse berichten.

[1] Google Play Core Library, ofizelle Dokumentation von Google.
[2] Beam Calc App.
[3] Stack Overflow, Get version from Play Store.
[4] jsoup: Java HTML Parser.

Einfeldträger (Beam Calc) neue Version 1.3

Die neue Version ist im Testbetrieb und wird in den nächsten Tagen auf Google- Play veröffentlicht.

Einfeldträger (Beam Calc) Version 1.3

Die Benutzeroberfläche wurde etwas entschlackt. Die Maßketten können nun nicht mehr ausgeblendet werden und werden immer angezeigt. Die Anzeige der resultierenden Auflagerkräfte und der mathematische Lösungsterm kann über das Antippen eines einzelnen Symbols ein oder ausgeschaltet werden.

Die einwirkenden Lasten können nun etwas komfortabler und übersichtlicher in einem eigenen Eingabedialog definiert werden. Die Textgröße in der grafischen Darstellung der Lösung wurde angepasst. Die Maßketten und die Angaben zu den Lasten sind jetzt auch auf kleineren Bildschirmen besser lesbar.

[1] Projektseite zur App, hier im Blog.

Einsatzplan

Ich habe die app verbessert. Aktuelles hier, genaueres kann man auf der Projektseite dazu, hier im Blog, nachlesen. Der Link findet sich am Ende dieses Artikels unter [1].

Im wesentlichen handelt es sich bei der app um ein Tool, mit dem man Kalendereinträge, die in einer Textdatei, zeilenweise, abgelegt sind in eine besser lesbare Liste umwandeln kann die sich dann filtern oder durchsuchen lässt. Das schönste daran ist aber, dass man einzelne Einträge oder Eintragserien ganz einfach in die Kalender app des Android Gerätes übernehmen kann.

Derzeit funktioniert das nur für Einsatzpläne die von der Firma für die ich arbeite erzeugt werden. Eine Anpassung kann aber ganz leicht, für ähnliche Einsatzzwecke und andere Datenformate erledigt werden.

Einsatzplan. Für jeden Eintrag kann eine Detailansicht ausgewählt werden, die es erlaubt einen Lehrgangstag oder den kompletten Lehrgang in die Kalender app des Android Gerätes zu übernehmen.

Ich habe das erzeugen von Kalendereinträgen und E- Mail Anfragen vereinfacht. Beides kann jetzt aus der Detailansicht, die man für jeden Eintrag aufrufen kann, heraus erledigt werden. Der Code wurde etwas entschlackt und optimiert. Im Ergebnis läuft die app jetzt sehr flüssig.

Details zur app habe ich hier im Blog veröffentlicht:

[1] Einsatzplan app, Projektseite.

Beam Calc II

Ich habe die Library überarbeitet. Es werden nun auch veränderliche Linien- Lasten unterstützt. Dreiecks Lasten und Trapez- Lasten können eingegeben und berechnet werden.

Beam Calc II, der Name ist etwas irreführend. Es gibt nämlich keinen ersten Teil. Die Namensgebung kommt daher, weil ich die erste Version über Code Review habe beurteilen lassen. Das verbesserte Ergebnis ist Beam Calc II.

Die Library kann man sich hier anschauen/ herunterladen: GitHub CodingByChanche.

Beispiel Rechnung mit detailliertem Ergebnis.

Die Library benutze ich zur Entwicklung einer Android App. Die kann man sich hier im im Blog anschauen: Projekte, Einfeldträger.

Wer möchte kann mich im Google Play Store besuchen, dort kann man sich die aktuelle Version dieser App direkt herunterladen. Einfeldträger (BeamCalc) bei Google Play.

Einfeldträger (BeamCalc) App.