In diesem Dokument werden mehrere gängige Anwendungsfälle beschrieben, in denen eine App mit anderen Apps interagiert. In jedem Abschnitt wird erläutert, wie die Funktionen der App mit eingeschränkter Paketsichtbarkeit erreicht werden können. Das ist wichtig, wenn Ihre 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, besteht der einfachste Ansatz darin, den Intent aufzurufen und die
ActivityNotFoundException
Ausnahme zu verarbeiten, wenn keine App verfügbar ist.
Wenn ein Teil Ihrer App davon abhängt, ob der Aufruf von
startActivity()
erfolgreich sein kann, z. B. um eine Benutzeroberfläche anzuzeigen, fügen Sie dem Element
<queries> des Manifests Ihrer App ein Element hinzu. In der Regel ist das ein <intent> Element.
URLs öffnen
In diesem Abschnitt werden verschiedene Möglichkeiten beschrieben, URLs in einer App zu öffnen, die auf Android 11 oder höher ausgerichtet ist.
URLs in einem Browser oder einer anderen App öffnen
Verwenden Sie einen Intent mit der
ACTION_VIEW Intent-Aktion, um eine URL zu öffnen. Weitere Informationen finden Sie im Leitfaden zum Laden einer Web
URL. Nachdem Sie startActivity() mit diesem Intent aufgerufen haben, geschieht eines der folgenden Dinge:
- Die URL wird in einer Webbrowser-App geöffnet.
- Die URL wird in einer App geöffnet, die die URL als Deep Link unterstützt.
- Ein Dialogfeld zur Auswahl wird angezeigt, in dem der Nutzer auswählen kann, mit welcher App die URL geöffnet werden soll.
Es tritt eine
ActivityNotFoundExceptionauf, weil auf dem Gerät keine App installiert ist, die die URL öffnen kann. (Das ist ungewöhnlich.)Es wird empfohlen, dass Ihre App die
ActivityNotFoundExceptionabfängt und verarbeitet, falls sie 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. Das 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 möchte Ihre App möglicherweise prüfen, ob auf dem Gerät mindestens ein Browser verfügbar ist oder ob ein bestimmter Browser der Standardbrowser ist, bevor sie versucht, 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 Browser-Apps, wenn der Nutzer die URL so konfiguriert hat, dass sie standardmäßig in einer Nicht-Browser-App geöffnet wird.
URLs in benutzerdefinierten Tabs öffnen
Benutzerdefinierte Tabs ermöglichen einer
App, das Aussehen und Verhalten des Browsers anzupassen. Sie können eine URL in
einem benutzerdefinierten Tab
öffnen, ohne das Element <queries> im App-Manifest Ihrer App hinzufügen oder ändern zu müssen.
Möglicherweise möchten Sie jedoch prüfen, ob das Gerät einen Browser hat, 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>
Nicht-Browser-Apps URLs verarbeiten lassen
Auch wenn Ihre App URLs mit benutzerdefinierten Tabs öffnen kann, wird empfohlen, dass Sie nach Möglichkeit eine Nicht-Browser-App eine URL öffnen lassen. Um diese
Funktion in Ihrer App bereitzustellen, versuchen Sie, startActivity() mit einem Intent
aufzurufen, der das
FLAG_ACTIVITY_REQUIRE_NON_BROWSER
Intent-Flag festlegt. Wenn das System eine ActivityNotFoundException auslöst, kann Ihre App die URL in einem benutzerdefinierten Tab öffnen.
Wenn ein Intent dieses Flag enthält, führt ein Aufruf von startActivity() dazu, dass eine ActivityNotFoundException ausgelöst wird, wenn eine der folgenden Bedingungen erfüllt ist:
- Der Aufruf hätte eine Browser-App direkt gestartet.
- Der Aufruf hätte dem Nutzer ein Dialogfeld zur Auswahl angezeigt, in dem nur Browser-Apps als Optionen verfügbar sind.
Das folgende Code-Snippet zeigt, wie Sie Ihre Logik aktualisieren, um das Intent-Flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER zu verwenden:
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 Auswahl vermeiden
Wenn Sie vermeiden möchten, dass das Dialogfeld zur Auswahl angezeigt wird, das Nutzer sehen könnten, wenn
sie eine URL öffnen, und die URL stattdessen in diesen
Situationen selbst verarbeiten möchten, können Sie einen Intent verwenden, der das
FLAG_ACTIVITY_REQUIRE_DEFAULT
Intent-Flag festlegt.
Wenn ein Intent dieses Flag enthält, führt ein Aufruf von startActivity() dazu, dass eine ActivityNotFoundException ausgelöst wird, wenn der Aufruf dem Nutzer ein Dialogfeld zur Auswahl angezeigt hätte.
Wenn ein Intent sowohl dieses Flag als auch das
FLAG_ACTIVITY_REQUIRE_NON_BROWSER
Intent-Flag enthält, führt ein Aufruf von startActivity() dazu, dass eine ActivityNotFoundException
ausgelöst wird, wenn eine der folgenden Bedingungen erfüllt ist:
- Der Aufruf hätte die Browser-App direkt gestartet.
- Der Aufruf hätte dem Nutzer ein Dialogfeld zur Auswahl angezeigt.
Das folgende Code-Snippet zeigt, wie Sie die Flags FLAG_ACTIVITY_REQUIRE_NON_BROWSER und FLAG_ACTIVITY_REQUIRE_DEFAULT zusammen verwenden:
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 App Dateien oder Anhänge verarbeitet, z. B. prüft, ob eine bestimmte Datei auf einem Gerät geöffnet werden kann, ist es in der Regel am einfachsten, zu versuchen, 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 bestimmte 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 <intent> Element im folgenden Code-Snippet als Teil des
<queries> Elements in Ihr Manifest ein. Fügen Sie den Dateityp ein, wenn Sie ihn bereits zur Kompilierzeit kennen.
<!-- 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>
Anschließend können Sie prüfen, ob eine App verfügbar ist, indem Sie resolveActivity() mit Ihrem Intent aufrufen.
URI-Zugriff gewähren
Hinweis: Das Deklarieren von Berechtigungen für den URI-Zugriff, wie in diesem Abschnitt beschrieben, ist für Apps erforderlich, die auf Android 11 (API-Level 30) oder höher ausgerichtet sind, und wird für alle Apps empfohlen, unabhängig von der Ziel-SDK-Version und davon, ob sie ihre Contentanbieter exportieren.
Damit Apps, die auf Android 11 oder höher ausgerichtet sind, auf den Content-URI zugreifen können, müssen im Intent Ihrer App Berechtigungen für den URI-Zugriff deklariert werden. Dazu müssen Sie eines oder beide der folgenden Intent-Flags festlegen:
FLAG_GRANT_READ_URI_PERMISSION
und
FLAG_GRANT_WRITE_URI_PERMISSION.
Unter Android 11 und höher ermöglichen die Berechtigungen für den URI-Zugriff der App, die den Intent empfängt, Folgendes:
- Je nach den angegebenen URI-Berechtigungen Daten lesen oder in die Daten schreiben, die der Inhalts-URI darstellt.
- Sichtbarkeit in die App erhalten, die den Contentanbieter enthält, der mit der URI-Autorität übereinstimmt. Die App, die den Contentanbieter enthält, kann sich von der App unterscheiden, die den Intent sendet.
Das folgende Code-Snippet zeigt, wie Sie ein Intent-Flag für URI-Berechtigungen hinzufügen, damit eine andere App, die auf Android 11 oder höher ausgerichtet ist, die Daten im Inhalts-URI ansehen 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 sichtbar
automatisch ist, können Sie die
entsprechende Intent-Aktion in einem <queries> Element deklarieren. In den folgenden Abschnitten finden Sie Beispiele für häufig verwendete Dienste.
Verbindung zu einer Text-to-Speech-Engine herstellen
Wenn Ihre App mit einer Text-to-Speech-Engine (TTS) 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 Spracherkennungsservice herstellen
Wenn Ihre App mit einem Spracherkennungsservice 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 Media-Browser-Diensten herstellen
Wenn Ihre App eine Media-Browser-Client
App ist, fügen Sie
das folgende Element <intent> als Teil des Elements <queries> in Ihr
Manifest ein:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
Benutzerdefinierte Funktionen bereitstellen
Wenn Ihre App anpassbare Aktionen ausführen oder anpassbare
Informationen basierend auf ihren Interaktionen mit anderen Apps anzeigen muss, können Sie dieses
benutzerdefinierte Verhalten mithilfe von Intent-Filter
Signaturen als
Teil des <queries> Elements in Ihrem Manifest darstellen. In den folgenden Abschnitten finden Sie detaillierte Anleitungen für mehrere gängige Szenarien.
SMS-Apps abfragen
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 Freigabeblatt erstellen
Verwenden Sie nach Möglichkeit ein vom System bereitgestelltes
Freigabeblatt. Alternativ können Sie das folgende <intent> Element als Teil des <queries> Elements in
Ihr Manifest einfügen:
<!-- 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>
Der Prozess zum Erstellen des Freigabeblatts in der Logik Ihrer App, z. B. der Aufruf von queryIntentActivities(), bleibt im Vergleich zu Android-Versionen vor Android 11 ansonsten unverändert.
Benutzerdefinierte Aktionen zur Textauswahl anzeigen
Wenn Nutzer Text in Ihrer App auswählen, werden in einer Symbolleiste zur Textauswahl
die möglichen Aktionen angezeigt, die für den ausgewählten Text ausgeführt werden können. Wenn in dieser
Symbolleiste benutzerdefinierte Aktionen aus anderen 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
Apps können dem Kontakteanbieter benutzerdefinierte Datenzeilen hinzufügen. Damit eine Kontakte-App diese benutzerdefinierten Daten anzeigen kann, muss sie Folgendes tun können:
- Die Datei
contacts.xmlaus den anderen Apps lesen. - Ein Symbol laden, das dem benutzerdefinierten MIME-Typ entspricht.
Wenn Ihre App eine Kontakte-App ist, fügen Sie die folgenden <intent> Elemente als Teil
des <queries> Elements in Ihr 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>