In den letzten Beiträgen wurde die Struktur des Smarthome-Systems ein wenig angepasst, um es leichter um neue Geräte-Typen erweitern zu können. Da diese Anpassungen nicht unbedeutend in manche Systemteile eingegriffen haben, muss nun auch die Smarthome-App ein wenig angepasst werden. Es sind jedoch nur drei Klassen der App betroffen, nämlich "RoomFragment", "MainActivity" und "Icons". Nachdem die Klassen angepasst wurden, werden noch die Methoden der Klasse "SaveData" implementiert und der Login-Bildschirm optimiert.
MainActivity anpassen
Als erstes öffnest du die Datei "MainActivity.java" im Java-Verzeichnis des Projektes. Da die Struktur der Datenbank optimiert wurde und die Icons der Räume jetzt in der Datenbank abgespeichert werden, muss in der MainActivity beim Erstellen des Hauptmenüs der abgespeicherte Icon des Raumes übergeben werden. Dazu muss in der Methode createRooms() der Konstruktoraufruf angepasst werden. Der zweite Parameter des Konstruktoraufrufs in Zeile 217 wird zu "Icons.getRoomIcon(o.getString("icon"))".drawerItemList.add(new DrawerItem(o.getString("name"), Icons.getRoomIcon(o.getString("icon")), o.getString("location"), new RoomFragment()));
Icons bearbeiten
Anschließend wird die Datei "Icons.java" geöffnet. Hier wird nun die Methode getRoomIcon() angelegt, die in der MainActivity aufgerufen wurde. Diese Methode liefert den Icon des Raumes des übergebenen Key's zurück:/**
* Gibt anhand des übergebenen Key's den passenden Icon zurück
* @param key
* @return
*/
public static int getRoomIcon(String key){
//Methode wird später genauer implementiert
switch(key){
default:
return R.mipmap.ic_launcher;
}
}
RoomFragment anpassen
Öffne nun die Klasse "RoomData.java", um auch dort ein paar Anpassungen vorzunehmen. Als erstes wird in der Klasse RoomItem die Variable "deviceType" erstellt (Zeile 4), eine Getter-Methode dafür implementiert (Zeile 59 - 65) und der Konstruktor entsprechend angepasst (Zeile 7 & Zeile 15). In dieser neuen Variable wid abgespeichert, von welchem Gerätetypen das Gerät ist. Damit kann das Smarthome-System leichter um neue Geräte erweitert werden. Die Klasse RoomItem sollte nach den Änderungen so aussehen:public class RoomItem{
//Hier wurde die Variable "deviceType" hinzugefügt
private String name, device, icon, type, value, deviceType;
//Hier wurde der Parameter "deviceType" hinzugefügt
public RoomItem(String name, String device, String icon, String deviceType, String type, String value){
this.name = name;
this.device = device;
this.icon = icon;
this.type = type;
this.value = value;
//Hier wurde eine Wertezuweisung hinzugefügt
this.deviceType = deviceType;
}
/**
* Gibt den Namen des Items zurück
* @return
*/
public String getName(){
return name;
}
/**
* Gibt den Wert des Items zurück
* @return
*/
public String getValue(){
return value;
}
/**
* Gibt den Typ des Items zurück
* @return
*/
public String getType(){
return type;
}
/**
* Gibt den Icon des Items zurück
* @return
*/
public String getIcon(){
return icon;
}
/**
* Gibt das Device des Items zurück
* @return
*/
public String getDevice(){
return device;
}
//Hier wurde eine Getter-Methode für den Gerätetypen hinzugefügt
/**
* Gibt den Gerätetypen des Items zurück
* @return
*/
public String getDeviceType(){
return deviceType;
}
}
roomItems.add(new RoomItem(c.getString("name"), c.getString("device"), c.getString("icon"),
c.getString("device_type"), c.getString("type"), c.getString("value")));
showOverview(ri.getDeviceType(), ri.getDevice());
setModes(ri, !switchViewHolder.switchView.isChecked());
public void showOverview(String type, String sensor){}
public void setModes(final RoomItem item, boolean mode){}
SaveData implementieren
Im nächsten Schritt werden die Methoden der Klasse SaveData implementiert, damit die Login-Daten der Nutzer gespeichert werden können. Dazu wird die Datei "SaveData.java" geöffnet. Hier werden am Anfang der Datei sechs neue Variablen angelegt. Die ersten drei speichern den Nutzernamen, das Passwort und die Server-IP. Die anderen drei Variablen enthalten den Pfad zu den Speicherorten der Dateien für Nutzername, Passwort und Server-IP. Alle Variablen sind private statische Strings.private static String username = null;
private static String password = null;
private static String serverIp = null;
private static String usernameFile = "uname.ini";
private static String passwordFile = "psw.ini";
private static String serverFile = "serverip.ini";
/**
* Gibt den Nutzernamen zurück
* @param context Kontext der App
* @return der Nutzername
*/
public static String getUsername(Context context){
String savedUsername = readFromFile(context, usernameFile);
if(savedUsername != null){
username = savedUsername;
}
return username;
}
/**
* Gibt das Password zurück
* @param context Kontext der App
* @return das Passwort
*/
public static String getPassword(Context context){
String savedPassword = readFromFile(context, passwordFile);
if(savedPassword != null){
password = savedPassword;
}
return password;
}
/**
* Gibt die IP zurück
* @param context Kontext der App
* @return die IP
*/
public static String getServerIp(Context context){
String savedIp = readFromFile(context, serverFile);
if(savedIp != null){
serverIp = savedIp;
}
return serverIp;
}
/**
* Setzt die Login-Daten des Nutzers
* @param context Kontext der App
* @param uname Nutzername
* @param pw Passwort
* @param saveData true, wenn Daten gespeichert werden sollen
* false, wenn nicht
*/
public static void setLoginData(Context context, String uname, String pw, boolean saveData){
if(saveData){
writeToFile(context, usernameFile, uname);
writeToFile(context, passwordFile, pw);
}
username = uname;
password = pw;
}
public static void setServerIp(Context context, String serverIp){}
/**
* Gibt zurück, ob die Nutzerdaten gespeichert wurden
* @param context Kontext der App
* @return
*/
public static boolean getSaveLoginData(Context context){
boolean saveLoginData = (getUsername(context) != null && getPassword(context) != null);
return saveLoginData;
}
/**
* Schreibt den übergebenen Text in die angegebene Datei
* @param context Kontext der App
* @param filePath Pfad der Datei
* @param text der zu schreibende Text
*/
private static void writeToFile(Context context, String filePath, String text){
try{
FileOutputStream fos = context.openFileOutput(filePath, Context.MODE_PRIVATE);
fos.write(text.getBytes());
fos.close();
}catch(IOException e){
e.printStackTrace();
}
}
/**
* Gibt den Text der ausgegebenen Datei aus
* @param context Kontext der App
* @param filePath Pfad der zu lesenden Datei
* @return String mit dem Inhalt der Datei oder null, falls Datei leer ist oder es einen Fehler gab
*/
private static String readFromFile(Context context, String filePath){
String text = "";
try{
FileInputStream fis = context.openFileInput(filePath);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while((line = bufferedReader.readLine()) != null){
sb.append(line);
}
text = ""+sb;
if(text.equals("")){
return null;
}
}catch(Exception e){
e.printStackTrace();
text = null;
}
return text;
}
/**
* Löscht alle gespeicherten Nutzerdaten
* @param context Kontext der App
*/
public static void deleteAllUserData(Context context){
writeToFile(context, usernameFile, "");
writeToFile(context, passwordFile, "");
writeToFile(context, serverFile, "");
username = null;
password = null;
serverIp = null;
}
Login-Bildschirm optimieren
Jetzt wird der Login-Bildschirm an die neuen Methoden der Klasse SaveData angepasst. Öffne dazu die Klasse "LoginActivity.java". Als erstes werden die Aufrufe auf die eben gelöschte Methode setSaveLoginData() entfernt. Dazu löscht du den setSaveLoginData()-Aufruf in Zeile 61. Anschließend wird der OnCheckedChangedListener in Zeile 72 - 76 entfernt, da er nicht mehr benötigt wird. Der Methode login() wird ein weiterer Parameter namens "saveData" vom Typ boolean hinzugefügt, mit dem angegeben wird, ob die Daten gespeichert werden sollen:public void login(final String username, final String password, final String serverIp, final boolean saveData){
//...
}
SaveData.setLoginData(getApplicationContext(), username, password, saveData);
SaveData.setServerIp(getApplicationContext(), serverIp);
login(username, password, serverIp, saveLogin.isChecked());
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_ROOMS, result);
startActivity(intent);
finish();
Logout-Button erstellen
Um einen Logout-Button zu erstellen, öffnest du zuerst die Datei "main.xml" im Verzeichnis "/res/menu" und fügst dort einen neuen Item-Block hinzu, der den Titel "Ausloggen", die ID "action_logout" und bei showAsAction "never" hat. Damit wird der Button immer als Text angezeigt.<item
android:id="@+id/action_logout"
android:orderInCategory="100"
android:title="Ausloggen"
app:showAsAction="never" />
Logout-Button in MainActivity einfügen
Damit die App auch reagiert, wenn der Logout-Button geklickt wird, muss die Methode onOptionsItemSelected() ein wenig erweitert werden. Dazu wechselst du wieder zur Datei "MainActivity.java" und erstellst in dem vorhandenen if-Block einen "else if"-Block für den Buttonklick, der die gespeicherten Nutzerdaten löscht, die Login-Activity startet und die MainActivity beendet:else if(post_id == R.id.action_logout){
SaveData.deleteAllUserData(getApplicationContext());
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
Dieser Beitrag hat dir gefallen?
Dann abonniere doch unseren Newsletter!