2024-03-22 01:37:32 +01:00

6.5 KiB

Einstellungen Feature

Das Einstellungen Feature zeigt auf der Startseite eine Liste an Optionen, die der Benutzer konfigurieren kann. Dazu gehören visuelle Einstellungen, wie das Aktivieren des Dark Modes, die Möglichkeit vom Material 3 Design zum Material 2 Design zu wechseln, eine Auswahl an Farben für den ColorSeed der App und das Anzeigen des eingebauten Performance Overlays von Flutter. Ansonsten gibt es nur die Möglichkeit, das WLAN zu konfigurieren (siehe Abbildung \ref{settings}). Der aktivierte Dark Mode und die Farbauswahl können in Abbildung \ref{settingsDark} betrachtet werden. Alle visuellen Einstellungen werden mit von Riverpod generierten Providern angesprochen und alle Einstellungen außer dem "Performance Overlay" nutzen dabei die SharedPreferences, um die Einstellungen zu speichern. Im Test gab es dabei in der finalen Version mit Yocto Linux manchmal das Problem, dass die SharedPreferences nicht richtig gespeichert werden. Erst kam die Vermutung auf, dass der Nutzer keine Schreibrechte auf das Verzeichnis von SharedPreferences hat, doch nach einem oder auch zwei Neustarts funktioniert das Speichern der Einstellungen problemlos. Der genaue Fehler konnte also nicht gefunden werden, da es keine Fehlermeldungen gab und es ein merkwürdiges Verhalten aufweist, da der Nutzer nicht plötzlich Schreibrechte auf das Verzeichnis bekommen kann, das Problem sich aber nach mehreren Neustarts "von selbst" löst. Im Falle von Flutter-Pi werden die Einstellung in der Datei ~/.local/share/flutter-pi/shared_preferences.json gespeichert, diese kann manuell bearbeitet werden und auch zum Vorkonfigurieren von Einstellungen genutzt werden.

\pagebreak

\Begin{multicols}{2}

\begin{figure}[H] \caption{Startseite der Einstellungen} \label{settings} \centering {\shadowimage[width=7cm]{./assets/screenshots/settings.png}} \end{figure}

\begin{figure}[H] \caption{Einstellungen mit aktiviertem Dark Mode und Farbauswahl} \label{settingsDark} \centering {\shadowimage[width=7cm]{./assets/screenshots/settingsDark.png}} \end{figure}

\End{multicols}

Die WLAN-Einstellungen sind in einer eigenen Ansicht untergebracht in der eine Liste an verfügbaren WLAN-Netzwerken angezeigt wird (siehe Abbildung \ref{settingsWifiList}). Wählt der Benutzer ein Netzwerk aus, so werden die Details des Netzwerks in einem Dialogfenster im Vollbildmodus angezeigt (siehe Abbildung \ref{settingsWifiDetails}). Von da aus kann der Benutzer sich mit dem Netzwerk verbinden und kann falls nötig ein Passwort eingeben. Die Eingabe des Passworts geschieht wie auch beim Morsecode Feature in einem eigenen Fenster mit der Tastatur.

\begin{multicols}{2}

\begin{figure}[H] \caption{WLAN Netzwerke Liste} \label{settingsWifiList} \centering {\shadowimage[width=7cm]{./assets/screenshots/settingsWifiList.png}} \end{figure}

\begin{figure}[H] \caption{WLAN Netzwerk Details} \label{settingsWifiDetails} \centering {\shadowimage[width=7cm]{./assets/screenshots/settingsWifiDetails.png}} \end{figure}

\end{multicols}

In der Implementierung wird das Paket nm genutzt, welches von Canonical, dem Unternehmen hinter der weltbekannten Linux Distribution Ubuntu, entwickelt wurde. Dieses Paket bietet eine Schnittstelle zum NetworkManager, welcher das Netzwerkmanagement unter Linux übernimmt. Diese Schnittstelle wird über die D-Bus API vom NetworkManager angesprochen, dazu wird das Paket dbus genutzt, welches auch von Canonical entwickelt wurde. Canonical gibt hiermit auch eine Beispielimplementierung in Dart, die zeigt wie man eine DBUS-Schnittstelle in Dart implementiert. Das nm Paket ist unter GitHub verfügbar [@CanonicalNmDart2023].

In der Geschäftslogikschicht wurde zur Ansteuerung des nm Pakets ein eigener Controller WifiController implementiert, der die Funktionalität des nm Pakets kapselt. In dem Controller sind Funktionen wie disconnectFromWifiNetwork und connectToWifiNetwork implementiert und es kann ein wifiStream abonniert werden, der den aktuellen Status des WLANs zusammen mit verfügbaren WLAN Netzwerken zurückgibt. Der Stream nutzt hierzu das neue Records Feature von Dart, welches seit Version 3.0 verfügbar ist [@googleinc.Records]. Records funktionieren technisch ähnlich zu klassischen Tuplen und werden im Stream genutzt, um Objekte der Klassen NetworkManagerDevice und NetworkManagerClient zusammen zu übergeben. Auflistung \ref{wifiStream} zeigt den Ausschnitt des WifiController mit dem wifiStream.

Die Implementierung des WifiControllers ist nur sehr rudimentär und deckt nur die nötigsten Funktionen ab, um auf dem Raspberry Pi sich mit einem WLAN Netzwerk zu verbinden. Das Abspeichern der Verbindung wird von dem NetworkManager selbst übernommen und es funktioniert in der Applikation problemlos.

@riverpod
class WifiController extends _$WifiController {

  ...

  NetworkManagerDevice get _device => state.value!.devices
      .firstWhere((d) => d.deviceType == NetworkManagerDeviceType.wifi);

  Stream<(NetworkManagerDevice, NetworkManagerClient)> wifiStream() {
    return Stream.periodic(const Duration(milliseconds: 100), (_) {
      return (_device, state.value!);
    });
  }

  ...
}

Dieser WifiController wird auch für den Status des WLANs in der Statusleiste genutzt, um den aktuellen Status des WLANs anzuzeigen.

Erstellung der Yocto-Distribution