Stand: 23.06.2018

Mobile Apps bestehen häufig aus verschiedenen Screens, zwischen denen man wechselt. Weierhin ist es üblich, zwischen verschiedenen Apps zu wechseln, z.B. von einer Mail in der Mail-App zum Browser, um einen Link zu betrachten, und zurück, oder von einer Kamera-App zu einer Chat-App, um das Foto zu teilen.

7.1 Intents

API: Intent

Intents stellen Verbindungen zwischen den Activities her, sowohl zwischen Activities der selben App als auch zwischen Activities unterschiedlicher Apps. Wenn man von Activity A zu Activity B wechseln möchte, erzeugt man ein neues Intent-Objekt und teilt dieser mit, dass man Activity B (eine Klasse) aufrufen möchte. Anschließend übergibt man den Intent einer Android-Methode, die den Übergang regelt.

Wir haben es also bei einem einfachen Übergang zwischen zwei Activities mit diesen drei Objekten zu tun:

Intent

Warum so etwas vermeintlich einfaches wie der Übergang von Activity A zu Activity B von einem Objekt geregelt werden - reicht nicht ein einfacher Funktionisaufruf? Nein, denn Intent-Objekte können eine Reihe von Zusatzinformationen zum Übergang enthalten:

7.2 Explizite Intents

Man unterscheidet zwischen expliziten Intents und impliziten Intents. Explizite Intents benutzt man, um zu einer anderen Activity zu wechseln. Es handelt sich also um einen Übergang innerhalb der eigenen App.

explizite und implizite Intents

Wir beginnen mit expliziten Intents. Nehmen wir an, wir haben eine App mit zwei Screens, also zwei Activities. In der ersten Activity (MainActivity) haben wir eine Texteingabe und einen Button. Man kann eine beliebige "Nachricht" für die zweite Screen schreiben. Auf der zweiten Screen (= SecondActivity) möchten wir den Text zeigen, den der User auf der ersten Screen eingegeben hat.

Beispiel für explizite Intents

Für den ersten Übergang erstellen ein Intent-Objekt, das die Ziel-Klasse enthält:

Intent gotoSecond = new Intent(this, SecondActivity.class);

Bei dem Buttonklick "starten" wir den Intent mit der Methode startActivity:

startActivity(gotoSecond);

Wir geben wir der SecondActivity den Text mit, den der User eingegeben hat? Wenn wir noch Daten an die zweite Screen mitgeben wollen, sind das sogenannte Extras. Extras sind aufgebaut wie eine Tabelle: wir geben für jede Information (= String) einen Schlüssel an. Bei uns heißt der Schlüssel "secret". Wir verwenden die Methode putExtra, um einem Intent eine Information hinzuzufügen.

Beispiel für explizite Intents mit Extras

Wenn wir also einen String foo hätten, könnten wir ihn mit

gotoSecond.putExtra("secret", foo);

dem Intent hinzufügen.

Im Code kann das so aussehen. Wir holen hier den Text aus dem editierbaren Textfeld (editText). Wir brauchen das "final" bei dem Intent, damit wir innerhalb des Button-Handlers auf den Intent zugreifen können.

public class MainActivity extends AppCompatActivity {

    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Intent gotoSecond = new Intent(this, SecondActivity.class);
        editText = (EditText)findViewById(R.id.editText);

        Button next = (Button)findViewById(R.id.buttonNext);
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                gotoSecond.putExtra("secret", editText.getText().toString());
                startActivity(gotoSecond);
            }
        });
    }
}

Auf der zweiten Screen können wir uns die Extra-Infos holen mit

getIntent().getExtras().get("secret");

Alternativ können wir (kürzer) schreiben:

getIntent().getStringExtra("secret");

In SecondActivity benötigen wir außerdem einen weiteren expliziten Intent, um wieder in die MainActivity zurückzukehren.

Beispiel für explizite Intents

Der Code von SecondActivity sieht wie folgt aus:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    final Intent gotoMain = new Intent(this, MainActivity.class);

    String message = getIntent().getStringExtra("secret");
    ((TextView)findViewById(R.id.textMessage)).setText(message);

    Button back = (Button)findViewById(R.id.buttonBack);
    back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(gotoMain);
        }
    });
}

7.3 Sub-Activity und Datenrückgabe [optional]

Es gibt Activities, die häufiger als "Dienst" verwendet werden, z.B. reine Eingabe-Screens für Namen, Adressen etc. Eine solche Activity kann also mit der Intention aufgerufen werden, dass ein Wert (z.B. Text) zurückgegeben wird. Dann spricht man auch von einer Sub-Activity.

Aufruf der Sub-Activity

Nehmen wir an, wir haben eine Activity A, die eine Sub-Activity B aufruft. Auch hier verwenden wir einen Intent, aber der Aufruf erfolgt mit startActivityForResult.

Damit Activity A weiß, zu welchem Zweck B aufgerufen wurde, kann ein RequestCode (eine ganze Zahl) mitgegeben werden. Das ist insbesondere dann wichtig, wenn A mehrere Sub-Activities aufrufen kann, denn die Ergebnisse werden alle in einer einzigen Methoden aufgefangen.

Außerdem kann man dem eigenen Intent Extras mitgeben (s.o.). Damit kann man einer Eingabemaske mitgeben, was man genau abfragen will ("Name" oder "Telefon").

Nehmen wir an, Sie haben eine (Sub-)Activity FrageActivity, die dem User eine Frage stellen kann und die Antwort zurückgibt.

Intent intent = (this, FrageActivity.class);
intent.putExtra("fragetext", "Warum ist die Banane krumm?");
startActivityForResult(intent, 0);

Den RequestCode setzen wir einfach auf 0.

In der Sub-Activity

In der Sub-Activity B wird z.B. eine Eingabemaske gezeigt und auf Input gewartet. Typischerweise hat man Buttons für "OK" und "Abbrechen". Sobald OK gedrückt wird, kann man in Activity A zurückspringen. Dazu

Hinweis: Nicht den Result-Code mit dem Request-Code verwechseln! Der Result-Code besagt, ob der User abgebrochen oder bestätigt hat. Der Result-Code sagt der aufrufenden Activity, von welcher Sub-Activity das Ergebnis kommt.

In unserem Beispiel mit der FrageActivity nehmen wir an, dass wir eine EditText-Komponente in der Variablen editText halten. Sofern der User die Eingabe bestätigt, rufen wir dies auf:

Intent intent = new Intent();
intent.putExtra("antwort", editText.getText().toString());
setResult(RESULT_OK, intent);
finish();

Bei "Abbrechen" setzt man setResult auf RESULT_CANCELED und ruft finish auf.

Beachten Sie, dass die Sub-Activity nach Aufruf von finish komplett zerstört wird (siehe Modul Lifecycle).

Ergebnis auffangen

In Activity A wird nach Beendigung von Sub-Activity B die Methode onActivityResult aufgerufen. Diese muss man also implementieren (d.h. überschreiben). Innerhalb der Methode kann man sich den ResultCode anschauen (ist entweder RESULT_OK oder RESULT_CANCELED) und den RequestCode (hat man selbst bestimmt). In dem mitgelieferten Intent-Objekt stehen die Extras, wo auch die Eingabe gespeichert wurde.

In unserem Beispiel wären wir z.B. wieder in MainActivity:

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    if (requestCode == 0 && resultCode == RESULT_OK) {
        String antwort = intent.getStringExtra("anwort", "KEINE ANTWORT");
        ...
    }
}

Wie schon erwähnt wird immer diese eine Methode aufgerufen, egal von welcher Sub-Activity wir zurückkehren (für den Fall, dass mehr als eine Sub-Activity von A aus aufgerufen werden kann). Der Request-Code dient in solchen Fällen dazu, die Ergebnisse korrekt zu behandeln. Hier haben wir der Sub-Activity lediglich eine 0 mitgegeben und bekommen diese auch zurück.

7.4 Übung

Kontaktseite mit Edit-Activity

Schreiben Sie für eine Kontakte-App eine Sub-Activity, in der Sie eine Texteingabe machen können.

Ihre App besteht aus einer Seite mit Feldern für Name, Telefon und Mail:

Kontaktseite

Wird jetzt einer der drei Edit-Buttons betätigt, springt die App in eine Sub-Activity, in der die Texteingabe erfolgen kann. Beachten Sie, dass über dem Texteingabe-Feld (Klasse EditText, in der Design-Ansicht unter "Plain Text") noch steht, um welche Eingabe es sich handelt (Name, Telefon oder Mail):

Edit-Screen

Wenn auf OK geklickt wird, wird die Eingabe in das entsprechende Feld übernommen:

Kontaktseite mit Name

Hier nochmal schematisch der Ablauf:

Ablauf