Datenspeicherung

Einleitung

Die Android-Plattform bietet mehrere Möglichkeiten der Datenspeicherung an. Je nach Anwendungsfall kann eine geeignete Variante gewählt werden.

Shared Preferences

Diese Art der Speicherung eignet sich sehr gut für einfache Anwendungen, wie das Speichern von Einstellungen. Es handelt sich um einen Key-Value-Store, in den Werte anhand eines Namens eingetragen und wieder ausgelesen werden können. Nur die eigene Anwendung hat Zugriff auf diese Daten.

Um Shared Preferences zu testen, wird zuerst ein neues Projekt angelegt und eine Activity erstellt. Die Benutzeroberfläche soll ein einfaches Texteingabefeld enthalten und einen Button. Beim Start der Activity soll ein gespeicherter Wert in das Textfeld geschrieben werden. Diesen kann der Nutzer ändern und durch einen Klick auf den Button soll der neue Wert gespeichert werden. Dieser sollte dann beim nächsten Start der Activity angezeigt werden.

Um Werte auszulesen, gibt es die Methoden getPreferences() und getSharedPreferences() . Der Unterschied besteht darin, dass bei der zweiten Methode ein Name angegeben werden kann. Dies wird benötigt, wenn mehrere Einstellungsdateien von der Activity genutzt werden. Die Klasse SharedPreferences besitzt Methoden wie getString , getBoolean usw., welchen als erster Parameter der Name der Einstellung übergeben wird. Ein zweiter Parameter gibt einen Standardwert an, welche zurückgegeben wird, wenn der Parametername nicht existiert.

public class PreferencesTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        SharedPreferences preferences = getPreferences(MODE_PRIVATE);
        
        EditText editText = (EditText) findViewById(R.id.editText);
        editText.setText(preferences.getString("myvalue", ""));
    }
}

Um Werte zu ändern, wird ein Editor benötigt. Diesen erhält man durch Aufrug der Methode edit() . Der Editor besitzt Methode zum Setzen von Einstellungen, wie putString() und putBoolean() . Diese Methoden speichern die Einstellungen jedoch noch nicht auf dem Gerät ab. Dazu muss am Ende die Methode commit() aufgerufen werden. Um dieses Vorgehen zu demonstrieren, wird dem Button ein OnClickListener hinzugefügt, welcher den aktuellen Wert aus dem Textfeld nimmt und in den Einstellungen speichert.

package de.hszg.mobileapps;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class PreferencesTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        SharedPreferences preferences = getPreferences(MODE_PRIVATE);
        
        final EditText editText = (EditText) findViewById(R.id.editText);
        editText.setText(preferences.getString("myvalue", ""));
        
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                SharedPreferences preferences = getPreferences(MODE_PRIVATE);
                
                Editor editor = preferences.edit();
                editor.putString("myvalue", editText.getText().toString());
                
                editor.commit();
            }
        });
    }
}

Internal Storage

Diese Art der Datenspeicherung ermöglicht es, Dateien zu speichern. Mit der Methode openFileOutput() erhält man einen FileOutputStream , welcher zum Schreiben der Daten genutzt werden kann. Das vorangegange Beispiel wird nun so abgeändert, dass der Wert in einer Datei gespeichert und aus dieser wieder ausgelesen wird.

package de.hszg.mobileapps;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class PreferencesTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        final EditText editText = (EditText) findViewById(R.id.editText);
        
        FileInputStream fis = null;
        try {
            fis = openFileInput("test_file");
            InputStreamReader reader = new InputStreamReader(fis);
            BufferedReader br = new BufferedReader(reader);
            editText.setText(br.readLine());
            
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if(fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String string = editText.getText().toString();

                try {
                    FileOutputStream fos = openFileOutput("test_file", MODE_PRIVATE);
                    fos.write(string.getBytes());
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Datenbanken

Sollten die ersten beiden Varianten zur Datenspeicherung nicht ausreichen, so kann als Alternative SQLite verwendet werden. Die Android-Plattform stellt die Klasse SQLiteOpenHelper zur Verfügung. Erbt man von dieser Klasse kann die Methode onCreate() überschrieben werden. Innerhalb dieser kann ein SQL-Statement zur Erstellung der Datenbank ausgeführt werden:

public class MyDatabaseOpenHelper extends SQLiteOpenHelper {

    MyDatabaseOpenHelper(Context context) {
        super(context, "MyDB", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE mytable (" +
                "column1 TEXT, " +
                "column2 TEXT);");
    }
}

Der letzte Parameter, der dem Oberklassen-Konstruktor übergeben wird ist die Version der Datenbank. Sobald diese erhöht oder verringert wird, wird die Datenank neu erstellt. Dafür müssen die Methoden onUpgrade() sowie onDowngrade() überschrieben werden. Innerhalb dieser können alte Tabellen gelöscht und neue angelegt werden. Der Lese- und Schreibzugriff auf die Datenbank erfolgt über ein Objekt vom Typ SQLiteDatabase. Dieses erhält man mit den methode getReadableDatabase() bzw. getWritableDatabase(). Unter http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html können von dieser Klasse zur Verfügung gestellte Methoden betrachtet werden. Wichtig sind vor allem die Methoden execSQL() sowie query() mit seinen Überladungen

.

External Storage

Mit External Storage ist es möglich, Daten auf einer Speicherkarte abzulegen. Eine Übersicht über die Verwendung dieser Methode findet man auf der Entwicklerseite von Android unter http://developer.android.com/guide/topics/data/data-storage.html.

Hinweis: Für die Projektaufgabe werden nur Internal Storage und Shared Preferences benötigt.