Was „android:exported needs to be explicitly specified“ bedeutet

„Manifest merger failed: Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined.“ bedeutet, dass das endgültige Manifest eine Aktivität, einen Dienst oder einen Broadcast-Empfänger mit Intent-Filter, aber ohne explizite Zugriffseinstellung enthält. Dies gilt, wenn die App auf Android 12/API 31 oder höher ausgerichtet ist.

Die entsprechenden Meldungen für <activity>, <service> oder <receiver> bezeichnen dasselbe Problem. android:exported steuert, ob andere Apps diese Komponente starten können. Setzen Sie den Wert nicht einfach auf true, nur damit der Build durchläuft. Ermitteln Sie zuerst die genaue Komponente und das Quellmanifest in der zusammengeführten Ausgabe. Siehe die offizielle Anforderung für exportierte Komponenten unter Android 12.

Dieser Leitfaden beschränkt sich auf Aktivitäten, Dienste und Empfänger mit Intent-Filtern. Content-Provider sind keine übliche entsprechende Variante dieses Android-12-Fehlers.

Fehlerhafte Komponente und zuständiges Manifest ermitteln

Verwenden Sie die Ausgabe der Manifestzusammenführung, bevor Sie das App-Manifest ändern. Der betroffene Eintrag kann aus dem App-Modul, einer Build-Variante, einem Testmodul, einem generierten Manifest oder einer Drittanbieterabhängigkeit stammen.

  1. Öffnen Sie die AndroidManifest.xml des betroffenen Moduls in Android Studio.
  2. Wählen Sie Merged Manifest.
  3. Wählen Sie die betroffene Aktivität, den Dienst oder den Empfänger aus.
  4. Verwenden Sie Merging Log und Manifest Sources, um das beitragende Manifest zu identifizieren.
  5. Prüfen Sie bei Bedarf den Build-Bericht der Manifestzusammenführung.
  6. Korrigieren Sie das zuständige Manifest oder verwenden Sie nur dann eine eng begrenzte Merge-Regel mit höherer Priorität, wenn deren Voraussetzungen erfüllt sind.

Erwartetes Ergebnis: Sie kennen den Komponententyp, seinen Namen und die Manifestquelle, die für das fehlende oder widersprüchliche Attribut verantwortlich ist. Dies ist mit geringem Risiko verbunden und erfordert kein Zurücksetzen zur Laufzeit; machen Sie nur eine Manifeständerung rückgängig, falls die spätere Prüfung fehlschlägt. Android dokumentiert die zusammengeführte Ansicht, Protokolle, Quellen, Berichte und Merge-Markierungen in der Dokumentation zum Verwalten von Manifestdateien.

Den richtigen Wert für android:exported wählen

Fügen Sie für eine Komponente, die Ihnen gehört oder die Sie bearbeiten können, im zuständigen Manifest einen expliziten Wert hinzu. Erstellen Sie anschließend die betroffene Variante neu und prüfen Sie das endgültige zusammengeführte Manifest.

Zweck der Komponente Passender Wert Begründung
Launcher-Aktivität der App android:exported="true" Der Launcher ist ein Einstiegspunkt für externe Apps.
Bewusst extern erreichbare Aktivität, Dienst oder Empfänger android:exported="true" Verwenden Sie dies nur, wenn eine andere App die Komponente aufrufen muss.
Nur intern verwendeter Dienst android:exported="false" Verhindert unnötigen externen Zugriff.
Nur intern verwendeter Empfänger android:exported="false" Verhindert unnötigen externen Zugriff.
  1. Öffnen Sie das Manifest, zu dem die betroffene Komponente gehört.
  2. Fügen Sie android:exported="true" nur hinzu, wenn externe Apps sie erreichen müssen.
  3. Fügen Sie android:exported="false" hinzu, wenn sie nur intern verwendet wird.
  4. Erstellen Sie die betroffene Variante neu.
  5. Bestätigen Sie, dass das endgültige Merged Manifest den geprüften Wert enthält.

Risiko: Die Manifeständerung selbst ist mit geringem Risiko verbunden, aber das Setzen von true macht die Komponente extern zugänglich. Intent-Filter allein bieten für eine exponierte Komponente keine ausreichende Zugriffskontrolle. Prüfen Sie die Sicherheitsauswirkungen anhand der Android-Leitlinien zur Sicherheit exportierter Komponenten. Um die Änderung rückgängig zu machen, entfernen oder ändern Sie nur das hinzugefügte Attribut und erstellen Sie die App neu.

Den Fall einer MAIN- und LAUNCHER-Aktivität beheben

Wenn die betroffene Aktivität einen Intent-Filter mit MAIN und LAUNCHER enthält, ist sie der Einstiegspunkt der App und sollte normalerweise android:exported="true" deklarieren.

  1. Suchen Sie die Aktivität mit dem Intent-Filter MAIN und LAUNCHER.
  2. Setzen Sie bei dieser Aktivität android:exported="true".
  3. Erstellen Sie die App.
  4. Installieren oder starten Sie die App und prüfen Sie, ob das Launcher-Symbol die vorgesehene Aktivität öffnet.

Erwartetes Ergebnis: Die Launcher-Aktivität verfügt über einen expliziten Exportstatus und bleibt startbar. Damit wird kein separat benannter Fehler eines Dienstes oder Empfängers behoben. Das Risiko ist gering; stellen Sie die vorherige Deklaration nur wieder her, wenn die Aktivität kein Launcher-Einstiegspunkt mehr ist.

Wenn die Komponente aus einer Abhängigkeit, einem Testmodul oder einem generierten Manifest stammt

Wenn Merged Manifest zeigt, dass eine andere Eingabe die Komponente bereitstellt, sollten Sie nicht davon ausgehen, dass Ihr primäres App-Manifest der richtige Ort für die Änderung ist. Untersuchen Sie die tatsächlich beitragende Abhängigkeit, transitive Bibliothek, das Testmodul, die Build-Variante oder das generierte Manifest.

Vorsichtige Option: Wenn die Quelle veraltet erscheint, prüfen Sie vor der Pflege einer lokalen Überschreibung, ob ein kompatibles Abhängigkeitsupdate verfügbar ist. Ein Update kann die Deklaration entfernen oder korrigieren, dies ist jedoch nicht garantiert und muss in der betroffenen Variante getestet werden. Bestätigen Sie, dass erforderliche Funktionen der Abhängigkeit weiterhin funktionieren und das endgültige zusammengeführte Manifest den beabsichtigten Wert enthält.

Entfernen Sie eine beigesteuerte Komponente nicht nur, um den Fehler zu beseitigen. Sie kann für eine Bibliotheksfunktion erforderlich sein.

Eine eng begrenzte Manifest-Merger-Überschreibung nur bei Bedarf verwenden

Verwenden Sie eine Überschreibung erst, nachdem Merged Manifest nachweist, dass ein Manifest mit niedrigerer Priorität dieselbe Komponente definiert und ein tatsächlicher Konflikt beim Attribut android:exported vorliegt. Die Deklaration mit höherer Priorität muss dieselbe Komponente anhand von android:name identifizieren.

Einen geprüften exported-Wert überschreiben

  1. Deklarieren Sie den Tools-Namespace im Manifest mit höherer Priorität.
  2. Deklarieren Sie die übereinstimmende Komponente mit dem vorgesehenen Wert für android:exported.
  3. Verwenden Sie tools:replace="android:exported" nur bei einem tatsächlichen Attributkonflikt.
  4. Prüfen Sie Merged Manifest, um das Ergebnis zu bestätigen.
  5. Erstellen Sie die App neu und testen Sie den vorgesehenen Einstiegspfad der Komponente.

Risiko: mittel. Eine Überschreibung kann die externe Erreichbarkeit verändern. Machen Sie die Änderung rückgängig, indem Sie die überschreibende Komponentendeklaration und tools:replace entfernen und die App anschließend neu erstellen.

Eine nachweislich nicht benötigte Bibliothekskomponente entfernen

  1. Vergewissern Sie sich, dass die Komponente nicht von der Abhängigkeit oder einer App-Funktion benötigt wird.
  2. Fügen Sie im Manifest mit höherer Priorität eine passende Komponentendeklaration hinzu.
  3. Wenden Sie auf diese Komponente tools:node="remove" an.
  4. Prüfen Sie Merged Manifest, um die Entfernung zu bestätigen.
  5. Erstellen Sie die App und testen Sie Abhängigkeitsfunktionen, die die entfernte Komponente verwenden könnten.

Risiko: mittel. Das Entfernen einer Komponente kann das Verhalten einer Bibliothek beeinträchtigen. Machen Sie die Änderung rückgängig, indem Sie die Deklaration mit tools:node="remove" entfernen und die App neu erstellen.

Die Korrektur im endgültigen Manifest und im App-Verhalten prüfen

  • Bestätigen Sie, dass Merged Manifest bei der betroffenen Komponente einen expliziten, geprüften Wert für android:exported zeigt.
  • Erstellen Sie die betroffene Variante erfolgreich.
  • Testen Sie den vorgesehenen Einstiegspfad: Launcher, Deep Link, Dienst- oder Empfängerverhalten, je nach Fall.
  • Wenn sich ein Einstiegspunkt einer Abhängigkeit geändert hat, testen Sie Abhängigkeitsfunktionen, die diese Komponente aufrufen oder von ihr abhängen könnten.
  • Prüfen Sie bei einer extern erreichbaren Komponente manuell, ob ihre Aufrufer zusätzlich zum Exportstatus einen Berechtigungsschutz oder eine Aufruferprüfung benötigen.

Ein erfolgreicher Build bestätigt, dass die Merge-Anforderung erfüllt ist; er beweist allein nicht, dass die Komponente sicher ist oder sich wie vorgesehen verhält. Die Freigabe von Datei-URIs ist ein separates Problem der Zugriffskontrolle: Nutzen Sie die Anleitung zum Freigeben von Dateien mit FileProvider, statt Datei-URIs offenzulegen, anstatt Komponenten pauschal zu exportieren. Ebenso sind Fehler der Android-Netzwerksicherheitsrichtlinie von diesem Manifest-Merger-Fehler getrennt zu betrachten.

Häufig gestellte Fragen

Sollte ich android:exported=”true” setzen, um diesen Fehler zu beheben?

Nein. Verwenden Sie true nur, wenn andere Apps die Komponente aufrufen müssen. Verwenden Sie false für ausschließlich interne Aktivitäten, Dienste und Empfänger und prüfen Sie anschließend die zusammengeführte Ausgabe.

Warum bleibt der Fehler bestehen, nachdem ich meine Launcher-Aktivität geändert habe?

Die fehlerhafte Komponente kann eine andere Aktivität, ein Dienst oder Empfänger sein oder aus einer Abhängigkeit, einem Testmodul, einer Variante oder einem generierten Manifest stammen. Prüfen Sie Merged Manifest und dessen Quellen.

Kann ich tools:replace=”android:exported” verwenden?

Nur wenn ein Manifest mit höherer Priorität dieselbe Komponente definiert und ein tatsächlicher Konflikt beim Attribut android:exported besteht. Prüfen Sie das endgültige zusammengeführte Ergebnis und testen Sie den vorgesehenen Einstiegspfad der Komponente.