Intents und Intent-Filter

Ein Intent ist ein Messaging-Objekt, mit dem Sie eine Aktion von einer anderen App-Komponente anfordern können. Intents erleichtern die Kommunikation zwischen Komponenten auf verschiedene Weise. Es gibt drei grundlegende Anwendungsfälle:

  • Aktivität starten

    Ein Activity steht für einen einzelnen Bildschirm in einer App. Sie können eine neue Instanz von Activity starten, indem Sie ein Intent an startActivity() übergeben. Die Intent beschreibt die zu startende Aktivität und enthält alle erforderlichen Daten.

    Wenn Sie nach Abschluss der Aktivität ein Ergebnis erhalten möchten, rufen Sie startActivityForResult() auf. Ihre Aktivität erhält das Ergebnis als separates Intent-Objekt im onActivityResult()-Callback Ihrer Aktivität. Weitere Informationen finden Sie im Leitfaden zu Aktivitäten.

  • Dienst starten

    Ein Service ist eine Komponente, die Vorgänge im Hintergrund ohne Benutzeroberfläche ausführt. Ab Android 5.0 (API-Level 21) können Sie einen Dienst mit JobScheduler starten. Weitere Informationen zu JobScheduler finden Sie in der API-reference documentation.

    Bei Versionen vor Android 5.0 (API-Level 21) können Sie einen Dienst mit Methoden der Klasse Service starten. Sie können einen Dienst starten, um einen einmaligen Vorgang auszuführen (z. B. eine Datei herunterzuladen), indem Sie ein Intent an startService() übergeben. Die Intent beschreibt den zu startenden Dienst und enthält alle erforderlichen Daten.

    Wenn der Dienst mit einer Client-Server-Schnittstelle entwickelt wurde, können Sie ihn über eine andere Komponente binden, indem Sie ein Intent an bindService() übergeben. Weitere Informationen finden Sie im Leitfaden Dienste.

  • Broadcast senden

    Ein Broadcast ist eine Nachricht, die von jeder App empfangen werden kann. Das System sendet verschiedene Broadcasts für Systemereignisse, z. B. wenn das System hochfährt oder das Gerät mit dem Laden beginnt. Sie können einen Broadcast an andere Apps senden, indem Sie ein Intent an sendBroadcast() oder sendOrderedBroadcast() übergeben.

Im Rest dieses Dokuments wird erläutert, wie Intents funktionieren und wie Sie sie verwenden. Weitere Informationen finden Sie unter Interaktion mit anderen Apps und Inhalte teilen.

Intent-Typen

Es gibt zwei Arten von Intents:

  • Explizite Intents geben an, welche Komponente welcher Anwendung den Intent erfüllen soll, indem ein vollständiger ComponentName angegeben wird. Normalerweise verwenden Sie einen expliziten Intent, um eine Komponente in Ihrer eigenen App zu starten, da Sie den Klassennamen der Aktivität oder des Dienstes kennen, die bzw. den Sie starten möchten. Sie können beispielsweise als Reaktion auf eine Nutzeraktion eine neue Aktivität in Ihrer App starten oder einen Dienst starten, um eine Datei im Hintergrund herunterzuladen.
  • Bei impliziten Intents wird keine bestimmte Komponente angegeben, sondern eine allgemeine Aktion deklariert, die ausgeführt werden soll. Dadurch kann sie von einer Komponente einer anderen App verarbeitet werden. Wenn Sie dem Nutzer beispielsweise einen Ort auf einer Karte anzeigen möchten, können Sie mit einem impliziten Intent anfordern, dass eine andere geeignete App einen bestimmten Ort auf einer Karte anzeigt.

Abbildung 1 zeigt, wie eine Absicht beim Starten einer Aktivität verwendet wird. Wenn im Intent-Objekt eine bestimmte Aktivitätskomponente explizit angegeben ist, startet das System diese Komponente sofort.

Abbildung 1: So wird ein impliziter Intent über das System übergeben, um eine andere Aktivität zu starten: [1] Aktivität A erstellt einen Intent mit einer Aktionsbeschreibung und übergibt ihn an startActivity(). [2] Das Android-System sucht in allen Apps nach einem Intent-Filter, der mit dem Intent übereinstimmt. Wenn eine Übereinstimmung gefunden wird, [3] startet das System die passende Aktivität (Activity B), indem es die Methode onCreate() aufruft und ihr die Intent übergibt.

Wenn Sie einen impliziten Intent verwenden, sucht das Android-System nach der geeigneten Komponente, die gestartet werden soll. Dazu werden die Inhalte des Intents mit den Intent-Filtern verglichen, die in der Manifestdatei anderer Apps auf dem Gerät deklariert sind. Wenn die Absicht mit einem Intent-Filter übereinstimmt, startet das System die entsprechende Komponente und übergibt ihr das Intent-Objekt. Wenn mehrere Intent-Filter kompatibel sind, zeigt das System ein Dialogfeld an, in dem der Nutzer auswählen kann, welche App verwendet werden soll.

Ein Intent-Filter ist ein Ausdruck in der Manifestdatei einer App, der den Typ der Intents angibt, die die Komponente empfangen möchte. Wenn Sie beispielsweise einen Intent-Filter für eine Aktivität deklarieren, können andere Apps Ihre Aktivität direkt mit einer bestimmten Art von Intent starten. Wenn Sie für eine Aktivität keine Intent-Filter deklarieren, kann sie nur mit einem expliziten Intent gestartet werden.

Achtung:Damit Ihre App sicher ist, sollten Sie beim Starten eines Service immer einen expliziten Intent verwenden und keine Intent-Filter für Ihre Dienste deklarieren. Die Verwendung einer impliziten Intention zum Starten eines Dienstes ist ein Sicherheitsrisiko, da Sie nicht sicher sein können, welcher Dienst auf die Intention reagiert, und der Nutzer nicht sehen kann, welcher Dienst gestartet wird. Ab Android 5.0 (API-Level 21) löst das System eine Ausnahme aus, wenn Sie bindService() mit einem impliziten Intent aufrufen.

Intent erstellen

Ein Intent-Objekt enthält Informationen, die das Android-System verwendet, um zu bestimmen, welche Komponente gestartet werden soll (z. B. der genaue Komponentenname oder die Komponenten-Kategorie, die den Intent empfangen soll), sowie Informationen, die die Empfängerkonponente verwendet, um die Aktion richtig auszuführen (z. B. die auszuführende Aktion und die Daten, auf die sich die Aktion bezieht).

Die wichtigsten Informationen in einer Intent sind:

Komponentenname
Der Name der Komponente, die gestartet werden soll.

Das ist optional, aber es ist die entscheidende Information, die einen Intent explizit macht. Das bedeutet, dass der Intent nur an die App-Komponente gesendet werden sollte, die durch den Komponentennamen definiert ist. Ohne Komponentennamen ist die Intention implizit und das System entscheidet anhand der anderen Intent-Informationen (z. B. Aktion, Daten und Kategorie, siehe unten), welche Komponente die Intention empfangen soll. Wenn Sie eine bestimmte Komponente in Ihrer App starten müssen, sollten Sie den Namen der Komponente angeben.

Hinweis:Wenn Sie eine Service starten, müssen Sie immer den Komponentennamen angeben. Andernfalls können Sie nicht sicher sein, welcher Dienst auf den Intent reagiert, und der Nutzer kann nicht sehen, welcher Dienst gestartet wird.

Dieses Feld von Intent ist ein ComponentName-Objekt, das Sie mit einem voll qualifizierten Klassennamen der Zielkomponente angeben können, einschließlich des Paketnamens der App, z. B. com.example.ExampleActivity. Sie können den Komponentennamen mit setComponent(), setClass(), setClassName() oder mit dem Intent-Konstruktor festlegen.

Aktion
Ein String, der die auszuführende generische Aktion angibt, z. B. view oder pick.

Bei einer Broadcast-Intent ist dies die Aktion, die stattgefunden hat und über die berichtet wird. Die Aktion bestimmt weitgehend, wie der Rest des Intents strukturiert ist, insbesondere die Informationen, die in den Daten und Extras enthalten sind.

Sie können eigene Aktionen für die Verwendung durch Intents in Ihrer App oder durch andere Apps zum Aufrufen von Komponenten in Ihrer App angeben. In der Regel geben Sie jedoch Aktionskonstanten an, die von der Klasse Intent oder anderen Framework-Klassen definiert werden. Hier sind einige gängige Aktionen zum Starten einer Aktivität:

ACTION_VIEW
Verwenden Sie diese Aktion in einem Intent mit startActivity(), wenn Sie Informationen haben, die in einer Aktivität für den Nutzer angezeigt werden können, z. B. ein Foto, das in einer Galerie-App angezeigt werden soll, oder eine Adresse, die in einer Karten-App angezeigt werden soll.
ACTION_SEND
Dieser Intent wird auch als share-Intent bezeichnet. Sie sollten ihn in einem Intent mit startActivity() verwenden, wenn Sie Daten haben, die der Nutzer über eine andere App wie eine E-Mail-App oder eine App zum Teilen in sozialen Netzwerken teilen kann.

Weitere Konstanten, die generische Aktionen definieren, finden Sie in der Intent-Klassenreferenz. Andere Aktionen werden an anderer Stelle im Android-Framework definiert, z. B. in Settings für Aktionen, die bestimmte Bildschirme in den Einstellungen des Systems öffnen.

Sie können die Aktion für einen Intent mit setAction() oder mit einem Intent-Konstruktor angeben.

Wenn Sie eigene Aktionen definieren, müssen Sie den Paketnamen Ihrer App als Präfix angeben, wie im folgenden Beispiel gezeigt:

Kotlin

const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"

Java

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Daten
Der URI (ein Uri-Objekt), der auf die Daten verweist, auf die reagiert werden soll, und/oder der MIME-Typ dieser Daten. Die Art der bereitgestellten Daten wird in der Regel durch die Aktion des Intents bestimmt. Wenn die Aktion beispielsweise ACTION_EDIT ist, sollten die Daten den URI des zu bearbeitenden Dokuments enthalten.

Beim Erstellen einer Absicht ist es oft wichtig, zusätzlich zum URI den Datentyp (MIME-Typ) anzugeben. Eine Aktivität, die Bilder anzeigen kann, kann beispielsweise wahrscheinlich keine Audiodatei abspielen, auch wenn die URI-Formate ähnlich sein könnten. Wenn Sie den MIME-Typ Ihrer Daten angeben, kann das Android-System die beste Komponente für den Empfang Ihres Intents finden. Der MIME-Typ kann jedoch manchmal aus dem URI abgeleitet werden, insbesondere wenn es sich bei den Daten um einen content:-URI handelt. Ein content:-URI gibt an, dass sich die Daten auf dem Gerät befinden und von einem ContentProvider gesteuert werden, wodurch der MIME-Typ der Daten für das System sichtbar ist.

Wenn Sie nur den Daten-URI festlegen möchten, rufen Sie setData() auf. Wenn Sie nur den MIME-Typ festlegen möchten, rufen Sie setType() auf. Bei Bedarf können Sie beide explizit mit setDataAndType() festlegen.

Achtung:Wenn Sie sowohl den URI als auch den MIME-Typ festlegen möchten, rufen Sie setData() und setType() nicht auf, da sie sich gegenseitig aufheben. Verwenden Sie immer setDataAndType(), um sowohl URI als auch MIME-Typ festzulegen.

Category
Ein String mit zusätzlichen Informationen zur Art der Komponente, die den Intent verarbeiten soll. In einer Intention kann eine beliebige Anzahl von Kategoriebeschreibungen angegeben werden. Für die meisten Intentionen ist jedoch keine Kategorie erforderlich. Hier sind einige gängige Kategorien:
CATEGORY_BROWSABLE
Die Zielaktivität kann von einem Webbrowser gestartet werden, um Daten anzuzeigen, auf die über einen Link verwiesen wird, z. B. ein Bild oder eine E‑Mail-Nachricht.
CATEGORY_LAUNCHER
Die Aktivität ist die erste Aktivität einer Aufgabe und wird im Anwendungs-Launcher des Systems aufgeführt.

Die vollständige Liste der Kategorien finden Sie in der Klassenbeschreibung für Intent.

Sie können eine Kategorie mit addCategory() angeben.

Die oben aufgeführten Eigenschaften (Komponentenname, Aktion, Daten und Kategorie) stellen die definierenden Merkmale einer Intention dar. Anhand dieser Eigenschaften kann das Android-System ermitteln, welche App-Komponente gestartet werden soll. Ein Intent kann jedoch zusätzliche Informationen enthalten, die sich nicht darauf auswirken, wie es in eine App-Komponente aufgelöst wird. Ein Intent kann auch die folgenden Informationen liefern:

Extras
Schlüssel/Wert-Paare, die zusätzliche Informationen enthalten, die für die Ausführung der angeforderten Aktion erforderlich sind. So wie für einige Aktionen bestimmte Arten von Daten-URIs verwendet werden, werden für einige Aktionen auch bestimmte Extras verwendet.

Sie können mit verschiedenen putExtra()-Methoden zusätzliche Daten hinzufügen. Jede Methode akzeptiert zwei Parameter: den Schlüsselnamen und den Wert. Sie können auch ein Bundle-Objekt mit allen zusätzlichen Daten erstellen und dann das Bundle mit putExtras() in das Intent einfügen.

Wenn Sie beispielsweise eine Absicht zum Senden einer E‑Mail mit ACTION_SEND erstellen, können Sie den to-Empfänger mit dem Schlüssel EXTRA_EMAIL und den subject-Betreff mit dem Schlüssel EXTRA_SUBJECT angeben.

Die Klasse Intent gibt viele EXTRA_*-Konstanten für standardisierte Datentypen an. Wenn Sie eigene zusätzliche Schlüssel deklarieren müssen (für Intents, die Ihre App empfängt), müssen Sie den Paketnamen Ihrer App als Präfix angeben, wie im folgenden Beispiel gezeigt:

Kotlin

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

Java

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

Achtung: Verwenden Sie keine Parcelable- oder Serializable-Daten, wenn Sie eine Absicht senden, die von einer anderen App empfangen werden soll. Wenn eine App versucht, auf Daten in einem Bundle-Objekt zuzugreifen, aber keinen Zugriff auf die geparcelte oder serialisierte Klasse hat, löst das System eine RuntimeException aus.

Flags
-Flags werden in der Klasse Intent definiert und dienen als Metadaten für die Intention. Die Flags können das Android-System anweisen, wie eine Aktivität gestartet werden soll (z. B. zu welcher Aufgabe die Aktivität gehören soll) und wie sie nach dem Start behandelt werden soll (z. B. ob sie in der Liste der letzten Aktivitäten enthalten sein soll).

Weitere Informationen finden Sie in der setFlags()-Methode.

Beispiel für expliziten Intent

Mit einem expliziten Intent starten Sie eine bestimmte App-Komponente, z. B. eine bestimmte Aktivität oder einen bestimmten Dienst in Ihrer App. Wenn Sie einen expliziten Intent erstellen möchten, definieren Sie den Komponentennamen für das Intent-Objekt. Alle anderen Intent-Attribute sind optional.

Wenn Sie beispielsweise einen Dienst in Ihrer App mit dem Namen DownloadService erstellt haben, der eine Datei aus dem Web herunterladen soll, können Sie ihn mit dem folgenden Code starten:

Kotlin

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
val downloadIntent = Intent(this, DownloadService::class.java).apply {
    data = Uri.parse(fileUrl)
}
startService(downloadIntent)

Java

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

Der Intent(Context, Class)-Konstruktor stellt der App Context und der Komponente ein Class-Objekt zur Verfügung. Daher wird mit diesem Intent explizit die Klasse DownloadService in der App gestartet.

Weitere Informationen zum Erstellen und Starten eines Dienstes finden Sie im Leitfaden Dienste.

Beispiel für impliziten Intent

Ein impliziter Intent gibt eine Aktion an, mit der jede App auf dem Gerät aufgerufen werden kann, die die Aktion ausführen kann. Die Verwendung eines impliziten Intents ist nützlich, wenn Ihre App die Aktion nicht ausführen kann, andere Apps dies aber wahrscheinlich können und Sie möchten, dass der Nutzer auswählt, welche App verwendet werden soll.

Wenn Sie beispielsweise möchten, dass der Nutzer Inhalte mit anderen Personen teilt, erstellen Sie einen Intent mit der Aktion ACTION_SEND und fügen Sie Extras hinzu, die die zu teilenden Inhalte angeben. Wenn Sie startActivity() mit dieser Absicht aufrufen, kann der Nutzer eine App auswählen, über die er die Inhalte teilen möchte.

Kotlin

// Create the text message with a string.
val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, textMessage)
    type = "text/plain"
}

// Try to invoke the intent.
try {
    startActivity(sendIntent)
} catch (e: ActivityNotFoundException) {
    // Define what your app should do if no activity can handle the intent.
}

Java

// Create the text message with a string.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Try to invoke the intent.
try {
    startActivity(sendIntent);
} catch (ActivityNotFoundException e) {
    // Define what your app should do if no activity can handle the intent.
}

Wenn startActivity() aufgerufen wird, prüft das System alle installierten Apps, um festzustellen, welche diese Art von Intent verarbeiten können (ein Intent mit der Aktion ACTION_SEND und den Daten „text/plain“). Wenn es nur eine App gibt, die die Anfrage verarbeiten kann, wird diese App sofort geöffnet und erhält den Intent. Wenn keine andere App die Anfrage verarbeiten kann, kann Ihre App die Ausnahme ActivityNotFoundException abfangen. Wenn mehrere Aktivitäten den Intent akzeptieren, zeigt das System ein Dialogfeld wie in Abbildung 2 an, damit der Nutzer auswählen kann, welche App verwendet werden soll.

Weitere Informationen zum Starten anderer Apps finden Sie auch im Leitfaden zum Weiterleiten des Nutzers zu einer anderen App.

Abbildung 2: Ein Auswahlfeld.

App-Auswahl erzwingen

Wenn es mehrere Apps gibt, die auf Ihren impliziten Intent reagieren, kann der Nutzer auswählen, welche App verwendet werden soll, und diese App zur Standardauswahl für die Aktion machen. Die Möglichkeit, eine Standard-App auszuwählen, ist hilfreich, wenn eine Aktion ausgeführt wird, für die der Nutzer wahrscheinlich jedes Mal dieselbe App verwenden möchte, z. B. beim Öffnen einer Webseite (Nutzer bevorzugen oft nur einen Webbrowser).

Wenn jedoch mehrere Apps auf den Intent reagieren können und der Nutzer möglicherweise jedes Mal eine andere App verwenden möchte, sollten Sie explizit ein Auswahlfeld anzeigen. Im Auswahlfeld wird der Nutzer aufgefordert, die App auszuwählen, die für die Aktion verwendet werden soll. Er kann keine Standard-App für die Aktion auswählen. Wenn Ihre App beispielsweise die Aktion ACTION_SEND ausführt, möchten Nutzer je nach aktueller Situation möglicherweise eine andere App zum Teilen verwenden. Daher sollten Sie immer den Auswahl-Dialog verwenden, wie in Abbildung 2 dargestellt.

Wenn Sie die Auswahl anzeigen möchten, erstellen Sie mit createChooser() ein Intent und übergeben Sie es an startActivity(), wie im folgenden Beispiel gezeigt. In diesem Beispiel wird ein Dialogfeld mit einer Liste von Apps angezeigt, die auf den Intent reagieren, der an die Methode createChooser() übergeben wurde. Der bereitgestellte Text wird als Dialogfeldtitel verwendet.

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
val title: String = resources.getString(R.string.chooser_title)
// Create intent to show the chooser dialog
val chooser: Intent = Intent.createChooser(sendIntent, title)

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(chooser)
}

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

Starten unsicherer Intents erkennen

Ihre App startet möglicherweise Intents, um zwischen Komponenten in Ihrer App zu wechseln oder um eine Aktion im Namen einer anderen App auszuführen. Um die Plattformsicherheit zu verbessern, bietet Android 12 (API-Level 31) und höher eine Debugging-Funktion, die Sie warnt, wenn Ihre App ein Intent auf unsichere Weise startet. Ihre App führt beispielsweise möglicherweise einen unsicheren Start eines verschachtelten Intents aus. Das ist ein Intent, der als Extra in einem anderen Intent übergeben wird.

Wenn Ihre App beide der folgenden Aktionen ausführt, erkennt das System einen unsicheren Intent-Start und es tritt ein StrictMode-Verstoß auf:

  1. Ihre App entpackt einen verschachtelten Intent aus den Extras eines ausgelieferten Intents.
  2. Ihre App startet sofort eine App-Komponente mit diesem verschachtelten Intent, z. B. indem sie den Intent an startActivity(), startService() oder bindService() übergibt.

Weitere Informationen dazu, wie Sie diese Situation erkennen und Änderungen an Ihrer App vornehmen können, finden Sie im Blogpost Android Nesting Intents auf Medium.

Auf unsichere Intent-Starts prüfen

Wenn Sie in Ihrer App nach unsicheren Intent-Starts suchen möchten, rufen Sie detectUnsafeIntentLaunch() auf, wenn Sie Ihre VmPolicy konfigurieren, wie im folgenden Code-Snippet gezeigt. Wenn Ihre App einen StrictMode-Verstoß erkennt, sollten Sie die Ausführung der App beenden, um potenziell vertrauliche Informationen zu schützen.

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}

Java

protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

Intents verantwortungsbewusster verwenden

Um die Wahrscheinlichkeit zu minimieren, dass ein unsicherer Intent gestartet wird und ein StrictMode-Verstoß auftritt, sollten Sie diese Best Practices befolgen.

Kopieren Sie nur die wichtigsten Extras in Intents und führen Sie alle erforderlichen Bereinigungen und Validierungen durch. Ihre App kopiert möglicherweise die Extras aus einem Intent in einen anderen Intent, der zum Starten einer neuen Komponente verwendet wird. Das passiert, wenn Ihre App putExtras(Intent) oder putExtras(Bundle) aufruft. Wenn Ihre App einen dieser Vorgänge ausführt, kopieren Sie nur die Extras, die die empfangende Komponente erwartet. Wenn durch den anderen Intent (der die Kopie empfängt) eine Komponente gestartet wird, die nicht exportiert wird, müssen die Extras bereinigt und validiert werden, bevor sie in den Intent kopiert werden, der die Komponente startet.

Komponenten Ihrer App nicht unnötig exportieren: Wenn Sie beispielsweise eine App-Komponente mit einem internen verschachtelten Intent starten möchten, legen Sie das Attribut android:exported dieser Komponente auf false fest.

Verwenden Sie stattdessen PendingIntent. Wenn eine andere App das PendingIntent ihres enthaltenden Intent entpackt, kann sie das PendingIntent mit der Identität Ihrer App starten. Mit dieser Konfiguration kann die andere App jede Komponente, einschließlich einer nicht exportierten Komponente, in Ihrer App sicher starten.

Das Diagramm in Abbildung 2 zeigt, wie die Steuerung vom System von Ihrer (Client-)App an eine andere (Dienst-)App und zurück an Ihre App übergeben wird:

  1. Ihre App erstellt einen Intent, der eine Aktivität in einer anderen App aufruft. In diesem Intent fügen Sie ein PendingIntent-Objekt als Extra hinzu. Dieser PendingIntent ruft eine Komponente in Ihrer App auf, die nicht exportiert wird.
  2. Nachdem die andere App den Intent Ihrer App empfangen hat, wird das verschachtelte PendingIntent-Objekt extrahiert.
  3. Die andere App ruft die Methode send() für das PendingIntent-Objekt auf.
  4. Nachdem die Steuerung an Ihre App zurückgegeben wurde, ruft das System den ausstehenden Intent mit dem Kontext Ihrer App auf.

Abbildung 2: Diagramm der Inter-App-Kommunikation bei Verwendung eines verschachtelten ausstehenden Intents.

Impliziten Intent empfangen

Wenn Sie angeben möchten, welche impliziten Intents Ihre App empfangen kann, deklarieren Sie in Ihrer Manifestdatei für jede Ihrer App-Komponenten ein oder mehrere Intent-Filter mit einem <intent-filter>-Element. Jeder Intent-Filter gibt den Typ der Intents an, die er basierend auf der Aktion, den Daten und der Kategorie des Intents akzeptiert. Das System stellt Ihrer App-Komponente nur dann eine implizite Absicht bereit, wenn die Absicht einen Ihrer Intent-Filter durchlaufen kann.

Hinweis:Eine explizite Absicht wird immer an das Ziel gesendet, unabhängig von den Intent-Filtern, die die Komponente deklariert.

Für jede eindeutige Aufgabe, die eine App-Komponente ausführen kann, sollte ein separater Filter deklariert werden. Eine Aktivität in einer Bildergalerie-App kann beispielsweise zwei Filter haben: einen zum Anzeigen eines Bildes und einen zum Bearbeiten eines Bildes. Wenn die Aktivität gestartet wird, wird Intent geprüft und anhand der Informationen in Intent (z. B. ob die Editor-Steuerelemente angezeigt werden sollen) wird entschieden, wie sich die Aktivität verhalten soll.

Jeder Intent-Filter wird durch ein <intent-filter>-Element in der Manifestdatei der App definiert, das in der entsprechenden App-Komponente (z. B. einem <activity>-Element) verschachtelt ist.

Legen Sie in jeder App-Komponente, die ein <intent-filter>-Element enthält, explizit einen Wert für android:exported fest. Dieses Attribut gibt an, ob die App-Komponente für andere Apps zugänglich ist. In einigen Situationen, z. B. bei Aktivitäten, deren Intent-Filter die Kategorie LAUNCHER enthalten, ist es sinnvoll, dieses Attribut auf true festzulegen. Andernfalls ist es sicherer, dieses Attribut auf false zu setzen.

Warnung:Wenn in Ihrer App eine Aktivität, ein Dienst oder ein Broadcast-Empfänger Intent-Filter verwendet und der Wert für android:exported nicht explizit festgelegt ist, kann Ihre App nicht auf einem Gerät mit Android 12 oder höher installiert werden.

Im <intent-filter>-Element können Sie den Typ der zu akzeptierenden Intents mit einem oder mehreren der folgenden drei Elemente angeben:

<action>
Gibt an, dass die Intent-Aktion im Attribut name akzeptiert wurde. Der Wert muss der Literalstringwert einer Aktion sein, nicht die Klassenkonstante.
<data>
: Deklariert den Typ der akzeptierten Daten mithilfe von einem oder mehreren Attributen, die verschiedene Aspekte des Daten-URI (scheme, host, port, path) und des MIME-Typs angeben.
<category>
Gibt die akzeptierte Intent-Kategorie im Attribut name an. Der Wert muss der Literal-Stringwert einer Aktion sein, nicht die Klassenkonstante.

Hinweis:Damit Sie implizite Intents empfangen können, müssen Sie die Kategorie CATEGORY_DEFAULT in den Intent-Filter aufnehmen. Bei den Methoden startActivity() und startActivityForResult() werden alle Intents so behandelt, als ob sie die Kategorie CATEGORY_DEFAULT deklariert hätten. Wenn Sie diese Kategorie nicht in Ihrem Intent-Filter deklarieren, werden keine impliziten Intents für Ihre Aktivität aufgelöst.

Hier ist ein Beispiel für eine Aktivitätsdeklaration mit einem Intent-Filter zum Empfangen eines ACTION_SEND-Intents, wenn der Datentyp Text ist:

<activity android:name="ShareActivity" android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Sie können einen Filter erstellen, der mehrere Instanzen von <action>, <data> oder <category> enthält. Wenn Sie das tun, müssen Sie sicher sein, dass die Komponente alle Kombinationen dieser Filterelemente verarbeiten kann.

Wenn Sie mehrere Arten von Intents verarbeiten möchten, aber nur in bestimmten Kombinationen aus Aktion, Daten und Kategorie, müssen Sie mehrere Intent-Filter erstellen.

Eine implizite Intention wird anhand eines Filters getestet, indem die Intention mit jedem der drei Elemente verglichen wird. Damit die Intent an die Komponente übermittelt werden kann, muss sie alle drei Tests bestehen. Wenn auch nur eine der beiden nicht übereinstimmt, wird der Intent vom Android-System nicht an die Komponente übergeben. Da eine Komponente jedoch mehrere Intent-Filter haben kann, kann ein Intent, der einen Filter einer Komponente nicht durchläuft, möglicherweise einen anderen Filter durchlaufen. Weitere Informationen dazu, wie das System Intents auflöst, finden Sie unten im Abschnitt Intent-Auflösung.

Achtung : Die Verwendung eines Intent-Filters ist keine sichere Methode, um zu verhindern, dass andere Apps Ihre Komponenten starten. Intention-Filter schränken zwar ein, dass eine Komponente nur auf bestimmte Arten von impliziten Intents reagiert, aber eine andere App kann Ihre App-Komponente möglicherweise mit einem expliziten Intent starten, wenn der Entwickler die Namen Ihrer Komponenten kennt. Wenn es wichtig ist, dass nur Ihre eigene App eine Ihrer Komponenten starten kann, deklarieren Sie keine Intent-Filter in Ihrem Manifest. Legen Sie stattdessen das Attribut exported für diese Komponente auf "false" fest.

Um zu vermeiden, dass versehentlich die Service einer anderen App ausgeführt wird, sollten Sie immer einen expliziten Intent verwenden, um Ihren eigenen Dienst zu starten.

Hinweis:Für alle Aktivitäten müssen Sie Ihre Intent-Filter in der Manifestdatei deklarieren. Filter für Broadcast-Receiver können jedoch dynamisch registriert werden, indem registerReceiver() aufgerufen wird. Du kannst den Empfänger dann mit unregisterReceiver() abmelden. So kann Ihre App nur während eines bestimmten Zeitraums auf bestimmte Broadcasts warten, während sie ausgeführt wird.

Beispielfilter

Um einige der Verhaltensweisen von Intent-Filtern zu veranschaulichen, finden Sie hier ein Beispiel aus der Manifestdatei einer App zum Teilen in sozialen Netzwerken:

<activity android:name="MainActivity" android:exported="true">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity" android:exported="false">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

Die erste Aktivität, MainActivity, ist der Haupteinstiegspunkt der App – die Aktivität, die geöffnet wird, wenn der Nutzer die App zum ersten Mal über das Launcher-Symbol startet:

  • Die Aktion ACTION_MAIN gibt an, dass dies der Haupteinstiegspunkt ist und keine Intent-Daten erwartet werden.
  • Die Kategorie CATEGORY_LAUNCHER gibt an, dass das Symbol für diese Aktivität im App-Launcher des Systems platziert werden soll. Wenn im Element <activity> kein Symbol mit icon angegeben ist, verwendet das System das Symbol aus dem Element <application>.

Diese beiden müssen gekoppelt werden, damit die Aktivität im App Launcher angezeigt wird.

Die zweite Aktivität, ShareActivity, soll das Teilen von Text- und Medieninhalten erleichtern. Nutzer können diese Aktivität zwar über MainActivity aufrufen, aber auch direkt über eine andere App, die einen impliziten Intent ausgibt, der mit einem der beiden Intent-Filter übereinstimmt.ShareActivity

Hinweis:Der MIME-Typ application/vnd.google.panorama360+jpg ist ein spezieller Datentyp, der Panoramabilder angibt, die Sie mit den Google-Panorama-APIs verarbeiten können.

Intents mit Intent-Filtern anderer Apps abgleichen

Wenn eine andere App auf Android 13 (API‑Level 33) oder höher ausgerichtet ist, kann sie den Intent Ihrer App nur verarbeiten, wenn Ihr Intent mit den Aktionen und Kategorien eines <intent-filter>-Elements in dieser anderen App übereinstimmt. Wenn das System keine Übereinstimmung findet, wird eine ActivityNotFoundException ausgelöst. Die sendende App muss diese Ausnahme behandeln.

Wenn Sie Ihre App so aktualisieren, dass sie auf Android 13 oder höher ausgerichtet ist, werden alle Intents, die von externen Apps stammen, nur dann an eine exportierte Komponente Ihrer App gesendet, wenn der Intent den Aktionen und Kategorien eines <intent-filter>-Elements entspricht, das von Ihrer App deklariert wird. Dieses Verhalten tritt unabhängig von der SDK-Zielversion der sendenden App auf.

In den folgenden Fällen wird der Intent-Abgleich nicht erzwungen:

  • Intents, die an Komponenten gesendet werden, für die keine Intent-Filter deklariert sind.
  • Intents, die aus derselben App stammen.
  • Intents, die vom System stammen, d. h. Intents, die von der „System-UID“ (uid=1000) gesendet werden. Zu den System-Apps gehören system_server und Apps, bei denen android:sharedUserId auf android.uid.system festgelegt ist.
  • Intents, die vom Stamm stammen.

Weitere Informationen zum Abgleich von Intentionen

Pending Intent verwenden

Ein PendingIntent-Objekt ist ein Wrapper für ein Intent-Objekt. Der Hauptzweck einer PendingIntent besteht darin, einer fremden Anwendung die Berechtigung zu erteilen, die enthaltene Intent so zu verwenden, als ob sie aus dem eigenen Prozess Ihrer App ausgeführt würde.

Wichtige Anwendungsfälle für einen ausstehenden Intent:

  • Deklarieren eines Intents, der ausgeführt werden soll, wenn der Nutzer eine Aktion mit Ihrer Benachrichtigung ausführt (das NotificationManager des Android-Systems führt den Intent aus).
  • Deklarieren einer Absicht, die ausgeführt werden soll, wenn der Nutzer eine Aktion mit Ihrem App-Widget ausführt (die Startbildschirm-App führt die Intent aus).
  • Eine Absicht deklarieren, die zu einem bestimmten zukünftigen Zeitpunkt ausgeführt werden soll (das Android-System AlarmManager führt die Intent aus).

So wie jedes Intent-Objekt für die Verarbeitung durch einen bestimmten Typ von App-Komponente (entweder eine Activity, eine Service oder eine BroadcastReceiver) konzipiert ist, muss auch eine PendingIntent unter Berücksichtigung dieser Aspekte erstellt werden. Wenn Sie einen ausstehenden Intent verwenden, führt Ihre App den Intent nicht mit einem Aufruf wie startActivity() aus. Stattdessen müssen Sie den gewünschten Komponententyp deklarieren, wenn Sie die PendingIntent erstellen, indem Sie die entsprechende Erstellungsmethode aufrufen:

Sofern Ihre App keine Pending Intents von anderen Apps empfängt, sind die oben genannten Methoden zum Erstellen eines PendingIntent wahrscheinlich die einzigen PendingIntent-Methoden, die Sie jemals benötigen werden.

Jede Methode verwendet die aktuelle App Context, die Intent, die Sie umschließen möchten, und ein oder mehrere Flags, die angeben, wie der Intent verwendet werden soll (z. B. ob der Intent mehr als einmal verwendet werden kann).

Weitere Informationen zur Verwendung ausstehender Intents finden Sie in der Dokumentation für die jeweiligen Anwendungsfälle, z. B. in den API-Leitfäden zu Benachrichtigungen und App-Widgets.

Unveränderlichkeit angeben

Wenn Ihre App auf Android 12 oder höher ausgerichtet ist, müssen Sie die Veränderlichkeit aller PendingIntent-Objekte angeben, die von Ihrer App erstellt werden. Um anzugeben, ob ein bestimmtes PendingIntent-Objekt veränderlich oder unveränderlich ist, verwenden Sie das Flag PendingIntent.FLAG_MUTABLE bzw. PendingIntent.FLAG_IMMUTABLE.

Wenn Ihre App versucht, ein PendingIntent-Objekt zu erstellen, ohne eines der beiden Mutabilitäts-Flags festzulegen, löst das System eine IllegalArgumentException aus und die folgende Meldung wird in Logcat angezeigt:

PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

Nach Möglichkeit unveränderliche ausstehende Intents erstellen

In den meisten Fällen sollte Ihre App unveränderliche PendingIntent-Objekte erstellen, wie im folgenden Code-Snippet gezeigt. Wenn ein PendingIntent-Objekt unveränderlich ist, können andere Apps die Intention nicht ändern, um das Ergebnis des Aufrufs der Intention anzupassen.

Kotlin

val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

Für bestimmte Anwendungsfälle sind jedoch veränderliche PendingIntent-Objekte erforderlich:

  • Unterstützung von Aktionen zum direkten Antworten in Benachrichtigungen. Für die direkte Antwort ist eine Änderung der Clipdaten im PendingIntent-Objekt erforderlich, das mit der Antwort verknüpft ist. Normalerweise fordern Sie diese Änderung an, indem Sie FILL_IN_CLIP_DATA als Flag an die Methode fillIn() übergeben.
  • Benachrichtigungen mit dem Android Auto-Framework verknüpfen, indem Instanzen von CarAppExtender verwendet werden.
  • Unterhaltungen in Bubbles platzieren, indem Instanzen von PendingIntent verwendet werden. Ein veränderliches PendingIntent-Objekt ermöglicht es dem System, die richtigen Flags wie FLAG_ACTIVITY_MULTIPLE_TASK und FLAG_ACTIVITY_NEW_DOCUMENT anzuwenden.
  • Standortinformationen des Geräts werden durch Aufrufen von requestLocationUpdates() oder ähnlichen APIs angefordert. Mit dem veränderlichen PendingIntent-Objekt kann das System Intent-Extras hinzufügen, die Standort-Lebenszyklusereignisse darstellen. Zu diesen Ereignissen gehören eine Änderung des Standorts und die Verfügbarkeit eines Anbieters.
  • Weckrufe mit AlarmManager planen. Das veränderliche PendingIntent-Objekt ermöglicht es dem System, das Intent-Extra EXTRA_ALARM_COUNT hinzuzufügen. Diese Zusatzinformation gibt an, wie oft ein sich wiederholender Alarm ausgelöst wurde. Durch dieses Extra kann die Intention eine App genau darüber informieren, ob ein sich wiederholender Wecker mehrmals ausgelöst wurde, z. B. wenn sich das Gerät im Ruhemodus befand.

Wenn Ihre App ein veränderliches PendingIntent-Objekt erstellt, wird dringend empfohlen, einen expliziten Intent zu verwenden und ComponentName auszufüllen. Wenn eine andere App PendingIntent aufruft und die Steuerung an Ihre App zurückgibt, wird immer dieselbe Komponente in Ihrer App gestartet.

Explizite Intents in ausstehenden Intents verwenden

Damit Sie besser festlegen können, wie andere Apps die ausstehenden Intents Ihrer App verwenden können, sollten Sie einen ausstehenden Intent immer in einen expliziten Intent einbetten. So können Sie diese Best Practice umsetzen:

  1. Prüfen Sie, ob die Felder für Aktion, Paket und Komponente des Basis-Intents festgelegt sind.
  2. Verwenden Sie FLAG_IMMUTABLE>, das in Android 6.0 (API-Level 23) hinzugefügt wurde, um ausstehende Intents zu erstellen. Dieses Flag verhindert, dass Apps, die ein PendingIntent empfangen, nicht festgelegte Attribute selbst festlegen. Wenn das minSdkVersion Ihrer App 22 oder niedriger ist, können Sie die Informationen zu Sicherheit und Kompatibilität zusammen mit dem folgenden Code angeben:

    if (Build.VERSION.SDK_INT >= 23) {
      // Create a PendingIntent using FLAG_IMMUTABLE.
    } else {
      // Existing code that creates a PendingIntent.
    }

Intent-Auflösung

Wenn das System einen impliziten Intent zum Starten einer Aktivität empfängt, sucht es nach der besten Aktivität für den Intent. Dazu wird der Intent anhand von drei Aspekten mit Intent-Filtern verglichen:

  • Aktion.
  • Daten (sowohl URI als auch Datentyp).
  • Kategorie:

In den folgenden Abschnitten wird beschrieben, wie Intents den entsprechenden Komponenten gemäß der Intent-Filter-Deklaration in der Manifestdatei einer App zugeordnet werden.

Aktion testen

Um akzeptierte Intent-Aktionen anzugeben, kann in einem Intent-Filter null oder mehr <action>-Elemente deklariert werden, wie im folgenden Beispiel gezeigt:

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

Damit der Filter angewendet wird, muss die in Intent angegebene Aktion mit einer der im Filter aufgeführten Aktionen übereinstimmen.

Wenn im Filter keine Aktionen aufgeführt sind, gibt es nichts, worauf ein Intent abgestimmt werden kann. Daher bestehen alle Intents den Test nicht. Wenn in einem Intent jedoch keine Aktion angegeben ist, wird der Test bestanden, sofern der Filter mindestens eine Aktion enthält.

Kategorietest

Um akzeptierte Intent-Kategorien anzugeben, kann ein Intent-Filter null oder mehr <category>-Elemente deklarieren, wie im folgenden Beispiel gezeigt:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

Damit eine Intention den Kategorietest besteht, muss jede Kategorie in Intent mit einer Kategorie im Filter übereinstimmen. Das Gegenteil ist nicht erforderlich: Der Intent-Filter kann mehr Kategorien deklarieren als in Intent angegeben sind, und Intent wird trotzdem bestanden. Daher besteht eine Intention ohne Kategorien diesen Test immer, unabhängig davon, welche Kategorien im Filter deklariert sind.

Hinweis:Android wendet die Kategorie CATEGORY_DEFAULT automatisch auf alle impliziten Intents an, die an startActivity() und startActivityForResult() übergeben werden. Wenn Ihre Aktivität implizite Intents empfangen soll, muss sie in ihren Intent-Filtern eine Kategorie für "android.intent.category.DEFAULT" enthalten, wie im vorherigen <intent-filter>-Beispiel gezeigt.

Datentest

Wenn Sie akzeptierte Intent-Daten angeben möchten, können Sie in einem Intent-Filter null oder mehr <data>-Elemente deklarieren, wie im folgenden Beispiel gezeigt:

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

Für jedes <data>-Element kann eine URI-Struktur und ein Datentyp (MIME-Medientyp) angegeben werden. Jeder Teil des URI ist ein separates Attribut: scheme, host, port und path:

<scheme>://<host>:<port>/<path>

Das folgende Beispiel zeigt mögliche Werte für diese Attribute:

content://com.example.project:200/folder/subfolder/etc

In diesem URI ist das Schema content, der Host com.example.project, der Port 200 und der Pfad folder/subfolder/etc.

Jedes dieser Attribute ist in einem <data>-Element optional, es gibt jedoch lineare Abhängigkeiten:

  • Wenn kein Schema angegeben ist, wird der Host ignoriert.
  • Wenn kein Host angegeben ist, wird der Port ignoriert.
  • Wenn sowohl das Schema als auch der Host nicht angegeben sind, wird der Pfad ignoriert.

Wenn der URI in einem Intent mit einer URI-Spezifikation in einem Filter verglichen wird, wird er nur mit den Teilen des URI verglichen, die im Filter enthalten sind. Beispiel:

  • Wenn in einem Filter nur ein Schema angegeben ist, stimmen alle URIs mit diesem Schema mit dem Filter überein.
  • Wenn in einem Filter ein Schema und eine Autorität, aber kein Pfad angegeben sind, werden alle URIs mit demselben Schema und derselben Autorität unabhängig von ihren Pfaden vom Filter akzeptiert.
  • Wenn in einem Filter ein Schema, eine Autorität und ein Pfad angegeben sind, werden nur URIs mit demselben Schema, derselben Autorität und demselben Pfad berücksichtigt.

Hinweis:Eine Pfadspezifikation kann ein Platzhaltersternchen (*) enthalten, um nur einen teilweisen Abgleich des Pfadnamens zu erfordern.

Beim Datentest werden sowohl der URI als auch der MIME-Typ im Intent mit einem im Filter angegebenen URI und MIME-Typ verglichen. Es gelten die folgenden Regeln:

  1. Ein Intent, das weder einen URI noch einen MIME-Typ enthält, besteht den Test nur, wenn im Filter keine URIs oder MIME-Typen angegeben sind.
  2. Ein Intent, das einen URI, aber keinen MIME-Typ enthält (weder explizit noch aus dem URI ableitbar), besteht den Test nur, wenn der URI mit dem URI-Format des Filters übereinstimmt und der Filter ebenfalls keinen MIME-Typ angibt.
  3. Ein Intent, der einen MIME-Typ, aber keinen URI enthält, besteht den Test nur, wenn im Filter derselbe MIME-Typ aufgeführt ist und kein URI-Format angegeben ist.
  4. Ein Intent, das sowohl einen URI als auch einen MIME-Typ enthält (entweder explizit oder aus dem URI ableitbar), besteht den MIME-Typ-Teil des Tests nur, wenn dieser Typ mit einem im Filter aufgeführten Typ übereinstimmt. Der URI-Teil des Tests wird entweder bestanden, wenn der URI mit einem URI im Filter übereinstimmt oder wenn er einen content:- oder file:-URI hat und im Filter kein URI angegeben ist. Mit anderen Worten: Eine Komponente unterstützt content:- und file:-Daten, wenn in ihrer Filterliste nur ein MIME-Typ aufgeführt ist.

Hinweis:Wenn in einer Intent ein URI oder MIME-Typ angegeben ist, schlägt der Datentest fehl, wenn es keine <data>-Elemente in der <intent-filter> gibt.

Diese letzte Regel (d) spiegelt die Erwartung wider, dass Komponenten lokale Daten aus einer Datei oder einem Contentanbieter abrufen können. Daher kann in ihren Filtern nur ein Datentyp aufgeführt werden. Die Schemas content: und file: müssen nicht explizit angegeben werden. Das folgende Beispiel zeigt einen typischen Fall, in dem ein <data>-Element Android mitteilt, dass die Komponente Bilddaten von einem Contentanbieter abrufen und anzeigen kann:

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

Filter, die einen Datentyp, aber keinen URI angeben, sind vielleicht am häufigsten, da die meisten verfügbaren Daten von Content-Anbietern bereitgestellt werden.

Eine weitere gängige Konfiguration ist ein Filter mit einem Schema und einem Datentyp. Mit einem <data>-Element wie dem folgenden wird Android beispielsweise mitgeteilt, dass die Komponente Videodaten aus dem Netzwerk abrufen kann, um die Aktion auszuführen:

<intent-filter>
    <data android:scheme="http" android:mimeType="video/*" />
    ...
</intent-filter>

Intent-Abgleich

Intents werden nicht nur mit Intent-Filtern abgeglichen, um eine Zielkomponente zu aktivieren, sondern auch, um Informationen über die Komponenten auf dem Gerät zu erhalten. Die Home App füllt den App-Launcher beispielsweise, indem sie alle Aktivitäten mit Intent-Filtern findet, die die Aktion ACTION_MAIN und die Kategorie CATEGORY_LAUNCHER angeben. Eine Übereinstimmung ist nur erfolgreich, wenn die Aktionen und Kategorien im Intent mit dem Filter übereinstimmen, wie in der Dokumentation für die Klasse IntentFilter beschrieben.

Ihre Anwendung kann Intent-Abgleich auf ähnliche Weise wie die Home App verwenden. Die PackageManager hat eine Reihe von query...()-Methoden, die alle Komponenten zurückgeben, die einen bestimmten Intent akzeptieren können, und eine ähnliche Reihe von resolve...()-Methoden, die die beste Komponente zum Reagieren auf einen Intent ermitteln. queryIntentActivities() gibt beispielsweise eine Liste aller Aktivitäten zurück, die den als Argument übergebenen Intent ausführen können, und queryIntentServices() gibt eine ähnliche Liste von Diensten zurück. Bei keiner der beiden Methoden werden die Komponenten aktiviert. Es werden nur die Komponenten aufgeführt, die antworten können. Für Broadcast-Empfänger gibt es eine ähnliche Methode: queryBroadcastReceivers().