Anwendungsgrundlagen

Android-Apps können mit Kotlin, der Programmiersprache Java, und C++-Sprachen geschrieben werden. Die Android SDK-Tools kompilieren deinen Code sowie alle Daten- und Ressourcendateien in einem APK oder Android App Bundle.

Ein Android-Paket, bei dem es sich um eine Archivdatei mit dem Suffix .apk handelt, enthält die Inhalte einer Android-App, die zur Laufzeit benötigt wird. Es ist die Datei, mit der Android-Geräte die App installieren.

Ein Android App Bundle, eine Archivdatei mit dem Suffix .aab, enthält die Inhalte eines Android-App-Projekts, einschließlich einiger zusätzlicher Metadaten, die zur Laufzeit nicht erforderlich sind. Ein AAB ist ein Veröffentlichungsformat und kann nicht auf Android-Geräten installiert werden. Die APK-Generierung und -Signierung werden auf eine spätere Phase verschoben.

Wenn Sie Ihre App beispielsweise über Google Play vertreiben, generieren die Server von Google Play optimierte APKs, die nur die Ressourcen und den Code enthalten, die für das Gerät, das die Installation der App anfordert, erforderlich sind.

Jede Android-App befindet sich in ihrer eigenen Sicherheits-Sandbox, die durch die folgenden Android-Sicherheitsfunktionen geschützt wird:

  • Das Betriebssystem Android ist ein Linux-System mit mehreren Nutzern, bei dem jede App ein anderer Nutzer ist.
  • Standardmäßig weist das System jeder App eine eindeutige Linux-Nutzer-ID zu, die nur vom System verwendet wird und der App nicht bekannt ist. Das System legt Berechtigungen für alle Dateien in einer App so fest, dass nur die Nutzer-ID, die der App zugewiesen ist, auf sie zugreifen kann.
  • Jeder Prozess hat eine eigene virtuelle Maschine (VM), sodass der Code einer Anwendung von anderen Anwendungen isoliert ausgeführt wird.
  • Standardmäßig wird jede Anwendung in einem eigenen Linux-Prozess ausgeführt. Das Android-System startet den Prozess, wenn eine der App-Komponenten ausgeführt werden muss, und fährt den Prozess herunter, wenn er nicht mehr benötigt wird oder wenn das System Arbeitsspeicher für andere Apps wiederherstellen muss.

Das Android-System implementiert das Prinzip der geringsten Berechtigung. Das heißt, jede Anwendung hat standardmäßig nur Zugriff auf die Komponenten, die für ihre Arbeit erforderlich sind, und nicht mehr. Dadurch entsteht eine sehr sichere Umgebung, in der eine App nicht auf Teile des Systems zugreifen kann, für die sie keine Berechtigung erteilt hat.

Es gibt jedoch Möglichkeiten, wie eine Anwendung Daten für andere Anwendungen freigeben und auf Systemdienste zugreifen kann:

  • Es ist möglich, zwei Apps dieselbe Linux-Nutzer-ID zu verwenden. Dadurch können sie auf die Dateien der anderen zugreifen. Um Systemressourcen zu sparen, können Anwendungen mit derselben Nutzer-ID auch so eingerichtet werden, dass sie im selben Linux-Prozess ausgeführt werden und dieselbe VM verwenden. Die Anwendungen müssen außerdem mit demselben Zertifikat signiert sein.
  • Eine App kann die Berechtigung für den Zugriff auf Gerätedaten anfordern, z. B. den Standort, die Kamera und die Bluetooth-Verbindung des Geräts. Der Nutzer muss diese Berechtigungen explizit gewähren. Weitere Informationen zu Berechtigungen findest du unter Berechtigungen unter Android.

Im weiteren Verlauf dieses Dokuments werden die folgenden Konzepte vorgestellt:

  • Die grundlegenden Framework-Komponenten, die deine App definieren.
  • Die Manifestdatei, in der Sie die Komponenten und die erforderlichen Gerätefunktionen für Ihre App deklarieren.
  • Ressourcen, die vom App-Code getrennt sind und mit denen Ihre App ihr Verhalten für verschiedene Gerätekonfigurationen reibungslos optimieren kann.

App-Komponenten

App-Komponenten sind die wesentlichen Bausteine einer Android-App. Jede Komponente ist ein Einstiegspunkt, über den das System oder Nutzer auf Ihre App zugreifen können. Einige Komponenten sind von anderen abhängig.

Es gibt vier Arten von Anwendungskomponenten:

  • Aktivitäten
  • Dienste
  • Broadcast-Receiver
  • Contentanbieter

Jeder Typ erfüllt einen bestimmten Zweck und hat einen eigenen Lebenszyklus, der definiert, wie eine Komponente erstellt und gelöscht wird. In den folgenden Abschnitten werden die vier Typen von Anwendungskomponenten beschrieben.

Aktivitäten
Eine Aktivität ist der Einstiegspunkt für die Interaktion mit dem Nutzer. Es stellt einen einzelnen Bildschirm mit einer Benutzeroberfläche dar. Beispielsweise kann eine E-Mail-Anwendung eine Aktivität haben, die eine Liste neuer E-Mails anzeigt, eine weitere Aktivität zum Schreiben einer E-Mail und eine weitere Aktivität zum Lesen von E-Mails. Obwohl die Aktivitäten gemeinsam eine zusammenhängende User Experience in der E-Mail-App bilden, sind alle voneinander unabhängig.

Eine andere App kann jede dieser Aktivitäten starten, wenn die E-Mail-App dies zulässt. Eine Kamera-App kann beispielsweise die Aktivität in der E-Mail-App zum Schreiben einer neuen E-Mail starten, damit der Nutzer ein Bild teilen kann.

Eine Aktivität ermöglicht die folgenden wichtigen Interaktionen zwischen System und App:

  • Verfolgung dessen, was für den Nutzer aktuell wichtig ist (was auf dem Bildschirm angezeigt wird), damit das System den Prozess, in dem die Aktivität gehostet wird, weiter ausführt.
  • Wenn der Nutzer weiß, welche zuvor verwendeten Prozesse angehaltene Aktivitäten enthalten, kann dieser Prozess priorisiert werden, damit sie verfügbar bleiben.
  • Beenden der App durch die App, damit der Nutzer zu Aktivitäten zurückkehren kann, bei denen der vorherige Status wiederhergestellt wurde
  • Apps eine Möglichkeit bieten, Nutzerflüsse untereinander zu implementieren und dem System zu koordinieren, diese Abläufe zu koordinieren. Das wichtigste Beispiel dafür ist das Teilen.

Sie implementieren eine Aktivität als Unterklasse der Activity-Klasse. Weitere Informationen zur Klasse Activity finden Sie unter Einführung in Aktivitäten.

Dienste
Ein Dienst ist ein allgemeiner Einstiegspunkt für die Ausführung einer Anwendung im Hintergrund aus den verschiedensten Gründen. Diese Komponente wird im Hintergrund ausgeführt, um lang andauernde Vorgänge oder Remoteprozesse auszuführen. Ein Dienst hat keine Benutzeroberfläche.

Ein Dienst kann beispielsweise Musik im Hintergrund abspielen, während sich der Nutzer in einer anderen App befindet, oder Daten über das Netzwerk abrufen, ohne die Nutzerinteraktion mit einer Aktivität zu blockieren. Eine andere Komponente, z. B. eine Aktivität, kann den Dienst starten und ausführen oder eine Bindung an ihn stellen, um mit ihm zu interagieren.

Es gibt zwei Arten von Diensten, die dem System mitteilen, wie eine Anwendung verwaltet werden soll: gestartete Dienste und gebundene Dienste.

Gestartete Dienste teilen dem System mit, dass sie weiter ausgeführt werden sollen, bis die Arbeit abgeschlossen ist. Dies kann dazu führen, dass einige Daten im Hintergrund synchronisiert oder Musik auch abgespielt werden, nachdem der Nutzer die App verlassen hat. Das Synchronisieren von Daten im Hintergrund oder das Abspielen von Musik stellt verschiedene Arten von gestarteten Diensten dar, die vom System anders verarbeitet werden:

  • Die Musikwiedergabe ist etwas, das der Nutzer direkt erkennt. Die App teilt dies dem System mit, indem sie darauf hinweist, dass sie im Vordergrund ausgeführt werden soll, und der Nutzer wird darüber informiert, dass die Musik abgespielt wird. In diesem Fall hat das System Priorität, den Prozess dieses Dienstes am Laufen zu halten, da es für den Nutzer ärgerlich ist, wenn er verschwindet.
  • Ein regulärer Hintergrunddienst ist dem Nutzer nicht direkt bekannt, sodass das System bei der Prozessverwaltung mehr Freiheiten hat. Er kann beendet werden und den Dienst zu einem späteren Zeitpunkt neu starten, wenn er RAM für Dinge benötigt, die für den Nutzer wichtiger sind.

Gebundene Dienste werden ausgeführt, weil eine andere Anwendung (oder das System) angegeben hat, dass sie den Dienst verwenden möchte. Ein gebundener Dienst stellt einem anderen Prozess eine API zur Verfügung. Das System weiß, dass zwischen diesen Prozessen eine Abhängigkeit besteht. Wenn also Prozess A an einen Dienst in Prozess B gebunden ist, weiß das System, dass es Prozess B beibehalten muss und sein Dienst für A ausgeführt werden muss. Wenn dem Nutzer Prozess A wichtig ist, weiß er darüber hinaus, dass er Prozess B als etwas behandeln soll, was dem Nutzer ebenfalls wichtig ist.

Aufgrund ihrer Flexibilität sind Dienste nützliche Bausteine für alle Arten von übergeordneten Systemkonzepten. Live-Hintergründe, Benachrichtigungs-Listener, Bildschirmschoner, Eingabemethoden, Bedienungshilfen und viele andere wichtige Systemfunktionen werden als Dienste erstellt, die von Anwendungen implementiert und an das System gebunden werden, wenn sie ausgeführt werden.

Ein Dienst wird als abgeleitete Klasse von Service implementiert. Weitere Informationen zur Klasse Service finden Sie in der Übersicht über Dienste.

Hinweis: Wenn deine App auf Android 5.0 (API-Level 21) oder höher ausgerichtet ist, verwende die Klasse JobScheduler, um Aktionen zu planen. Der Vorteil von JobScheduler besteht darin, den Akku zu schonen, indem Jobs optimal geplant werden, um den Stromverbrauch zu reduzieren, und die Doze API verwendet wird. Weitere Informationen zur Verwendung dieser Klasse finden Sie in der Referenzdokumentation zu JobScheduler.

Broadcast-Receiver
Ein Broadcast-Empfänger ist eine Komponente, mit der das System Ereignisse an die App außerhalb eines regulären Nutzerflusses senden kann, damit die App auf systemweite Broadcast-Ankündigungen reagieren kann. Da Broadcast-Empfänger ein weiterer klar definierter Eintrag in der Anwendung sind, kann das System Broadcasts auch an Apps senden, die derzeit nicht ausgeführt werden.

Beispielsweise kann eine App einen Alarm so planen, dass eine Benachrichtigung an den Nutzer über ein bevorstehendes Ereignis gesendet wird. Da der Alarm an ein BroadcastReceiver in der App gesendet wird, muss die App nicht weiter ausgeführt werden, bis der Alarm ausgelöst wird.

Viele Broadcasts stammen aus dem System, z. B. eine Nachricht, dass der Bildschirm ausgeschaltet ist, der Akkustand niedrig ist oder ein Bild aufgenommen wird. Apps können auch Broadcasts initiieren, um anderen Apps mitzuteilen, dass einige Daten auf das Gerät heruntergeladen wurden und für sie verfügbar sind.

Obwohl Sendeempfänger keine Benutzeroberfläche anzeigen, können sie eine Benachrichtigung in der Statusleiste erstellen, um den Nutzer über ein Broadcast-Ereignis zu informieren. Häufiger ist ein Broadcast-Empfänger jedoch nur ein Gateway zu anderen Komponenten und soll nur sehr wenig Arbeit ausführen.

Ein Sender kann beispielsweise mit JobScheduler einen JobService planen, um bei einem Ereignis bestimmte Aufgaben auszuführen. Bei Broadcast-Empfängern sind häufig Anwendungen beteiligt, die miteinander interagieren. Daher ist es wichtig, sich bei der Einrichtung der Auswirkungen auf die Sicherheit bewusst zu sein.

Ein Broadcast-Empfänger wird als abgeleitete Klasse von BroadcastReceiver implementiert und jeder Broadcast wird als ein Intent-Objekt gesendet. Weitere Informationen finden Sie in der Klasse BroadcastReceiver.

Contentanbieter
Ein Contentanbieter verwaltet einen freigegebenen Satz von App-Daten, die Sie im Dateisystem, in einer SQLite-Datenbank, im Web oder an einem anderen nichtflüchtigen Speicherort speichern können, auf den Ihre Anwendung zugreifen kann. Über den Contentanbieter können andere Apps die Daten abfragen oder ändern, wenn der Contentanbieter dies zulässt.

Das Android-System stellt beispielsweise einen Contentanbieter bereit, der die Kontaktdaten des Nutzers verwaltet. Jede Anwendung mit den entsprechenden Berechtigungen kann den Inhaltsanbieter – z. B. mit ContactsContract.Data – abfragen, um Informationen zu einer bestimmten Person zu lesen und zu schreiben.

Es ist verlockend, sich einen Contentanbieter als Abstraktion einer Datenbank zu vorstellen, da für diesen häufigen Fall viel API und Support integriert sind. Beim Systemdesign haben sie jedoch einen anderen Hauptzweck.

Für das System ist ein Inhaltsanbieter ein Einstiegspunkt in eine App zum Veröffentlichen benannter Datenelemente, die durch ein URI-Schema identifiziert werden. Auf diese Weise kann eine Anwendung entscheiden, wie die darin enthaltenen Daten einem URI-Namespace zugeordnet werden sollen. Diese URIs werden dann an andere Entitäten ausgegeben, die diese wiederum für den Zugriff auf die Daten verwenden können. Es gibt einige bestimmte Aktionen, mit denen das System eine App verwalten kann:

  • Wenn Sie einen URI zuweisen, muss die Anwendung nicht weiter ausgeführt werden. Daher können URIs bestehen, nachdem die zugehörigen Apps beendet wurden. Das System muss nur dann prüfen, ob eine zugehörige Anwendung noch ausgeführt wird, wenn es die Daten der Anwendung aus dem entsprechenden URI abruft.
  • Diese URIs bieten auch ein wichtiges, detailliertes Sicherheitsmodell. Eine App kann beispielsweise den URI für ein Bild in der Zwischenablage speichern, ihren Inhaltsanbieter aber gesperrt lassen, damit andere Apps nicht ungehindert darauf zugreifen können. Wenn eine zweite App versucht, auf diesen URI in der Zwischenablage zuzugreifen, kann das System dieser App über eine temporäre URI-Berechtigungserteilung Zugriff auf die Daten gewähren. So greift sie nur auf die Daten hinter diesem URI und auf nichts anderes aus der zweiten App zu.

Contentanbieter sind auch zum Lesen und Schreiben von Daten nützlich, die nur für Ihre App sichtbar sind und nicht weitergegeben werden.

Ein Contentanbieter wird als abgeleitete Klasse von ContentProvider implementiert und muss einen Standardsatz von APIs implementieren, mit denen andere Anwendungen Transaktionen ausführen können. Weitere Informationen finden Sie im Entwicklerleitfaden für Contentanbieter.

Ein besonderer Aspekt des Android-Systemdesigns besteht darin, dass jede App die Komponente einer anderen App starten kann. Wenn der Nutzer beispielsweise ein Foto mit der Gerätekamera aufnehmen soll, gibt es wahrscheinlich eine andere App, die dies tut. Ihre App kann sie verwenden, anstatt eine Aktivität zu entwickeln, um ein Foto selbst aufzunehmen. Du musst den Code aus der Kamera-App nicht einbinden oder sogar damit verknüpfen. Stattdessen kannst du die Aktivität in der Kamera-App starten, die ein Foto aufnimmt. Wenn das Foto fertig ist, wird es an Ihre App zurückgegeben, damit Sie es verwenden können. Für Nutzende scheint die Kamera tatsächlich Teil Ihrer App zu sein.

Wenn das System eine Komponente startet, startet es den Prozess für diese Anwendung, falls sie noch nicht ausgeführt wird, und instanziiert die für die Komponente erforderlichen Klassen. Wenn Ihre App beispielsweise die Aktivität in der Kamera-App startet, durch die ein Foto aufgenommen wird, wird diese Aktivität in dem Prozess ausgeführt, der zur Kamera-App gehört, und nicht in dem Prozess Ihrer App. Daher haben Android-Apps im Gegensatz zu Apps auf den meisten anderen Systemen keinen einzelnen Einstiegspunkt: Es gibt keine main()-Funktion.

Da das System jede App in einem separaten Prozess mit Dateiberechtigungen ausführt, die den Zugriff auf andere Apps einschränken, kann Ihre App eine Komponente nicht direkt aus einer anderen App aktivieren. Das Android-System kann das jedoch tun. Zum Aktivieren einer Komponente in einer anderen App senden Sie eine Nachricht an das System, die Ihre Absicht angibt, eine bestimmte Komponente zu starten. Das System aktiviert dann die Komponente für Sie.

Komponenten aktivieren

Eine asynchrone Nachricht, die als Intent bezeichnet wird, aktiviert drei der vier Komponententypen: Aktivitäten, Dienste und Broadcast-Empfänger. Intents binden einzelne Komponenten zur Laufzeit aneinander. Sie können sie sich als Boten vorstellen, die eine Aktion von anderen Komponenten anfordern, unabhängig davon, ob die Komponente zu Ihrer App oder einer anderen gehört.

Ein Intent wird mit einem Intent-Objekt erstellt, das eine Nachricht definiert, um entweder eine bestimmte Komponente (ein expliziter Intent) oder einen bestimmten Komponententyp (ein impliziter Intent) zu aktivieren.

Bei Aktivitäten und Diensten definiert ein Intent die auszuführende Aktion, z. B. das Ansehen oder Senden, und kann unter anderem den URI der Daten angeben, für die Aktionen ausgeführt werden sollen.

Ein Intent kann beispielsweise eine Anfrage für eine Aktivität übertragen, um ein Bild anzuzeigen oder eine Webseite zu öffnen. In einigen Fällen können Sie eine Aktivität starten, um ein Ergebnis zu erhalten. In diesem Fall gibt die Aktivität das Ergebnis auch in einem Intent zurück. Sie können auch ein Intent-Element ausgeben, damit der Nutzer einen persönlichen Kontakt auswählen und an Sie zurücksenden kann. Der Rückgabe-Intent enthält einen URI, der auf den ausgewählten Kontakt verweist.

Bei Empfängern von Rundfunknachrichten definiert der Intent die Broadcast-Ansage. Beispielsweise enthält ein Broadcast, der angibt, dass der Akku des Geräts schwach ist, nur einen bekannten Aktionsstring, der auf einen niedrigen Akkustand hinweist.

Im Gegensatz zu Aktivitäten, Diensten und Broadcast-Empfängern werden Inhaltsanbieter aktiviert, wenn sie durch eine Anfrage von einem ContentResolver angezielt werden. Der Inhaltsauflöser verarbeitet alle direkten Transaktionen mit dem Contentanbieter und die Komponente, die Transaktionen mit dem Anbieter ausführt, ruft Methoden für das ContentResolver-Objekt auf. So bleibt aus Sicherheitsgründen eine Abstraktionsebene zwischen dem Contentanbieter und der Komponente, die Informationen anfordert, übrig.

Es gibt verschiedene Methoden zum Aktivieren der einzelnen Komponententypen:

  • Sie können eine Aktivität starten oder ihr eine neue Aufgabe zuweisen. Dazu übergeben Sie ein Intent an startActivity(). Wenn die Aktivität ein Ergebnis zurückgeben soll, startActivityForResult().
  • Unter Android 5.0 (API-Level 21) und höher kannst du mit der Klasse JobScheduler Aktionen planen. Bei älteren Android-Versionen können Sie einen Dienst starten oder einem laufenden Dienst neue Anweisungen geben, indem Sie eine Intent an startService() übergeben. Sie können eine Bindung an den Dienst herstellen, indem Sie einen Intent an bindService() übergeben.
  • Sie können einen Broadcast starten, indem Sie eine Intent an Methoden wie sendBroadcast() oder sendOrderedBroadcast() übergeben.
  • Sie können eine Abfrage an einen Contentanbieter durchführen, indem Sie query() für ein ContentResolver aufrufen.

Weitere Informationen zur Verwendung von Intents finden Sie im Dokument zu Intents und Intent-Filtern. Die folgenden Dokumente enthalten weitere Informationen zum Aktivieren bestimmter Komponenten: Einführung in Aktivitäten, Dienstübersicht, BroadcastReceiver und Contentanbieter.

Manifestdatei

Bevor das Android-System eine App-Komponente starten kann, muss das System in der Manifestdatei AndroidManifest.xml der App erkennen, dass die Komponente existiert. Ihre Anwendung deklariert alle zugehörigen Komponenten in dieser Datei, die sich im Stammverzeichnis des Anwendungsprojektverzeichnisses befindet.

Im Manifest werden neben der Deklaration der App-Komponenten noch weitere Aktionen ausgeführt. Dazu gehören:

  • Identifiziert alle Nutzerberechtigungen, die für die App erforderlich sind, z. B. Internetzugriff oder Lesezugriff auf die Kontakte des Nutzers.
  • Deklariert die für die Anwendung erforderliche Mindest-API-Ebene, je nachdem, welche APIs die Anwendung verwendet.
  • Deklariert Hardware- und Softwarefunktionen, die von der App verwendet oder benötigt werden, z. B. eine Kamera, Bluetooth-Dienste oder ein Multi-Touch-Bildschirm.
  • Deklariert, mit welchen API-Bibliotheken die App verknüpft werden muss (mit Ausnahme der Android-Framework-APIs), z. B. die Google Maps-Bibliothek.

Komponenten deklarieren

Die Hauptaufgabe des Manifests besteht darin, das System über die Komponenten der App zu informieren. In einer Manifestdatei kann eine Aktivität beispielsweise so deklariert werden:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>

Im <application>-Element verweist das Attribut android:icon auf Ressourcen für ein Symbol, das die App identifiziert.

Im <activity>-Element gibt das Attribut android:name den voll qualifizierten Klassennamen der abgeleiteten Klasse Activity an und das Attribut android:label gibt einen String an, der als für den Nutzer sichtbares Label für die Aktivität verwendet werden soll.

Sie müssen alle App-Komponenten mithilfe der folgenden Elemente deklarieren:

Aktivitäten, Dienste und Contentanbieter, die Sie in Ihre Quelle aufnehmen, aber nicht im Manifest deklarieren, sind für das System nicht sichtbar und können daher nicht ausgeführt werden. Broadcast-Empfänger können jedoch entweder im Manifest deklariert oder dynamisch als BroadcastReceiver-Objekte im Code erstellt und durch Aufrufen von registerReceiver() im System registriert werden.

Weitere Informationen zum Strukturieren der Manifestdatei für Ihre App finden Sie in der Übersicht über das App-Manifest.

Komponentenfunktionen deklarieren

Wie im Abschnitt Komponenten aktivieren beschrieben, können Sie eine Intent verwenden, um Aktivitäten, Dienste und Broadcast-Empfänger zu starten. Dazu benennen Sie die Zielkomponente explizit mithilfe des Komponentenklassennamens im Intent. Sie können auch einen impliziten Intent verwenden, der den Typ der auszuführenden Aktion und optional die Daten beschreibt, für die Sie die Aktion ausführen möchten. Mit einem impliziten Intent kann das System auf dem Gerät eine Komponente finden, die die Aktion ausführen und starten kann. Wenn es mehrere Komponenten gibt, mit denen die durch den Intent beschriebene Aktion ausgeführt werden kann, wählt der Nutzer eine aus.

Achtung:Wenn Sie Service mit einem Intent starten, achten Sie darauf, dass Ihre Anwendung sicher ist, indem Sie einen expliziten Intent verwenden. Die Verwendung eines impliziten Intents zum Starten eines Dienstes stellt ein Sicherheitsrisiko dar, da Sie nicht sicher sein können, welcher Dienst auf den Intent reagiert, und der Nutzer nicht sehen kann, welcher Dienst gestartet wird. Ab Android 5.0 (API-Ebene 21) löst das System eine Ausnahme aus, wenn Sie bindService() mit einem impliziten Intent aufrufen. Deklarieren Sie keine Intent-Filter für Ihre Dienste.

Das System identifiziert die Komponenten, die auf einen Intent reagieren können. Dazu wird der empfangene Intent mit den Intent-Filtern verglichen, die in der Manifestdatei anderer Apps auf dem Gerät bereitgestellt werden.

Wenn Sie eine Aktivität im Manifest Ihrer App deklarieren, können Sie optional Intent-Filter einfügen, die die Funktionen der Aktivität deklarieren, damit sie auf Intents anderer Apps reagieren kann. Dazu fügen Sie ein <intent-filter>-Element als untergeordnetes Element des Deklarationselements der Komponente hinzu.

Wenn Sie beispielsweise eine E-Mail-Anwendung mit einer Aktivität zum Schreiben einer neuen E-Mail erstellen, können Sie einen Intent-Filter deklarieren, um auf „Senden“-Intents zu reagieren und eine neue E-Mail zu senden, wie im folgenden Beispiel gezeigt:

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Wenn eine andere Anwendung einen Intent mit der Aktion ACTION_SEND erstellt und an startActivity() übergibt, startet das System möglicherweise Ihre Aktivität, damit der Nutzer eine E-Mail verfassen und senden kann.

Weitere Informationen zum Erstellen von Intent-Filtern finden Sie im Dokument Intents und Intent-Filter.

App-Anforderungen deklarieren

Es gibt eine Vielzahl von Geräten mit Android, und nicht alle bieten dieselben Funktionen. Um zu verhindern, dass deine App auf Geräten installiert wird, auf denen Funktionen fehlen, die für deine App benötigt werden, ist es wichtig, dass du ein klares Profil für die von deiner App unterstützten Gerätetypen definierst. Deklariere dazu in der Manifestdatei Geräte- und Softwareanforderungen.

Die meisten dieser Erklärungen dienen nur zu Informationszwecken. Sie werden vom System nicht gelesen, aber externe Dienste wie Google Play lesen sie, damit Nutzer sie filtern können, wenn sie auf ihrem Gerät nach Apps suchen.

Angenommen, Ihre App erfordert eine Kamera und verwendet APIs, die in Android 8.0 (API-Ebene 26) eingeführt wurden. Sie müssen diese Anforderungen deklarieren. Die Werte für minSdkVersion und targetSdkVersion werden in der Datei build.gradle Ihres App-Moduls festgelegt:

android {
  ...
  defaultConfig {
    ...
    minSdkVersion 26
    targetSdkVersion 29
  }
}

Hinweis:Lege minSdkVersion und targetSdkVersion nicht direkt in der Manifestdatei fest, da sie während des Build-Prozesses von Gradle überschrieben werden. Weitere Informationen finden Sie unter Anforderungen an das API-Level angeben.

Sie deklarieren die Kamerafunktion in der Manifestdatei Ihrer App:

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    ...
</manifest>

Mit den Deklarationen in diesen Beispielen kann deine App auf Geräten ohne Kamera oder Android-Version unter 8.0 nicht über Google Play installiert werden. Sie können jedoch auch erklären, dass Ihre App die Kamera verwendet, sie aber nicht erforderlich ist. Dazu setzen Sie das Attribut required auf false, prüfen zur Laufzeit, ob das Gerät eine Kamera hat, und deaktivieren bei Bedarf alle Kamerafunktionen.

Weitere Informationen dazu, wie Sie die Kompatibilität Ihrer App mit verschiedenen Geräten verwalten können, finden Sie in der Übersicht über die Gerätekompatibilität.

App-Ressourcen

Eine Android-App besteht nicht nur aus Code. Dazu sind Ressourcen erforderlich, die vom Quellcode getrennt sind, z. B. Bilder, Audiodateien und alles, was mit der visuellen Darstellung der App zu tun hat. Mit XML-Dateien lassen sich beispielsweise Animationen, Menüs, Stile, Farben und das Layout der Benutzeroberflächen für Aktivitäten definieren.

Mithilfe von App-Ressourcen können Sie auf einfache Weise verschiedene Eigenschaften Ihrer App aktualisieren, ohne den Code zu ändern. Durch die Bereitstellung von Gruppen alternativer Ressourcen kannst du deine App für eine Vielzahl von Gerätekonfigurationen optimieren, z. B. für verschiedene Sprachen und Bildschirmgrößen.

Für jede Ressource, die Sie in Ihr Android-Projekt aufnehmen, definieren die SDK-Build-Tools eine eindeutige Ganzzahl-ID, mit der Sie aus Ihrem App-Code oder anderen in XML definierten Ressourcen auf die Ressource verweisen können. Wenn Ihre App beispielsweise eine Bilddatei namens logo.png enthält, die im Verzeichnis res/drawable/ gespeichert ist, generieren die SDK-Tools eine Ressourcen-ID mit dem Namen R.drawable.logo. Diese ID ist einer anwendungsspezifischen Ganzzahl zugeordnet, mit der Sie auf das Bild verweisen und es in Ihre Benutzeroberfläche einfügen können.

Einer der wichtigsten Aspekte beim Bereitstellen von Ressourcen unabhängig vom Quellcode ist die Möglichkeit, alternative Ressourcen für verschiedene Gerätekonfigurationen bereitzustellen.

Wenn Sie beispielsweise UI-Strings in XML definieren, können Sie diese Strings in andere Sprachen übersetzen und in separaten Dateien speichern. Anschließend wendet Android die entsprechenden Sprachstrings auf der Benutzeroberfläche an. Dies basiert auf einem Sprachqualifizierer, den Sie an den Namen des Ressourcenverzeichnisses (z. B. res/values-fr/ für französische Stringwerte) und der Spracheinstellung des Nutzers anhängen.

Android unterstützt viele Kennzeichner für deine alternativen Ressourcen. Der Qualifizierer ist ein kurzer String, den Sie in den Namen Ihrer Ressourcenverzeichnisse aufnehmen, um die Gerätekonfiguration zu definieren, für die diese Ressourcen verwendet werden.

Beispielsweise können Sie je nach Bildschirmausrichtung und Größe des Geräts unterschiedliche Layouts für Ihre Aktivitäten erstellen. Wenn sich der Gerätebildschirm im Hochformat (hoch) befindet, empfiehlt sich ein Layout mit vertikal angeordneten Schaltflächen. Im Querformat (breit) sollten die Schaltflächen jedoch horizontal ausgerichtet sein. Wenn Sie das Layout je nach Ausrichtung ändern möchten, können Sie zwei Layouts definieren und den entsprechenden Qualifier auf den Verzeichnisnamen jedes Layouts anwenden. Dann wendet das System automatisch das entsprechende Layout an, je nach der aktuellen Geräteausrichtung.

Weitere Informationen zu den verschiedenen Arten von Ressourcen, die Sie in Ihre Anwendung aufnehmen können, und zum Erstellen alternativer Ressourcen für verschiedene Gerätekonfigurationen finden Sie in der Übersicht über Anwendungsressourcen. Weitere Informationen zu Best Practices und zum Entwerfen robuster Apps in Produktionsqualität finden Sie im Leitfaden zur App-Architektur.

Weitere Informationen

Informationen zur Android-Entwicklung mithilfe von Videos und Code-Tutorials finden Sie im Udacity-Kurs Android-Apps mit Kotlin entwickeln.

Weiterlesen über:

Intents und Intent-Filter
Hier erfahren Sie, wie Sie mit den Intent APIs App-Komponenten wie Aktivitäten und Dienste aktivieren und Ihre App-Komponenten für die Nutzung durch andere Apps verfügbar machen.
Einführung in Aktivitäten
Hier erfahren Sie, wie Sie eine Instanz der Activity-Klasse erstellen, die in Ihrer Anwendung einen abgegrenzten Bildschirm mit einer Benutzeroberfläche zur Verfügung stellt.
App-Ressourcen – Übersicht
Hier erfährst du, wie Android-Apps so strukturiert sind, dass App-Ressourcen vom App-Code getrennt werden, und wie du alternative Ressourcen für bestimmte Gerätekonfigurationen bereitstellen kannst.

Ebenfalls interessant:

Gerätekompatibilität – Übersicht
Hier erfährst du, wie Android auf verschiedenen Gerätetypen funktioniert und wie du deine App für jedes Gerät optimieren oder die Verfügbarkeit für verschiedene Geräte einschränken kannst.
Berechtigungen unter Android
Hier erfährst du, wie Android den App-Zugriff auf bestimmte APIs mit einem Berechtigungssystem einschränkt, das die Einwilligung des Nutzers erfordert, damit deine App diese APIs verwenden kann.