Einführung in Android

Werbung
Einführung in Android
März 2015 | Anke Visser
1
Android
Eigenschaften

Android ist ein auf Linux basierendes Betriebssystem für
Smartphones und Tablets

Android ist freie Software

Android bietet eine Java Programmierschnittstelle

Mit dem AndroidSDK wird eine Entwicklungsumgebung für
Unix oder Windows bereitgestellt (Compiler, Debugger,
Emulator)
2
Dokumentation

http://developer.android.com
API, Tutorials, Styleguides und vieles mehr
http://developer.android.com/reference
http://developer.android.com/resources
http://www.androidbuch.de/
Deutsches Buch, eine alte Version ist als pdf kostenlos
erhältlich
–
–


HINWEIS:
Die bisher in Java genutzte API steht in Android nur
teilweise zur Verfügung. Es gibt z.B. das Paket java.util,
aber es enthält nicht alle Klassen der Java
Standardbibliothek.
3
Arbeitsumgebung: Eclipse mit ADT
Android SDK (http://developer.android.com/sdk)
Eclipse Plugin: Android Development Tools (ADT)
 Generiert automatisch alle benötigten Dateien
 Konfiguriert und startet Emulator
 Erzeugt apk Datei (Android Package)
Installation (im Ausbildungsraum bereits installiert)
 Vorhandes Eclipse:
– Download and install SDK
– Menü Help->Install New Software
– Work with: https://dl-ssl.google.com/android/eclipse/
– Window->Preferences->Android : SDK Location
 Window->Android SDK Manager
Auswahl der gewünschten Android-Version
(abwärtskompatibel? Vorschlag: 4er Version)
4
Erstellen eines Emulators
in Eclipse/Android Studio
Eclipse: Window->Android Virtual Device Manager
Button „New“ wählen, Fenster „Create new Android Virtual
Device“ wird aufgerufen
Target: Android-Version
– ggf. Auflösung des eigenen Gerätes eintragen
– ggf. weitere Emulatoren mit anderen Android-Versionen
und Auflösungen zum Testen
Der Emulator kann mit „Start“ aufgerufen werden.
–
Android Studio: Tools->Android->AVD Manager
Hinweis: Das Anlegen eines Emulator dauert auf den
Maschinen im Ausbildungsraum ggf. etwas länger
5
Das erste Projekt (Eclipse)
Application name: LaengenRechner, package name: matse.projekt
Eclipse:

Erstellen Sie einen eigenen Workspace für Ihre Android-Projekte

File->New->Other...
Select a wizard: Android ->Android Application Project

New Android Application Project
Testen auf dem Emulator:

Starten des Emulators

Run as Android Application, oder falls nicht vorhanden:
–
Run Configurations → Android Application erstellen
AndroidStudio:

File->New Project

Auwahl: "Phone and Tablet" + API version

Auswahl: "Blank aktivity"
6
Projektstruktur eines Android-Projektes
Die Projektstruktur wird von Eclipse/Android Studio erzeugt:

src: Quelldateien ( unter Android Studio: java )

res: Resourcen
drawable: Bilder in verschiedenen Auflösungen
– layout: Oberflächenelemente
– values: In der App benutzte Texte (=>Internationalisierung)
AndroidManifest.xml
Startpunkt und alle Eigenschaften und Rechte sind hier
beschrieben
–

Beim Build-Prozess erzeugte Ordner und Dateien

gen: automatisch generierte Quelldateien, z.B. R.java

bin: LaengenRechner.apk (Installationsdatei, nur Eclipse)
7
Projektstruktur
Beispiel 1. Projekt: LaengenRechner
Activity (.../src/matse/projekt/LaengenRechnerActivity.java)

Subklasse von Activity

Komponente, die Benutzerinteraktion realisiert

Main-Activity wird beim Anlegen eines Android Projektes
automatisch erzeugt und in das Manifest eingetragen

onCreate() ist der Startpunkt der Activity
View (LaengenRechner/res/layout/main.xml)

XML-Datei oder Java-Datei

XML-Datei legt die Komponenten der Oberfläche und ihr
Layout fest

Activity greift auf diese Komponenten zu
8
LaengenRechnerActivity.java
Die erste Activity wird von Eclipse automatisch erzeugt:
package matse.projekt;
import android.app.Activity;
import android.os.Bundle;
public class LaengenRechnerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
R.layout.main ist eine Referenz auf res/layout/main.xml und
wird von Eclipse erzeugt und in Klasse R automatisch verlinkt.
9
R.java
In der Klasse R werden alle Resourcen des aktuellen Paketes
verwaltet und mit einer eindeutigen ID versehen.
R.java

wird automatisch erzeugt

enthält Verweise auf alle Resourcen aus dem Ordner res, z.B.
–
–
–
–
Views, die in der inneren Klasse R.layout verwaltet werden,
z.B. die Hauptansicht R.layout.main
IDs innerhalb der xml-Dateien @id/name → R.id.name
Bilder, die mit R.drawable.bildname angesprochen werden
Strings die in der inneren Klasse R.string aufgelistet werden
10
Aufgabe: LaengenRechner
Erstellen der GUI

res/layout/main.xml auswählen

Tab wählen: Graphical Layout/Design[

[Form] Widget: 2 Radiobuttons:
cm->inch
inch->cm erstellen

Text Fields: 2 Textfelder
double-Eingabe
cm und inch

[Form] Widget: 1 Button mit Text ok
Alle Eingabefelder müssen mit sinnvollen Namen versehen
werden, um sie in der Activity ansprechen zu können
11
main.xml
<?xml version="1.0" encoding="utf­8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Längenmaßumrechner"
android:textSize="24sp" />
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/meter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Zentimeter ­> Inch" />
12
LaengenRechner
Erweitern der Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // layout aus main.xml setzen
// Gui­Elemente aus res/layouts/main.xml suchen
RadioButton meter = (RadioButton) findViewById(R.id.meter);
RadioButton inch = (RadioButton) findViewById(R.id.inch);
EditText bmeter = (EditText) findViewById(R.id.bmeter);
EditText binch = (EditText) findViewById(R.id.binch);
Button ok = (Button) findViewById(R.id.ok);
// ok­Button soll auf Klick reagieren
ok.setOnClickListener(new OkClick());
}
13
Listener
Zur Reaktion auf Benutzereingaben werden Listener benötigt.
Die Klasse Button stellt die folgende Methode bereit:
void setOnClickListener(View.OnClickListener l);
Beim Klicken auf den Button wird von der Klasse Button die
Methode onClick aufgerufen.
public interface OnClickListener {
public void onClick(View v);
}
Der Listener kann z.B. als innere Klasse implementiert
werden:
public class OkClick implements OnClickListener { public void onClick(View v) {
System.out.println(“Button wurde geklickt“);
}
}
14
Aufgabe
Erstellen Sie für die Arbeit mit Android einen separaten
Workspace in Eclipse.
Implementieren sie den Längenrechner.

Der Benutzer wählt zuerst ob Inch oder cm angegeben
werden

Danach wird in das entsprechende Eingabefeld der
umzurechnende Wert eingegeben

Nach Drücken des „Ok“-Buttons wird der entsprechende
Wert in Inch oder cm berechnet und in das passende
Textfeld eingetragen
15
Komponenten / Activities
Bisher bestand das Programm nur aus einer Komponente.
Android-Programme bestehen aus einer oder mehreren
Komponenten (z.B. Activities)
Diese Komponenten

können von anderen Komponenten des Programms
aktiviert werden

können auch von fremden Programmen aktiviert werden

können Informationen vom Aufrufer erhalten und
Informationen an den Aufrufer zurückgeben

müssen im Manifest des Programms deklariert werden
16
Weitere Activities und Views erzeugen
Eine neue Activity mit zugehöriger View kann mit
File->New ->Other...->Android Activity
erzeugt werden. Sie ist Subklasse von android.app.Activity.
Die neue Activity muss in AndroidManifest.xml eingetragen
werden, was bei Eclipse automatisch erfolgt.
<activity
android:name=".MeineActivity" >
</activity>
Zum Erzeugen einer weiteren View wird eine xml-Datei
benötigt
File->New- > Other...-> android XML file
17
Kommunikation mit Intents
Starten einer Activity
Eine neue Activity mit dem Klassennamen NextActivity soll
aufgerufen werden. Dazu wird ein Intent-Objekt benötigt.
public Intent(Context packageContext, Class<?> cls)
1. Parameter: Objekt der aufrufenden Activity denn jede Activity
ist Subklasse von Context
2. Parameter: die aufzurufende Klasse
Intent intent = new Intent(this,NextActivity.class);
startActivity(intent);
18
Kommunikation mit Intents
Starten einer Activity, Übergabe von Werten
Einem Intent können Werte hinzugefügt werden:
Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("text", "Ein Text");
intent.putExtra("zahl", 7);
startActivity(intent);
19
Intents
Lesen der übergebenen Werte
Das mitgegebene Intent-Objekt kann in der neu aufgerufenen
Activity ausgelesen werden:
public class NextActivity extends Activity
{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String text = intent.getStringExtra("text");
int zahl = intent.getIntExtra("zahl", 0);
System.out.println("Werte bekommen: "+text+","+zahl);
}
...
20
Kommunikation mit Intents
Rückgabewert einer Activity
Beim Aufruf einer Activity kann ein Ergebnis erwartet werden. In
diesem Fall wird die Methode startActivityForResult aufgerufen
und als 2. Parameter eine eindeutige ID übergeben.
private static final int MYID = 1; ...
Intent intent = new Intent(this,NextActivity.class);
startActivityForResult(intent, MYID);
21
Intents
Rückgabe eines Ergebnisses
Beim Beenden einer Activity kann ein Rückgabewert über ein
Intent gesetzt werden. Zusätzlich wird ein Resultcode mit den
Werten RESULT_CANCELED oder RESULT_OK gesetzt.
public class NextActivity extends Activity
{
...
private void ende(int zahl) {
Intent returnIntent = new Intent();
returnIntent.putExtra("value", zahl);
setResult(RESULT_OK, returnIntent); finish();
}
}
22
Intents
Ergebnis bearbeiten
Aufruf der Activity mit
startActivityForResult(intent, MYID);
Nach Beenden einer Activity mit Ergebnis wird die Methode
onActivityResult des Aufrufers aufgerufen.
[1] public void onActivityResult(int requestCode, int resultCode, Intent data) {
[2] switch (requestCode) {
[3] case MYID:
[4] switch (resultCode) {
[5] case Activity.RESULT_OK:
[6] double wert = data.getIntExra("value", 0);
[7] System.out.println("ok: "+wert);
[8] break;
[9] case Activity.RESULT_CANCELED:
[10] System.out.println("cancel"); break;
[11] }
[12] break;
[13] }
23
[14] } Zeichnen
Die Methode onDraw der Klasse View wird überschrieben:
[1] public class Drawing extends View {
[2] ...
[3] public void onDraw(Canvas canvas)
[4] {
[5] Resources res = this.getContext().getResources();
[6] Drawable image = res.getDrawable(R.drawable.cardback);
[7] int x = 50, y= 50;
[8] image.setBounds(x, y, image.getIntrinsicWidth()+x,
[9] image.getIntrinsicHeight()+y);
[10] image.draw(canvas);
[11] }
Das gezeichnete Bild ist eine png-Datei, die in den ResourcenOrdner res/drawable kopiert wurde. Die dort stehenden Dateien
(Kleinbuchstaben!) können unter R.drawable angesprochen
werden. Die Dateiendung muss weggelassen werden.
24
Reaktion auf Tasten/Touch/Klick
Weitere Listener müssen registiert werden:
[1] public class Drawing extends View implements OnTouchListener, [2] OnKeyListener {
[3] public Drawing(Context context) {
[4] super(context);
[5] setFocusable(true);
[6] setFocusableInTouchMode(true);
[7] this.setOnTouchListener(this); [8] this.setOnKeyListener(this);
[9] }
[10] public boolean onKey(View v, int keyCode, KeyEvent event) {
[11] System.out.println("key event: "+event);
[12] return false; // nicht bearbeitet => weiterleiten
[13] }
[14] // handles movement, for klick use onClickListener
[15] public boolean onTouch(View view, MotionEvent event) {
[16] System.out.println("pos: "+event.getX() + ","
[17] +event.getY());
[18] return true;
[19] }
25
Activity Lifecycle
Eine Activity kann sich in verschiedenen Zuständen befinden. Die
wesentlichen Zustände sind

resumed
Die Activity läuft im Vordergrund

paused
Eine andere Activity bekommt den Fokus, die Activity bleibt aber
sichtbar. Exklusive Resourcen (z.B. Kamera) sollten freigegeben
werden, rechenintensive Threads beendet werden.

stopped
Die Activity ist nicht mehr für den Benutzer sichbar.

destroyed
Die Activity wurde endgültig beendet.
Im Notfall (zu wenig Speicher vorhanden) kann das System die
Activity in den letzten drei Zuständen sofort beenden, so dass kein
Code dieser Activity mehr ausgeführt wird.
26
Activity Lifecycle
27
Datenhaltung
Applikationen nutzen oft eine zentrale Klasse zur Verwaltung
der Daten, z. B. Model-View-Controller
In Android ist jede Activity ein eigenständiges Element, die
Datenübergabe in Form von Referenzen ist nicht möglich.
Möglichkeiten der Datenkommunikation zwischen Activities

Intents (s. Kommunikation mit Intents)

Speichern der Daten an einem zentralen Ort
28
Daten sichern
Möglichkeiten Daten persistent zu speichern

Shared Preferences (Schlüssel-Werte-Paare)
Vorteil: einfach, für einfache Daten ausreichend

Interner Speicher (nur für die eigene App lesbar)

Externer Speicher (z.B. SD-Card, USB-Stick)

Datenbank (SQLite)
Temporäre Datenhaltung

Erstellen einer Singelton-Klasse (Klasse mit nur einer
Instanz), die von allen Activities genutzt wird. Dies bietet
die Möglichkeit komplexe Datenstrukturen zur Verfügung
zur stellen.
29
IO mit SharedPreferences
Beispiel: Spielstand sichern
[1] import android.content.SharedPreferences;
[2] import android.app.Activity;
[3] [4] public class MainActivity extends Activity [5] {
[6] private SharedPreferences prefs;
[7] static final String PREF_NAME="MyPrefs";
[8] [9] protected void onCreate(Bundle savedInstanceState) {
[10] super.onCreate(savedInstanceState);
[11] [12] prefs = getSharedPreferences(PREF_NAME, 0);
[13] int intValue = prefs.getInt("nummer", ­1);
[14] System.out.println("read value from preferences: "+intValue);
[15] [16] SharedPreferences.Editor editor = prefs.edit();
[17] editor.putInt("nummer", intValue+1); [18] boolean ok = editor.commit();
[19] System.out.println("Success writing to preferences: "+ok);
[20] }
[21] }
30
SharedPreferences
Die mit getSharedPreferences(“prefs“, 0) angesprochene
Datei /data/data/PaketeName/shared_prefs/prefs.xml kann im Emulator angesehen und editiert werden:

Das folgende Kommando öffnet eine Shell für den Emulator:
adb shell

Alternative Ansicht in der DDMS perspective in Eclipse
(File Explorer)
31
I/O
Die Methode openFileInput() von android.content.Context kann
direkt aus einer Activity aufgerufen werden.
Die Datei liegt unter /data/data/package/files/dateiname.
[1] try { // Lesen
[2] FileInputStream fin = openFileInput(dateiName1, MODE_PRIVATE);
[3] Scanner in = new Scanner(fin);
[4] while (in.hasNextLine()) {
[5] idx = in.nextInt();
[6] }
[7] // Schreiben
[8] FileOutputStream out = openFileOutput(dateiName2, MODE_PRIVATE);
[9] String inhalt = ...
[10] out.write(inhalt.getBytes());
[11] out.close();
[12] } catch (IOException e) {
[13] e.printStackTrace();
[14] }
32
Fehler und mögliche Ursachen
R.java wird nicht erzeugt/aktualisiert

import android.R;
Dieser Import darf nicht im Source stehen, wird aber unter
bestimmten Unständen von Eclipse vorgeschlagen.
33
Prioritäten beim Projekt

Funktionalität vor Design
Listen, Buttons... sehen im Default-Theme nicht sehr
dekorativ aus, können aber im Nachhinein durch zentrale
Themes angepasst werden.

Lauffähigkeit und Fehlerfreiheit vor Features
Weitere Features können beim Entwurf eingeplant werden.
Vor deren Implementierung muß die Implementation der
Hauptfunktionalität aber abgeschlossen sein.
34
Aufgabe: Activities
Der Prototyp eines Lernprogramms soll erstellt werden

Erstellen Sie dazu eine View und eine zugehörige Activity. Die
View soll zwei Buttons mit den Label „Addition üben“ und
„Subtraktion üben“ enthalten. Zusätzlich enthält sie ein
Ausgabeelement mit der Anzahl der korrekt bearbeiteten
Aufgaben.

Nach Auswahl eines Buttons soll eine neue Activity gestartet
werden, in der eine zufällige Aufgabe gestellt wird. Die Activity
bekommt die Information übergeben, ob eine Addition oder
Subtraktion geübt werden soll.

Der Benutzer soll eine Lösung eingeben, womit diese Activity
beendet wird.

Die aufrufende Activity bekommt die Information, ob die Aufgabe
korrekt gelöst wurde und wertet diese aus.
35
Herunterladen