In diesem Dokument werden einige gängige Anwendungsfälle beschrieben, in denen eine App mit anderen Apps interagiert. Jeder Abschnitt enthält Anleitungen dazu, wie du die Funktionen der App mit eingeschränkter Paketsichtbarkeit erreichen kannst. Dies musst du berücksichtigen, wenn deine App auf Android 11 (API-Level 30) oder höher ausgerichtet ist.
Wenn eine App, die auf Android 11 oder höher ausgerichtet ist, einen Intent verwendet, um eine Aktivität in einer anderen App zu starten, ist es am einfachsten, den Intent aufzurufen und die Ausnahme ActivityNotFoundException
zu behandeln, wenn keine App verfügbar ist.
Wenn ein Teil Ihrer App davon abhängt, ob der Aufruf von startActivity()
erfolgreich sein kann, z. B. das Anzeigen einer Benutzeroberfläche, fügen Sie dem Element <queries>
des Manifests Ihrer App ein Element hinzu. In der Regel ist dies ein <intent>
-Element.
URLs öffnen
In diesem Abschnitt werden verschiedene Möglichkeiten zum Öffnen von URLs in einer App beschrieben, die auf Android 11 oder höher ausgerichtet ist.
URLs in einem Browser oder einer anderen App öffnen
Verwenden Sie zum Öffnen einer URL einen Intent mit der Intent-Aktion ACTION_VIEW
, wie im Leitfaden zum Laden einer Web-URL beschrieben. Wenn du startActivity()
mit diesem Intent aufrufst, geschieht Folgendes:
- Die URL wird in einer Webbrowser-App geöffnet.
- Die URL wird in einer App geöffnet, die die URL als Deeplink unterstützt.
- Es wird ein Dialogfeld zur Klärung der Mehrdeutigkeit angezeigt, in dem der Nutzer auswählen kann, mit welcher App die URL geöffnet werden soll.
Eine
ActivityNotFoundException
wird angezeigt, weil auf dem Gerät keine App installiert ist, mit der die URL geöffnet werden kann. (Das ist ungewöhnlich.)Es wird empfohlen, die
ActivityNotFoundException
in Ihrer App abzufangen und zu verarbeiten, wenn dies auftritt.
Da für die startActivity()
-Methode keine Paketsichtbarkeit erforderlich ist, um die Aktivität einer anderen Anwendung zu starten, müssen Sie dem Manifest Ihrer App kein <queries>
-Element hinzufügen oder Änderungen an einem vorhandenen <queries>
-Element vornehmen. Dies gilt sowohl für implizite als auch für explizite Intents, die eine URL öffnen.
Prüfen, ob ein Browser verfügbar ist
In einigen Fällen kann Ihre App prüfen, ob auf dem Gerät mindestens ein Browser verfügbar ist oder ob ein bestimmter Browser der Standardbrowser ist, bevor versucht wird, eine URL zu öffnen. Fügen Sie in diesen Fällen das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent>
Wenn Sie queryIntentActivities()
aufrufen und einen Web-Intent als Argument übergeben, enthält die zurückgegebene Liste in einigen Fällen die verfügbaren Browser-Apps. Die Liste enthält keine Browseranwendungen, wenn der Nutzer die URL so konfiguriert hat, dass sie standardmäßig in einer nicht browsergestützten Anwendung geöffnet wird.
URLs in benutzerdefinierten Tabs öffnen
Mit benutzerdefinierten Tabs lässt sich das Erscheinungsbild einer App an das Erscheinungsbild des Browsers anpassen. Sie können eine URL auf einem benutzerdefinierten Tab öffnen, ohne das <queries>
-Element im App-Manifest hinzufügen oder ändern zu müssen.
Sie sollten jedoch prüfen, ob auf dem Gerät ein Browser installiert ist, der benutzerdefinierte Tabs unterstützt, oder einen bestimmten Browser auswählen, der mit benutzerdefinierten Tabs gestartet werden soll. Verwenden Sie dazu CustomTabsClient.getPackageName()
.
Fügen Sie in diesen Fällen das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent>
URLs von nicht browsergestützten Apps verarbeiten lassen
Auch wenn Ihre App URLs mit benutzerdefinierten Tabs öffnen kann, sollten Sie nach Möglichkeit eine andere App als Browser verwenden, um eine URL zu öffnen. Wenn Sie diese Funktion in Ihrer App anbieten möchten, versuchen Sie, startActivity()
mit einem Intent aufzurufen, der das Intent-Flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER
setzt. Wenn das System eine ActivityNotFoundException
zurückgibt, kann Ihre App die URL in einem benutzerdefinierten Tab öffnen.
Wenn ein Intent dieses Flag enthält, wird bei einem Aufruf von startActivity()
eine ActivityNotFoundException
ausgelöst, wenn eine der folgenden Bedingungen erfüllt ist:
- Der Aufruf hätte direkt eine Browser-App gestartet.
- Der Aufruf hätte dem Nutzer ein Dialogfeld zur Auswahl angezeigt, in dem die einzigen Optionen für Browser-Apps sind.
Das folgende Code-Snippet zeigt, wie Sie Ihre Logik so aktualisieren, dass das Intent-Flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER
verwendet wird:
Kotlin
try { val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { // The URL should either launch directly in a non-browser app (if it's // the default) or in the disambiguation dialog. addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER } startActivity(intent) } catch (e: ActivityNotFoundException) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url) }
Java
try { Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); // The URL should either launch directly in a non-browser app (if it's the // default) or in the disambiguation dialog. intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER); startActivity(intent); } catch (ActivityNotFoundException e) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url); }
Dialogfeld zur Klärung von Mehrdeutigkeit vermeiden
Wenn Sie nicht möchten, dass das Nachfragefenster angezeigt wird, das Nutzer beim Öffnen einer URL sehen, und die URL in diesen Situationen lieber selbst verarbeiten möchten, können Sie einen Intent verwenden, der das Intent-Flag FLAG_ACTIVITY_REQUIRE_DEFAULT
festlegt.
Wenn ein Intent dieses Flag enthält, wird beim Aufruf von startActivity()
eine ActivityNotFoundException
ausgelöst, wenn dem Nutzer ein Dialogfeld zur ‑auflösung angezeigt worden wäre.
Wenn ein Intent sowohl dieses Flag als auch das Intent-Flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER
enthält, wird bei einem Aufruf von startActivity()
eine ActivityNotFoundException
ausgelöst, wenn eine der folgenden Bedingungen erfüllt ist:
- Der Aufruf hätte die Browser-App direkt gestartet.
- Bei diesem Aufruf wird dem Nutzer ein Dialogfeld zur Klärung der Mehrdeutigkeit angezeigt.
Das folgende Code-Snippet zeigt, wie die Flags FLAG_ACTIVITY_REQUIRE_NON_BROWSER
und FLAG_ACTIVITY_REQUIRE_DEFAULT
zusammen verwendet werden:
Kotlin
val url = URL_TO_LOAD try { // For this intent to be invoked, the system must directly launch a // non-browser app. val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or FLAG_ACTIVITY_REQUIRE_DEFAULT } startActivity(intent) } catch (e: ActivityNotFoundException) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url) }
Java
String url = URL_TO_LOAD; try { // For this intent to be invoked, the system must directly launch a // non-browser app. Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER | FLAG_ACTIVITY_REQUIRE_DEFAULT); startActivity(intent); } catch (ActivityNotFoundException e) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url); }
Datei öffnen
Wenn Ihre Anwendung Dateien oder Anhänge verarbeitet und beispielsweise prüft, ob ein Gerät eine bestimmte Datei öffnen kann, ist es in der Regel am einfachsten, eine Aktivität zu starten, die die Datei verarbeiten kann. Verwenden Sie dazu einen Intent mit der Intent-Aktion ACTION_VIEW
und dem URI, der die jeweilige Datei darstellt. Wenn auf dem Gerät keine App verfügbar ist, kann Ihre App die ActivityNotFoundException
abfangen. In Ihrer Logik zur Ausnahmebehandlung können Sie entweder einen Fehler anzeigen oder versuchen, die Datei selbst zu verarbeiten.
Wenn Ihre App im Voraus wissen muss, ob eine andere App eine bestimmte Datei öffnen kann, fügen Sie das Element <intent>
im folgenden Code-Snippet als Teil des Elements <queries>
in Ihr Manifest ein. Geben Sie den Dateityp an, wenn Sie bereits wissen, was es zum Zeitpunkt der Kompilierung ist.
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". --> <data android:mimeType="application/pdf" /> </intent>
Sie können dann prüfen, ob eine App verfügbar ist, indem Sie resolveActivity()
mit Ihrer Absicht aufrufen.
URI-Zugriff gewähren
Hinweis:Die Deklarierung von URI-Zugriffsberechtigungen wie in diesem Abschnitt beschrieben ist für Apps erforderlich, die auf Android 11 (API-Level 30) oder höher ausgerichtet sind. Sie wird für alle Apps empfohlen, unabhängig von der SDK-Zielversion und davon, ob sie ihre Contentanbieter exportieren.
Bei Apps, die auf Android 11 oder höher ausgerichtet sind und auf den Inhalts-URI zugreifen möchten, müssen im Intent Ihrer App Berechtigungen für den URI-Zugriff deklariert werden. Legen Sie dazu eine oder beide der folgenden Intent-Flags fest:
FLAG_GRANT_READ_URI_PERMISSION
und FLAG_GRANT_WRITE_URI_PERMISSION
.
Unter Android 11 und höher gewähren die Berechtigungen für den URI-Zugriff der App, die die Intent empfängt, die folgenden Funktionen:
- Lesen aus oder Schreiben in die Daten, die der Inhalts-URI darstellt, je nach den angegebenen URI-Berechtigungen.
- Sie erhalten Informationen zur App, die den Contentanbieter enthält, der mit der URI-Autorität übereinstimmt. Die App, die den Inhaltsanbieter enthält, kann von der App abweichen, die die Intent sendet.
Im folgenden Code-Snippet wird gezeigt, wie ein URI-Berechtigungs-Intent-Flag hinzugefügt wird, damit eine andere App, die auf Android 11 oder höher ausgerichtet ist, die Daten im Inhalts-URI sehen kann:
Kotlin
val shareIntent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_GRANT_READ_URI_PERMISSION data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP }
Java
Intent shareIntent = new Intent(Intent.ACTION_VIEW); shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);
Verbindung zu Diensten herstellen
Wenn Ihre App mit einem Dienst interagieren muss, der nicht automatisch sichtbar ist, können Sie die entsprechende Intent-Aktion innerhalb eines <queries>
-Elements deklarieren. In den folgenden Abschnitten finden Sie Beispiele für häufig verwendete Dienste.
Mit einer Text-in-Sprache-Engine verbinden
Wenn Ihre App mit einer TTS-Engine (Text-to-Speech) interagiert, fügen Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent>
Verbindung zu einem Spracherkennungsdienst herstellen
Wenn Ihre App mit einem Spracherkennungsdienst interagiert, fügen Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.speech.RecognitionService" /> </intent>
Verbindung zu Medienbrowser-Diensten herstellen
Wenn es sich bei Ihrer App um einen Client-Medienbrowser handelt, fügen Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
Benutzerdefinierte Funktionen bereitstellen
Wenn Ihre App benutzerdefinierte Aktionen ausführen oder benutzerdefinierte Informationen basierend auf Interaktionen mit anderen Apps anzeigen muss, können Sie dieses benutzerdefinierte Verhalten mithilfe von Intent-Filtersignaturen als Teil des <queries>
-Elements in Ihrem Manifest darstellen. In den folgenden Abschnitten finden Sie ausführliche Anleitungen für einige gängige Szenarien.
Abfrage für SMS-Apps
Wenn Ihre App Informationen zu den auf einem Gerät installierten SMS-Apps benötigt, z. B. um zu prüfen, welche App der Standard-SMS-Handler des Geräts ist, fügen Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
Benutzerdefiniertes Freigabe-Sheet erstellen
Verwenden Sie nach Möglichkeit ein vom System bereitgestelltes Freigabe-Sheet. Alternativ können Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest aufnehmen:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SEND" /> <!-- Replace with the MIME type that your app works with, if needed. --> <data android:mimeType="image/jpeg" /> </intent>
Das Erstellen des Freigabebereichs in der Logik Ihrer App, z. B. der Aufruf von queryIntentActivities()
, bleibt im Vergleich zu älteren Android-Versionen (vor Android 11) unverändert.
Benutzerdefinierte Aktionen für die Textauswahl anzeigen
Wenn Nutzer in Ihrer App Text auswählen, wird eine Symbolleiste für die Textauswahl mit den möglichen Vorgängen angezeigt, die für den ausgewählten Text ausgeführt werden können. Wenn in dieser Symbolleiste benutzerdefinierte Aktionen anderer Apps angezeigt werden, fügen Sie das folgende <intent>
-Element als Teil des <queries>
-Elements in Ihr Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.PROCESS_TEXT" /> <data android:mimeType="text/plain" /> </intent>
Benutzerdefinierte Datenzeilen für einen Kontakt anzeigen
Anwendungen können dem Kontaktanbieter benutzerdefinierte Datenzeilen hinzufügen. Damit eine Kontakt-App diese benutzerdefinierten Daten anzeigen kann, muss sie Folgendes tun können:
- Die Datei
contacts.xml
aus den anderen Apps lesen. - Lädt ein Symbol entsprechend dem benutzerdefinierten MIME-Typ.
Wenn deine App eine Kontakt-App ist, füge die folgenden <intent>
-Elemente als Teil des <queries>
-Elements in dein Manifest ein:
<!-- Place inside the <queries> element. --> <!-- Lets the app read the contacts.xml file from other apps. --> <intent> <action android:name="android.accounts.AccountAuthenticator" /> </intent> <!-- Lets the app load an icon corresponding to the custom MIME type. --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="content" android:host="com.android.contacts" android:mimeType="vnd.android.cursor.item/*" /> </intent>