Intents in Android

Android Entwicklung: Grundlagen Logo
Was sind Intents?

Intents in Android sind asynchrone Nachrichten, die es App-Komponenten (z. B. Activities) ermöglichen, eine bestimmte Funktionalität von einer anderen Komponente anzufordern. Intents sorgen dabei entweder für die Kommunikation zwischen Komponenten innerhalb der gleichen App oder zwischen den Komponenten von zwei verschiedenen Apps.

Intents können aus insgesamt drei unterschiedlichen Zwecken eingesetzt werden:

  • Senden einer Broadcast-Nachricht
  • Starten einer Activity
  • Starten eines Services

 

Beispiel:

Angenommen, du möchtest in deiner App Fotos bearbeiten können und benötigst dazu die Hilfe einer Foto-Verwaltungsapp (z.B. Google Fotos), um an die Fotos auf deinem Smartphone zu kommen. Hier kannst du jetzt mittels einer Komponente deiner App eine Komponente einer anderen App (Foto-Verwaltungsapp) aufrufen. In der Komponente der fremden App wählst du dann ein Foto aus und kehrst anschließend zu deiner App zurück, um das ausgewählte Foto zu bearbeiten. Für die Interaktion zwischen den Komponenten benötigst du Intents.

 

Welche Arten von Intents gibt es?

Es gibt insgesamt zwei verschiedene Intents, die wir nachfolgend kurz erklären:

Expliziter Intent:

Explizite Intents werden hauptsächlich für die Kommunikation zwischen Komponenten innerhalb einer App verwendet. Dabei musst du explizit diejenige Komponente (z. B. Activity, Service) benennen, die vom Android-System aufgerufen werden soll, indem du den Klassennamen als Bezeichner verwendest.

Beispiel-Code:
(1) final String URL = "https://www.big-app.de";

(2) Intent browserIntent = new Intent(this, BrowserActivity.class); //Intent mit Ziel anlegen 
(3) browserIntent.setData(Uri.parse(URL)); //Dem Intent die Daten mitgeben, mit denen er arbeiten soll (4) startActivity(browserIntent); //Eine neue Activity mit dem fertigen Intent-Objekt starten 

Beispiel-Erklärung: 
(1) In der ersten Zeile legen wir einen String mit der URL unserer Website an, die wir in einem Browser (z. B. Chrome-App) anschauen möchten

(2) In der zweiten Zeile erzeugen wir einen expliziten Intent üben den Intent-Konstruktor, der mit "this" als ersten Parameter den Kontext der aktuellen Activity und mit "BrowserActivity.class" den Klassennamen der Ziel-Activity als zweiten Parameter bekommt.
>> ACHTUNG: Beim Klassennamen darauf achten, dass hinter dem Namen ein ".class" eingefügt wird! 

(3) In der dritten Zeile übergeben wir der "setData()"-Methode ein URI-Objekt mit der URL als Daten für den Intent. 

(4) In der vierten Zeile starten wir dann über die "startActivity()"-Methode die Ziel-Activity und übergeben dieser Methode das Intent-Objekt.

 

Impliziter Intent:

Implizite Intents werden überwiegend für die Kommunikation zwischen den Komponenten von zwei verschiedenen Apps verwendet. Sie geben an, welche Aktion von einer Komponente ausgeführt werden soll und eventuell auch die Daten, die für die Aktion wichtig sind. Wenn ein impliziter Intent an das Android-System gesendet wird, sucht Android nach allen Komponenten, die für die spezifische Aktion geeignet sind. Wird nur eine Komponente gefunden, startet Android diese Komponente direkt. Wenn mehrere Komponenten durch das Android-System identifiziert werden, erhält der Benutzer einen Auswahldialog und kann selbst entscheiden, welche Komponente für den Zweck verwendet werden soll.

Beispiel-Code: 
(1) Intent browserIntent = new Intent(); //Intent ohne Ziel anlegen
(2) browserIntent.setAction(Intent.ACTION_VIEW); //Allgemeine Aktion festlegen
(3) browserIntent.setData(Uri.parse(URL)); //Dem Intent die Daten mitgeben, mit denen er arbeiten soll
(4) startActivity(browserIntent); //Eine neue Activity mit dem fertigen Intent-Objekt starten

Beispiel-Erklärung: 
(1) In der ersten Zeile erzeugen wir eine neue Instanz für den impliziten Intent.

(2) Mit Hilfe dieser Instanz wird in der zweiten Zeile zunächst über die "setAction()"-Methode eine allgemeine Aktion festgelegt. (In unserem Fall: ACTION_VIEW, um die Website anschauen zu können)

(3) In der dritten Zeile wird dann die "setData()"-Methode aufgerufen und die URL unserer Website als URI-Objekt übergeben.

(4) Zum Schluss schicken wir unser Intent-Objekt mit der "startActivity()"-Methode los, um eine neue Activity einer fremden App zu starten. Da wir ja in der ersten Zeile keine konkrete Activity angegeben haben, gibt es nun zwei Möglichkeiten:

-> Wenn nur eine Browser-App auf dem System installiert ist, dann wird diese App direkt gestartet
-> Wenn mehrere Browser-Apps auf dem System installiert sind, dann wird der Benutzer gefragt, welche davon er benutzen möchte

Das nachfolgende Bild veranschaulicht nochmal den Unterschied zwischen den beiden Intent-Arten. Dabei geht deutlich hervor, dass bei expliziten Intents die Kommunikation hauptsächlich zwischen Komponenten innerhalb der gleichen App stattfindet und bei impliziten Intents die Kommunikation zwischen zwei verschiedenen Apps abläuft.

Unterschied expliziter und impliziter Intent

 

Was muss ein Intent liefern, dass eine passende Komponente gefunden werden kann?

Jedes Intent-Objekt beinhaltet eine Reihe von Informationen, die von Android zur Bestimmung der richtigen Ziel-Komponente verwendet werden. Dazu gehören der Komponentenname, eine Aktion, bestimmte Daten und eine bestimmte Kategorie. Im weiteren Verlauf beschränken wir uns genau auf diese vier Informationsarten, obwohl es auch noch Extras und Flags geben würde. Wir verzichten also bewusst auf eine Erklärung der beiden letztgenannten Intent-Bestandteile, da diese nicht für die Bestimmung der richtigen Ziel-Komponente relevant sind.

Komponentenname: 

Der Komponentenname wird bei expliziten Intents angegeben und spezifiziert exakt diejenige Komponente (z. B. Activity, Service), die gestartet werden soll. Wenn der Komponentenname angegeben wird, kannst du dir alle anderen Informationen sparen, da Android diese Information zur Bestimmung einer passenden Komponente völlig ausreicht. Der Komponentenname kann auf drei unterschiedliche Arten festgelegt werden:

-> Intent-Konstruktor(Kontext, Ziel-Activity)
-> setClass(Kontext, Ziel-Activity) 
-> setComponent(Komponentenname)

Info: Als "Kontext" ist hier die Activity gemeint, in der man sich befindet. Über das Schlüsselwort "this" kann auf das Objekt dieser Activity gezeigt werden.

Beispiele: 
//Komponentenname über Konstruktor festlegen
Intent browserIntent = new Intent(this, BrowserActivity.class); 

//Komponentenname über setClass()-Methode festlegen
Intent browserIntent = new Intent(); 
browserIntent.setClass(this, BrowserActivity.class);

//Komponentenname über setComponent()-Methode festlegen
Intent browserIntent = new Intent(); 
browserIntent.setComponent(new Component(this, BrowserActivity.class);

Info: Für die Ermittlung einer passenden Ziel-Komponente bei „expliziten Intents“ reicht der Komponentenname völlig aus, da Android genau weiß, welche Komponente aufzurufen ist. Für die Bestimmung einer passenden Ziel-Komponente bei „impliziten Intents“ wird jedoch kein Komponentenname angegeben und somit müssen andere Information geliefert werden, die wir nachfolgend erklären.

Action: 

Dieser Bestandteil des Intent-Objekts benennt die auszuführende oder über eine Broadcast-Nachricht zu berichtende Aktion. Dabei können von Android vordefinierte Aktionen oder sogar selbst definierte Aktionen eingesetzt werden. Zu den Android-Aktionen gehören z. B.:

-> ACTION_WEB_SEARCH: Zur Durchführung einer Websuche
-> ACTION_VIEW: Zum Anzeigen von Daten (z. B. Bilder, Website)
-> ACTION_TIMEZONE_CHANGED: Zur Mitteilung, dass sich die Zeitzone geändert hat

Allgemein wird jede Aktion mittels "Intent-Konstruktor" oder der "setAction()"-Methode bestimmt.

Beispiel für vordefinierte Aktion: 
Intent browserIntent = new Intent(Intent.ACTION_VIEW) //Aktion über Konstruktor festlegen

Intent browserIntent = new Intent() //Aktion über setAction()-Methode festlegen
browserIntent.setAction(Intent.ACTION_VIEW);

Beispiel für selbst definierte Aktion: 
static final String ACTION_MYACTION = "com.example.superindy.mycontentprovider.MYACTION";

Intent browserIntent = new Intent(ACTION_MYACTION) //Aktion über Konstruktor festlegen

Intent browserIntent = new Intent() //Aktion über setAction()-Methode festlegen
browserIntent.setAction(ACTION_MYACTION);

 

Daten:

Mit Hilfe dieses Bestandteils des Intent-Objekts werden die zu verarbeitenden Daten genauer beschrieben. Dabei kann für die Daten folgendes angegeben:

-> Der Datentyp: Mittels der "setType()"-Methode wird der Datentyp (z. B. XML) festgelegt
-> Ein URI-Objekt: Mittels der "setData()"-Methode und einem URI-Objekt wird die Adresse der Daten festgelegt (z. B. URL)
-> Der Datentyp und eine URI: Mittels der "setDataAndType()"-Methode wird beides festgelegt

Beispiel: 
browserIntent.setData(Uri.parse(URL)); //Dem Intent die Daten übergeben

 

Kategorie: 

Die Kategorie ist ein optionaler Teil des Intent-Objekts und wird als String übergeben, der zusätzliche Informationen über die Art der Komponente enthält, die ein Intent behandeln soll. Es gibt mehrere Kategorien, die festgelegt werden, wie z. B.:

-> CATEGORY_LAUNCHER: Legt fest, dass die Activity die erste Activity in einem Task ist 
-> CATEGORY_DEFAULT: Legt fest, dass eine Activity implizite Intents empfängt
-> CATEGORY_BROWSABLE: Legt fest, dass nur eine Activity sich von einem Browser starten lässt

Dabei können folgende Methoden verwendet werden:

-> addCategory(): Mit dieser Methode wird dem Intent eine Kategorie hinzugefügt
-> removeCategory(): Mit dieser Methode wird die Kategorie aus dem Intent entfernt

Beispiel: 
browserIntent.setCategory(Intent.CATEGORY_BROWSABLE); //Kategorie festlegen

 

Woher weiß Android, welche Komponenten geeignet sind, um auf implizite Intents reagieren zu können?
Jede Komponente kann sich über einen Intent-Filter im Android-Manifest für eine bestimmte Aktion, Kategorie oder Daten registrieren. Ein Intent-Filter spezifiziert die Arten von Intents, auf die eine Activity, ein Service oder ein Broadcast-Receiver reagieren kann. Dazu muss der Filter die Fähigkeiten einer Komponente deklarieren. 

Wenn ein impliziter Intent an das Android-System gesendet wird, ermittelt Android einen passenden Empfänger dazu und verwendet dafür die Daten, die im Intent-Objekt enthalten sind. Wenn sich mehrere Komponenten für denselben Intent-Filter registriert haben, kann der Benutzer entscheiden, welche Komponente gestartet werden soll.

Du kannst deine Android-Komponenten über solche Intent-Filter für bestimmte Ereignisse registrieren. Wenn für eine Komponente jedoch kein Filter definiert ist, kann sie nur durch explizite Intents aufgerufen werden!

Über die Intent-Filter können folgende Informationen festgelegt werden:

-> Action: Darüber wird eine Aktion definiert, die akzeptiert wird
-> Category: Darüber wird eine Kategorie definiert, die akzeptiert wird
-> Data: Darüber werden die unterstützenden Datentypen definiert

Im nachfolgenden Screenshot siehst du beispielsweise die AndroidManifest-Datei mit dem Intent-Filter der "MainActivity". Innerhalb des Filters ist dabei sowohl eine Aktion, als auch eine bestimmte Kategorie festgelegt. Über die Kategorie weiß Android hier z. B., dass es sich bei der "MainActivity", um die erste Activity in der App handelt und somit beim App-Start zuerst gestartet werden muss.

Intent-Filter im AndroidManifest