Neben neuen Funktionen und Möglichkeiten beinhaltet Android 8.0 (API-Level 26) eine Reihe von Änderungen am System- und API-Verhalten. In diesem Dokument werden einige der wichtigsten Änderungen beschrieben, die Sie in Ihren Anwendungen verstehen und berücksichtigen sollten.
Die meisten dieser Änderungen betreffen alle Apps, unabhängig davon, auf welche Android-Version sie ausgerichtet sind. Einige Änderungen betreffen jedoch nur Apps, die auf Android 8.0 ausgerichtet sind. Der Übersichtlichkeit halber ist diese Seite in zwei Abschnitte unterteilt: Änderungen für alle Apps und Änderungen für Apps, die auf Android 8.0 ausgerichtet sind.
Änderungen für alle Apps
Diese Verhaltensänderungen gelten für
Limits für die Ausführung im Hintergrund
Eine der Änderungen, die in Android 8.0 (API-Level 26) eingeführt wird, um die Akkulaufzeit zu verlängern: Wenn deine App in den Cache-Status wechselt und keine aktiven Komponenten vorhanden sind, gibt das System alle Wakelocks der App frei.
Darüber hinaus schränkt das System zur Verbesserung der Geräteleistung bestimmte Verhaltensweisen von Apps ein, die nicht im Vordergrund ausgeführt werden. Im Detail:
- Für Anwendungen, die im Hintergrund ausgeführt werden, gelten jetzt Einschränkungen für den freien Zugriff auf Hintergrunddienste.
- Apps können ihre Manifeste nicht verwenden, um sich für die meisten impliziten Broadcasts zu registrieren, d. h. Broadcasts, die nicht speziell auf die App ausgerichtet sind.
Standardmäßig gelten diese Einschränkungen nur für Apps, die auf O ausgerichtet sind. Nutzer können diese Einschränkungen jedoch auf dem Bildschirm Einstellungen für jede App aktivieren, auch wenn die App nicht auf O ausgerichtet ist.
Android 8.0 (API-Level 26) umfasst außerdem die folgenden Änderungen bei bestimmten Methoden:
- Die Methode
startService()
gibt jetzt einIllegalStateException
aus, wenn eine auf Android 8.0 ausgerichtete App versucht, diese Methode in einer Situation zu verwenden, in der das Erstellen von Hintergrunddiensten nicht zulässig ist. - Mit der neuen Methode
Context.startForegroundService()
wird ein Dienst im Vordergrund gestartet. Durch das System können AppsContext.startForegroundService()
auch dann aufrufen, wenn die App im Hintergrund läuft. Die Anwendung muss die MethodestartForeground()
dieses Dienstes jedoch innerhalb von fünf Sekunden nach Erstellung des Dienstes aufrufen.
Weitere Informationen finden Sie unter Limits für die Hintergrundausführung.
Beschränkungen für die Standortermittlung im Hintergrund auf Android-Geräten
Hintergrund-Apps erhalten Standortupdates seltener, wenn sie auf einem Gerät mit Android 8.0 verwendet werden, um den Akku, die Nutzerfreundlichkeit und den Systemzustand zu schonen. Diese Verhaltensänderung betrifft alle Apps, die Standortaktualisierungen erhalten, einschließlich Google Play-Dienste.
Diese Änderungen betreffen die folgenden APIs:
- Fused Location Provider (FLP)
- Geofencing
- GNSS-Messungen
- Standortmanager
- WLAN-Manager
So sorgen Sie dafür, dass Ihre App wie erwartet ausgeführt wird:
- Prüfen Sie die Logik Ihrer App und achten Sie darauf, dass Sie die neuesten Standort-APIs verwenden.
- Testen Sie, ob Ihre Anwendung das Verhalten zeigt, das Sie für jeden Anwendungsfall erwarten.
- Du kannst den Fused Location Provider (FLP) oder Geofencing verwenden, um die Anwendungsfälle abzuwickeln, die vom aktuellen Standort des Nutzers abhängen.
Weitere Informationen zu diesen Änderungen findest du unter Limits für die Standortermittlung im Hintergrund.
App-Verknüpfungen
Unter Android 8.0 (API-Level 26) wurden die folgenden Änderungen an App-Verknüpfungen vorgenommen:
- Die
com.android.launcher.action.INSTALL_SHORTCUT
-Übertragung hat keine Auswirkungen mehr auf Ihre App, da sie jetzt eine private, implizite Übertragung ist. Erstellen Sie stattdessen eine App-Verknüpfung mit der MethoderequestPinShortcut()
aus der KlasseShortcutManager
. - Der Intent
ACTION_CREATE_SHORTCUT
kann jetzt App-Verknüpfungen erstellen, die Sie mit der KlasseShortcutManager
verwalten. Dieser Intent kann auch Legacy-Launcher-Verknüpfungen erstellen, die nicht mitShortcutManager
interagieren. Bisher konnten mit diesem Intent nur Legacy-Launcher-Verknüpfungen erstellt werden. - Verknüpfungen, die mit
requestPinShortcut()
erstellt wurden, und Verknüpfungen, die in einer Aktivität erstellt wurden, die den IntentACTION_CREATE_SHORTCUT
verarbeitet, sind jetzt vollwertige App-Verknüpfungen. Daher können Anwendungen sie jetzt mit den Methoden inShortcutManager
aktualisieren. - Alte Tastenkombinationen funktionieren weiterhin wie in früheren Android-Versionen, müssen aber in deiner App manuell in App-Verknüpfungen umgewandelt werden.
Weitere Informationen zu Änderungen an App-Verknüpfungen finden Sie im Leitfaden zum Anpinnen von Verknüpfungen und Widgets.
Sprachen und Internationalisierung
Mit Android 7.0 (API-Level 24) wurde das Konzept eingeführt, ein Standardgebietsschema für die Kategorie angeben zu können. Einige APIs nutzten jedoch weiterhin die generische Locale.getDefault()
-Methode ohne Argumente, obwohl sie stattdessen die Standardsprache der DISPLAY
-Kategorie verwendet hätten sollten. In Android 8.0 (API-Level 26) wird für die folgenden Methoden jetzt Locale.getDefault(Category.DISPLAY)
anstelle von Locale.getDefault()
verwendet:
Locale.getDisplayScript(Locale)
wird auch auf Locale.getDefault()
zurückgesetzt, wenn der für das Argument Locale
angegebene displayScript-Wert nicht verfügbar ist.
Zusätzliche Änderungen in Bezug auf die Sprache und die Internationalisierung:
- Durch das Aufrufen von
Currency.getDisplayName(null)
wird entsprechend dem dokumentierten Verhalten einNullPointerException
ausgegeben. - Das Parsen von Zeitzonennamen hat sich geändert. Bisher wurde auf Android-Geräten der beim Start erfasste Systemuhrwert verwendet, um die Zeitzonennamen im Cache zu speichern, die zum Parsen von Datum und Uhrzeit verwendet wurden. Dies kann sich negativ auf das Parsen auswirken, wenn die Systemuhr beim Start falsch war oder in anderen, seltenen Fällen.
In den meisten Fällen verwendet die Parsing-Logik beim Parsen von Zeitzonennamen ICU und den aktuellen Systemuhrwert. Durch diese Änderung erhältst du korrektere Ergebnisse, die sich von früheren Android-Versionen unterscheiden können, wenn deine App Klassen wie
SimpleDateFormat
verwendet. - Unter Android 8.0 (API-Level 26) wird die ICU auf Version 58 aktualisiert.
Benachrichtigungsfenster
Wenn eine App die Berechtigung SYSTEM_ALERT_WINDOW
und einen der folgenden Fenstertypen verwendet, um zu versuchen, Benachrichtigungsfenster über anderen Apps und Systemfenstern anzuzeigen:
...dann werden diese Fenster immer unter den Fenstern mit dem Fenstertyp TYPE_APPLICATION_OVERLAY
angezeigt. Ist eine App auf Android 8.0 (API-Level 26) ausgerichtet, verwendet die App den Fenstertyp TYPE_APPLICATION_OVERLAY
, um Benachrichtigungsfenster anzuzeigen.
Weitere Informationen finden Sie im Abschnitt Häufig verwendete Fenstertypen für Benachrichtigungsfenster in den Verhaltensänderungen für Apps für Android 8.0.
Eingabe und Navigation
Mit der Einführung von Android-Apps unter ChromeOS und anderen großen Formfaktoren wie Tablets haben wir festgestellt, dass die Tastaturnavigation in Android-Apps immer häufiger verwendet wird. Unter Android 8.0 (API-Level 26) haben wir die Tastatur als Navigationseingabegerät überarbeitet, was zu einem zuverlässigeren, vorhersehbaren Modell für die pfeil- und tabulatorbasierte Navigation führt.
Insbesondere haben wir die folgenden Änderungen am Verhalten des Elementfokus vorgenommen:
-
Wenn du für ein
View
-Objekt (entweder sein Drawable im Vorder- oder Hintergrund) keine Farben für den Fokusstatus definiert hast, legt das Framework jetzt eine Standardfarbe für die Hervorhebung des Fokus fürView
fest. Diese Fokusmarkierung ist ein Ripple-Drawable, das auf dem Thema der Aktivität basiert.Wenn du nicht möchtest, dass ein
View
-Objekt diese standardmäßige Hervorhebung beim Empfang des Fokus verwendet, setze dasandroid:defaultFocusHighlightEnabled
-Attribut in der Layout-XML-Datei, dieView
enthält, auffalse
oder übergibfalse
in der UI-Logik deiner App ansetDefaultFocusHighlightEnabled()
. - Wenn Sie testen möchten, wie sich die Tastatureingabe auf den Fokus des UI-Elements auswirkt, können Sie die Entwickleroption Zeichnung > Layoutgrenzen anzeigen aktivieren. In Android 8.0 wird durch diese Option ein „X“-Symbol über dem Element angezeigt, das derzeit im Fokus ist.
Außerdem sind alle Symbolleistenelemente in Android 8.0 automatisch Tastaturnavigationscluster, was den Nutzern das Aufrufen und Verlassen der einzelnen Symbolleisten erleichtert.
Weitere Informationen dazu, wie Sie die Unterstützung für die Tastaturnavigation in Ihrer App verbessern können, finden Sie im Leitfaden Unterstützung der Tastaturnavigation.
Webformular automatisch ausfüllen
Da das Android Autofill-Framework jetzt die Funktion zum automatischen Ausfüllen unterstützt, haben sich die folgenden Methoden für WebView
-Objekte für Apps geändert, die auf Geräten mit Android 8.0 (API-Ebene 26) installiert sind:
WebSettings
-
- Die Methode
getSaveFormData()
gibt jetztfalse
zurück. Zuvor wurde bei dieser Methode stattdessentrue
zurückgegeben. - Das Aufrufen von
setSaveFormData()
hat keine Auswirkungen mehr.
- Die Methode
WebViewDatabase
-
- Das Aufrufen von
clearFormData()
hat keine Auswirkungen mehr. - Die Methode
hasFormData()
gibt jetztfalse
zurück. Bisher wurde bei dieser Methodetrue
zurückgegeben, wenn das Formular Daten enthielt.
- Das Aufrufen von
Bedienungshilfen
Unter Android 8.0 (API-Level 26) wurden die folgenden Änderungen bei den Bedienungshilfen vorgenommen:
-
Das Framework für Bedienungshilfen wandelt jetzt alle Touch-Gesten zum Doppeltippen in
ACTION_CLICK
-Aktionen um. Durch diese Änderung verhält sich TalkBack ähnlich wie andere Bedienungshilfen.Wenn die
View
-Objekte deiner App benutzerdefinierte Touchbedienung verwenden, solltest du prüfen, ob sie noch mit TalkBack funktionieren. Unter Umständen müssen Sie nur den Klick-Handler registrieren, der von IhrenView
-Objekten verwendet wird. Wenn TalkBack weiterhin keine Touch-Gesten erkennt, die für dieseView
-Objekte ausgeführt wurden, überschreiben SieperformAccessibilityAction()
. - Bedienungshilfen erkennen jetzt alle
ClickableSpan
-Instanzen in denTextView
-Objekten deiner App.
Weitere Informationen dazu, wie Sie die Barrierefreiheit Ihrer App verbessern können, finden Sie unter Bedienungshilfen.
Netzwerk und HTTP(S)-Verbindung
Android 8.0 (API-Level 26) umfasst die folgenden Änderungen im Verhalten von Netzwerken und HTTP(S)-Verbindungen:
- OPTIONS-Anfragen ohne Text haben einen
Content-Length: 0
-Header. Bisher hatten sie keineContent-Length
-Kopfzeile. - HttpURLConnection normalisiert URLs mit leeren Pfaden, indem nach dem Host- oder Zertifizierungsstellennamen ein Schrägstrich mit einem Schrägstrich angehängt wird. Beispielsweise wird
http://example.com
inhttp://example.com/
umgewandelt. - Eine mit ProxySelector.setDefault() festgelegte benutzerdefinierte Proxyauswahl zielt nur auf die Adresse (Schema, Host und Port) einer angeforderten URL ab. Die Proxyauswahl kann daher nur auf diesen Werten basieren. Eine URL, die an einen benutzerdefinierten Proxy-Selektor übergeben wird, enthält nicht den Pfad, die Abfrageparameter oder die Fragmente der angeforderten URL.
- URIs dürfen keine leeren Labels enthalten.
Bisher wurde von der Plattform eine Problemumgehung unterstützt, um leere Labels in Hostnamen zu akzeptieren. Die Verwendung von URIs ist damit nicht zulässig. Diese Umgehung diente der Kompatibilität mit älteren Libcore-Releases. Entwicklern, die die API fälschlicherweise verwenden, wird die ADB-Meldung angezeigt: „URI beispiel.de enthält leere Labels im Hostnamen. Dieses ist fehlerhaft und wird in zukünftigen Android-Releases nicht mehr akzeptiert.“ Unter Android 8.0 wurde diese Problemumgehung entfernt. Das System gibt für fehlerhafte URIs null zurück.
- Die Implementierung von HttpsURLConnection in Android 8.0 bietet keinen Fallback für unsichere TLS/SSL-Protokollversionen.
- Die Verarbeitung von Tunneling-HTTP(S)-Verbindungen hat sich folgendermaßen geändert:
- Beim Tunneling einer HTTPS-Verbindung über eine Verbindung fügt das System beim Senden dieser Informationen an einen Zwischenserver die Portnummer (:443) korrekt in die Host-Zeile ein. Bisher kam die Portnummer nur in der CONNECT-Zeile vor.
- Das System sendet keine User-Agent- und Proxy-Autorisierungs-Header von einer getunnelten Anfrage an den Proxyserver.
Beim Einrichten des Tunnels sendet das System keinen Proxy-Autorisierungs-Header auf einer getunnelten Http(s)URLConnection an den Proxy. Stattdessen generiert das System einen Proxy-Autorisierungs-Header und sendet ihn an den Proxy, wenn dieser Proxy als Antwort auf die ursprüngliche Anfrage HTTP 407 sendet.
Ebenso wird der User-Agent-Header nicht mehr von der getunnelten Anfrage in die Proxyanfrage kopiert, die den Tunnel einrichtet. Stattdessen generiert die Bibliothek einen User-Agent-Header für diese Anfrage.
- Die Methode
send(java.net.DatagramPacket)
löst eine SocketException aus, wenn die zuvor ausgeführte Methode "connect()" fehlgeschlagen ist.- DatagramSocket.connect() legt eine pendingSocketException fest, wenn ein interner Fehler vorliegt. Vor Android 8.0 löste ein nachfolgender recv()-Aufruf eine SocketException aus, obwohl ein send()-Aufruf erfolgreich gewesen wäre. Aus Konsistenzgründen geben beide Aufrufe jetzt eine SocketException ab.
- InetAddress.isReachable() versucht ICMP, bevor auf das TCP Echo-Protokoll zurückgegriffen wird.
- Einige Hosts, die Port 7 (TCP Echo) blockieren, z. B. google.com, sind jetzt möglicherweise erreichbar, wenn sie das ICMP Echo-Protokoll akzeptieren.
- Für wirklich nicht erreichbare Hosts bedeutet diese Änderung, dass das Doppelte der Zeit aufgewendet wird, bevor der Aufruf zurückkehrt.
Bluetooth
Unter Android 8.0 (API-Level 26) werden die folgenden Änderungen an der Länge der Daten vorgenommen, die von der Methode ScanRecord.getBytes()
abgerufen werden:
- Bei der Methode
getBytes()
wird keine Annahme in Bezug auf die Anzahl der empfangenen Byte getroffen. Daher sollten sich Anwendungen nicht auf eine Mindest- oder Höchstanzahl der zurückgegebenen Byte verlassen. Stattdessen sollten sie die Länge des resultierenden Arrays auswerten. - Bluetooth 5-kompatible Geräte geben möglicherweise Daten zurück, die das vorherige Maximum von ca. 60 Byte überschreiten.
- Wenn ein Remote-Gerät keine Scanantwort zurückgibt, werden möglicherweise auch weniger als 60 Byte zurückgegeben.
Nahtlose Konnektivität
Unter Android 8.0 (API-Level 26) wurden eine Reihe von Verbesserungen an den WLAN-Einstellungen vorgenommen, um die Auswahl des WLANs mit der besten Nutzererfahrung zu erleichtern. Zu den Änderungen gehören:
- Verbesserte Stabilität und Zuverlässigkeit
- Eine intuitivere Benutzeroberfläche.
- Ein einzelnes, konsolidiertes Menü für die WLAN-Einstellungen.
- Auf kompatiblen Geräten wird die WLAN-Funktion automatisch aktiviert, wenn sich ein hochwertiges gespeichertes Netzwerk in der Nähe befindet.
Sicherheit
Android 8.0 umfasst die folgenden sicherheitsbezogenen Änderungen:
- SSLv3 wird von der Plattform nicht mehr unterstützt.
- Beim Herstellen einer HTTPS-Verbindung zu einem Server, auf dem die Verhandlung von TLS-Protokollversionen falsch implementiert ist, versucht
HttpsURLConnection
nicht mehr, auf frühere TLS-Protokollversionen zurückzugreifen und es noch einmal zu versuchen. - Android 8.0 (API-Level 26) wendet einen SECCOMP-Filter (Secure Computing) auf alle Apps an. Die Liste der zulässigen Systemaufrufe ist auf diejenigen beschränkt, die über Bionik ausgelöst werden. Obwohl aus Gründen der Abwärtskompatibilität einige andere Systemaufrufe bereitgestellt werden, raten wir von ihrer Verwendung ab.
- Die
WebView
-Objekte Ihrer App werden jetzt im Multiprozessmodus ausgeführt. Zur erhöhten Sicherheit werden Webinhalte in einem separaten, isolierten Prozess von dem Prozess der beinhaltenden Anwendung verarbeitet. -
Sie können nicht mehr davon ausgehen, dass sich APKs in Verzeichnissen befinden, deren Namen auf -1 oder -2 enden. Anwendungen sollten zum Abrufen des Verzeichnisses
sourceDir
verwenden und sich nicht direkt vom Verzeichnisformat abhängig machen. - Informationen zu Sicherheitsverbesserungen in Bezug auf die Verwendung nativer Bibliotheken finden Sie unter Native Bibliotheken.
Darüber hinaus werden in Android 8.0 (API-Level 26) die folgenden Änderungen im Zusammenhang mit der Installation unbekannter Apps aus unbekannten Quellen eingeführt:
- Der Wert der Legacy-Einstellung
INSTALL_NON_MARKET_APPS
ist jetzt immer „1“. Wenn Sie ermitteln möchten, ob eine unbekannte Quelle Anwendungen mit dem Paketinstallationsprogramm installieren kann, sollten Sie stattdessen den RückgabewertcanRequestPackageInstalls()
verwenden. - Wenn Sie versuchen, den Wert von
INSTALL_NON_MARKET_APPS
mitsetSecureSetting()
zu ändern, wird einUnsupportedOperationException
ausgegeben. Wenn Sie verhindern möchten, dass Nutzer unbekannte Apps aus unbekannten Quellen installieren, sollten Sie stattdessen die NutzereinschränkungDISALLOW_INSTALL_UNKNOWN_SOURCES
festlegen. -
Bei verwalteten Profilen, die auf Geräten mit Android 8.0 (API-Level 26) erstellt werden, ist die Nutzereinschränkung
DISALLOW_INSTALL_UNKNOWN_SOURCES
automatisch aktiviert. Bei vorhandenen verwalteten Profilen auf Geräten, die auf Android 8.0 aktualisiert werden, wird die NutzereinschränkungDISALLOW_INSTALL_UNKNOWN_SOURCES
automatisch aktiviert, es sei denn, der Profilinhaber hat diese Einschränkung vor dem Upgrade explizit deaktiviert, indem erINSTALL_NON_MARKET_APPS
auf 1 gesetzt hat.
Weitere Informationen zum Installieren unbekannter Apps finden Sie in der Anleitung Unbekannte App-Installationsberechtigungen.
Weitere Richtlinien zur Erhöhung der Sicherheit Ihrer App finden Sie unter Sicherheit für Android-Entwickler.
Datenschutz
Unter Android 8.0 (API-Level 26) werden die folgenden datenschutzbezogenen Änderungen an der Plattform vorgenommen.
- Kennungen werden auf der Plattform jetzt unterschiedlich verarbeitet.
-
Bei Apps, die vor einem OTA-Update auf eine Version von Android 8.0 (API-Level 26) (API-Level 26) installiert wurden, bleibt der Wert von
ANDROID_ID
gleich, sofern sie nicht deinstalliert und nach dem OTA-Update wieder neu installiert wird. Damit Werte nach dem OTA-Update auch bei Deinstallationen beibehalten werden, können Entwickler die alten und neuen Werte mithilfe der Schlüssel/Wert-Sicherung verknüpfen. - Für Apps, die auf einem Gerät mit Android 8.0 installiert sind, wird der Wert von
ANDROID_ID
jetzt pro App-Signaturschlüssel und pro Nutzer definiert. Der Wert vonANDROID_ID
ist für jede Kombination aus App-Signaturschlüssel, Nutzer und Gerät eindeutig. Dadurch wird für Apps mit unterschiedlichen Signaturschlüsseln, die auf demselben Gerät ausgeführt werden, nicht mehr dieselbe Android-ID angezeigt (auch nicht für denselben Nutzer). - Der Wert von
ANDROID_ID
ändert sich bei der Deinstallation oder Neuinstallation eines Pakets nicht, solange der Signaturschlüssel gleich ist und die App nicht vor einem OTA-Update auf eine Version von Android 8.0 installiert wurde. - Der Wert von
ANDROID_ID
ändert sich nicht, auch wenn ein Systemupdate eine Änderung des Paketsignaturschlüssels zur Folge hat. - Auf Geräten, die mit Google Play-Diensten und der Werbe-ID ausgeliefert werden, musst du die
Werbe-ID verwenden. Die Werbe-ID ist eine eindeutige, vom Nutzer zurücksetzbare Werbe-ID, ein einfaches Standardsystem zur Monetarisierung von Apps. Sie wird von den Google Play-Diensten bereitgestellt.
Andere Gerätehersteller sollten weiterhin
ANDROID_ID
bereitstellen.
-
Bei Apps, die vor einem OTA-Update auf eine Version von Android 8.0 (API-Level 26) (API-Level 26) installiert wurden, bleibt der Wert von
- Beim Abfragen der Systemeigenschaft
net.hostname
wird ein Nullergebnis zurückgegeben.
Protokollierung nicht erfasster Ausnahmen
Wenn eine App eine Thread.UncaughtExceptionHandler
installiert, die nicht den standardmäßigen Thread.UncaughtExceptionHandler
aufruft, beendet das System die App nicht, wenn eine nicht abgefangene Ausnahme auftritt. Ab Android 8.0 (API-Ebene 26) protokolliert das System in dieser Situation den Ausnahme-Stacktrace. In früheren Versionen der Plattform hätte das System den Ausnahme-Stacktrace nicht protokolliert.
Wir empfehlen, dass benutzerdefinierte Thread.UncaughtExceptionHandler
-Implementierungen immer den Standard-Handler aufrufen. Apps, die dieser Empfehlung folgen, sind von der Änderung in Android 8.0 nicht betroffen.
findViewById()-Signaturänderung
Alle Instanzen der findViewById()
-Methode geben jetzt
<T extends View> T
anstelle von View
zurück. Diese Änderung hat folgende Auswirkungen:
- Dies kann dazu führen, dass vorhandener Code einen mehrdeutigen Rückgabetyp hat, z. B. wenn sowohl
someMethod(View)
als auchsomeMethod(TextView)
das Ergebnis eines Aufrufs vonfindViewById()
annimmt. - Bei Verwendung der Java 8-Quellsprache erfordert dies eine explizite Umwandlung in
View
, wenn der Rückgabetyp nicht eingeschränkt ist (z. B.assertNotNull(findViewById(...)).someViewMethod())
). - Für Überschreibungen nicht finaler
findViewById()
-Methoden (z. B.Activity.findViewById()
) muss der Rückgabetyp aktualisiert werden.
Änderung der Nutzungsstatistiken des Kontaktanbieters
In früheren Android-Versionen können Entwickler mit der Contact Provider-Komponente Nutzungsdaten für jeden Kontakt abrufen. In diesen Nutzungsdaten finden Sie Informationen für jede E-Mail-Adresse und jede Telefonnummer, die mit einem Kontakt verknüpft ist, einschließlich der Häufigkeit, mit der der Kontakt kontaktiert wurde, und der letzten Kontaktaufnahme mit dem Kontakt. Apps, die die Berechtigung READ_CONTACTS
anfordern, können diese Daten lesen.
Apps können diese Daten weiterhin lesen, wenn sie die Berechtigung READ_CONTACTS
anfordern. Unter Android 8.0 (API-Level 26) und höher werden bei Abfragen von Nutzungsdaten Näherungswerte und nicht exakte Werte zurückgegeben. Das Android-System verwaltet die genauen Werte intern, sodass diese Änderung keine Auswirkungen auf die API für die automatische Vervollständigung hat.
Diese Verhaltensänderung betrifft die folgenden Abfrageparameter:
Umgang mit Sammlungen
AbstractCollection.removeAll()
und AbstractCollection.retainAll()
geben jetzt immer ein NullPointerException
aus. Zuvor wurde NullPointerException
nicht ausgegeben, wenn die Sammlung leer war. Durch diese Änderung entspricht das Verhalten der Dokumentation.
Android Enterprise
Android 8.0 (API-Level 26) ändert das Verhalten einiger APIs und Funktionen für Unternehmensanwendungen, einschließlich Device Policy Controller (DPCs). Zu den Änderungen gehören:
- Neue Funktionsweisen, damit Apps Arbeitsprofile auf vollständig verwalteten Geräten unterstützen
- Änderungen an der Verarbeitung von Systemupdates, App-Überprüfung und Authentifizierung zur Verbesserung der Geräte- und Systemintegrität.
- Verbesserungen für Bereitstellung, Benachrichtigungen, den Bildschirm „Zuletzt verwendet“ und das durchgehend aktive VPN
Alle Änderungen für Unternehmen in Android 8.0 (API-Level 26) und deren Auswirkungen auf deine App findest du unter Android in Unternehmen.
Apps, die auf Android 8.0 ausgerichtet sind
Diese Änderungen gelten ausschließlich für Apps, die auf Android 8.0 (API-Level 26) oder höher ausgerichtet sind. Apps, die für Android 8.0 kompiliert werden oder für targetSdkVersion
Android 8.0 oder höher festlegen, müssen gegebenenfalls diese Verhaltensweisen entsprechend anpassen.
Benachrichtigungsfenster
Apps mit der Berechtigung SYSTEM_ALERT_WINDOW
können die folgenden Fenstertypen nicht mehr verwenden, um Benachrichtigungsfenster über anderen Apps und Systemfenstern anzuzeigen:
Stattdessen müssen Anwendungen einen neuen Fenstertyp mit dem Namen TYPE_APPLICATION_OVERLAY
verwenden.
Wenn Sie den Fenstertyp TYPE_APPLICATION_OVERLAY
zum Anzeigen von Benachrichtigungsfenstern für Ihre App verwenden, beachten Sie die folgenden Eigenschaften des neuen Fenstertyps:
- Die Benachrichtigungsfenster einer Anwendung werden immer unter kritischen Systemfenstern wie der Statusleiste und den IMEs angezeigt.
- Das System kann Fenster, die den Fenstertyp
TYPE_APPLICATION_OVERLAY
verwenden, verschieben oder ihre Größe anpassen, um die Bildschirmdarstellung zu verbessern. - Durch Öffnen der Benachrichtigungsleiste können Nutzer auf die Einstellungen zugreifen, um zu verhindern, dass eine App Benachrichtigungsfenster anzeigt, die mit dem Fenstertyp
TYPE_APPLICATION_OVERLAY
angezeigt werden.
Benachrichtigungen zu Inhaltsänderungen
Unter Android 8.0 (API-Level 26) ändert sich das Verhalten von ContentResolver.notifyChange()
und registerContentObserver(Uri, boolean, ContentObserver)
bei Apps, die auf Android 8.0 ausgerichtet sind.
Für diese APIs muss jetzt ein gültiger ContentProvider
für die Zertifizierungsstelle in allen URIs definiert sein. Wenn du eine gültige ContentProvider
mit entsprechenden Berechtigungen definierst, kannst du deine App besser vor Inhaltsänderungen durch schädliche Anwendungen schützen und verhindern, dass potenziell private Daten an schädliche Anwendungen weitergegeben werden.
Fokus anzeigen
Anklickbare View
-Objekte sind jetzt auch standardmäßig fokussierbar. Wenn ein View
-Objekt anklickbar, aber nicht fokussierbar sein soll, setzen Sie das Attribut
android:focusable
in der Layout-XML-Datei, die View
enthält, auf false
oder übergeben Sie false
in der UI-Logik Ihrer App auf setFocusable()
.
User-Agent-Abgleich bei der Browsererkennung
Android 8.0 (API-Level 26) und höher enthalten den Build-ID-String OPR
. Einige Musterübereinstimmungen können dazu führen, dass die Browsererkennungslogik einen Nicht-Opera-Browser fälschlicherweise als Opera identifiziert.
Ein Beispiel für eine solche Musterübereinstimmung könnte sein:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
Um Probleme aufgrund einer solchen Fehlidentifizierung zu vermeiden, verwenden Sie einen anderen String als OPR
als Musterübereinstimmung für den Opera-Browser.
Sicherheit
Die folgenden Änderungen wirken sich auf die Sicherheit unter Android 8.0 (API-Level 26) aus:
- Wenn in der Netzwerksicherheitskonfiguration Ihrer App die Unterstützung von Klartext-Traffic deaktiviert wird, können die
WebView
-Objekte Ihrer App nicht über HTTP auf Websites zugreifen. JedesWebView
-Objekt muss stattdessen HTTPS verwenden. - Die Systemeinstellung Unbekannte Quellen zulassen wurde entfernt. Mit der Berechtigung Unbekannte Apps installieren werden unbekannte App-Installationen aus unbekannten Quellen verwaltet. Weitere Informationen zu dieser neuen Berechtigung finden Sie in der Anleitung Unbekannte Berechtigungen für die Installation von Apps.
Weitere Richtlinien zur Erhöhung der Sicherheit Ihrer App finden Sie unter Sicherheit für Android-Entwickler.
Kontozugriff und Sichtbarkeit
In Android 8.0 (API-Ebene 26) können Apps nur dann auf Nutzerkonten zugreifen, wenn der Authenticator Inhaber der Konten ist oder der Nutzer diesen Zugriff gewährt. Die Berechtigung GET_ACCOUNTS
reicht nicht mehr aus. Damit Anwendungen Zugriff auf ein Konto erhalten, sollten sie entweder AccountManager.newChooseAccountIntent()
oder eine Authenticator-spezifische Methode verwenden. Nachdem eine App Zugriff auf Konten erhalten hat, kann sie AccountManager.getAccounts()
aufrufen, um darauf zuzugreifen.
Unter Android 8.0 wird LOGIN_ACCOUNTS_CHANGED_ACTION
eingestellt. Anwendungen sollten stattdessen addOnAccountsUpdatedListener()
verwenden, um während der Laufzeit Updates zu Konten zu erhalten.
Informationen zu neuen APIs und Methoden, die für den Kontozugriff und die Sichtbarkeit hinzugefügt wurden, finden Sie in diesem Dokument im Abschnitt zu den neuen APIs unter Kontozugriff und Auffindbarkeit.
Datenschutz
Die folgenden Änderungen wirken sich auf den Datenschutz unter Android 8.0 (API-Level 26) aus.
-
Die Systemeigenschaften
net.dns1
,net.dns2
,net.dns3
undnet.dns4
sind nicht mehr verfügbar. Mit dieser Änderung wird der Datenschutz auf der Plattform verbessert. -
Um Netzwerkinformationen wie DNS-Server zu erhalten, können Apps mit der Berechtigung
ACCESS_NETWORK_STATE
einNetworkRequest
- oderNetworkCallback
-Objekt registrieren. Diese Klassen sind ab Android 5.0 (API-Level 21) verfügbar. -
Build.SERIAL wurde eingestellt.
Apps, die die Seriennummer der Hardware kennen müssen, sollten stattdessen die neue Methode
Build.getSerial()
verwenden, für die die BerechtigungREAD_PHONE_STATE
erforderlich ist. -
Mit der
LauncherApps
API können Apps im Arbeitsprofil keine Informationen mehr zum primären Profil abrufen. Wenn sich ein Nutzer in einem Arbeitsprofil befindet, verhält sich dieLauncherApps
API so, als ob keine Apps in anderen Profilen in derselben Profilgruppe installiert sind. Wie zuvor verursachen Versuche, auf nicht relevante Profile zuzugreifen, SecurityExceptions.
Berechtigungen
Vor Android 8.0 (API-Level 26) hat das System der App auch fälschlicherweise die restlichen Berechtigungen erteilt, die zur selben Berechtigungsgruppe gehören und im Manifest registriert waren, wenn eine App zur Laufzeit eine Berechtigung angefordert und die Berechtigung erteilt wurde.
Bei Apps, die auf Android 8.0 ausgerichtet sind, wurde dieses Verhalten korrigiert. Der Anwendung werden nur die Berechtigungen gewährt, die sie explizit angefordert hat. Sobald der Nutzer der App jedoch eine Berechtigung erteilt, werden alle nachfolgenden Berechtigungsanfragen in dieser Berechtigungsgruppe automatisch gewährt.
Angenommen, eine Anwendung listet in ihrem Manifest sowohl READ_EXTERNAL_STORAGE
als auch WRITE_EXTERNAL_STORAGE
auf.
Die Anwendung fordert READ_EXTERNAL_STORAGE
an und der Nutzer gewährt sie. Wenn die App auf API-Level 25 oder niedriger ausgerichtet ist, gewährt das System gleichzeitig WRITE_EXTERNAL_STORAGE
, da sie zur selben STORAGE
-Berechtigungsgruppe gehört und auch im Manifest registriert ist. Wenn die App auf Android 8.0 (API-Level 26) ausgerichtet ist, gewährt das System zu diesem Zeitpunkt nur READ_EXTERNAL_STORAGE
. Wenn die App jedoch später WRITE_EXTERNAL_STORAGE
anfordert, gewährt das System diese Berechtigung sofort, ohne den Nutzer zu fragen.
Medien
- Das Framework kann automatisches Audio-Ducking selbst ausführen. Wenn in diesem Fall eine andere Anwendung den Fokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
anfordert, verringert die fokussierte Anwendung die Lautstärke, erhält aber normalerweise keinenonAudioFocusChange()
-Callback und verliert den Audiofokus nicht. Mit neuen APIs lässt sich dieses Verhalten bei Anwendungen überschreiben, die anstelle von Ducking pausiert werden müssen. - Wenn der Nutzer einen Anruf annimmt, werden aktive Medien für die Dauer des Anrufs stummgeschaltet.
- Alle audiobezogenen APIs sollten
AudioAttributes
anstelle von Audiostreamtypen verwenden, um den Anwendungsfall für die Audiowiedergabe zu beschreiben. Audiostreamtypen weiterhin nur für die Lautstärkeregelung verwenden. Andere Verwendungen von Streamtypen funktionieren weiterhin (z. B. dasstreamType
-Argument für den verworfenenAudioTrack
-Konstruktor), das System protokolliert dies jedoch als Fehler. - Wenn die Anwendung bei Verwendung eines
AudioTrack
einen ausreichend großen Audiozwischenspeicher anfordert, versucht das Framework, die tiefe Zwischenspeicherausgabe zu verwenden, sofern verfügbar. - In Android 8.0 (API-Level 26) werden Ereignisse für Medienschaltflächen anders verarbeitet:
- Die Verarbeitung von Medienschaltflächen in einer UI-Aktivität bleibt unverändert: Vordergrundaktivitäten haben bei der Verarbeitung von Medienschaltflächenereignissen weiterhin Vorrang.
- Wenn die Aktivität im Vordergrund das Medienschaltflächenereignis nicht verarbeitet, leitet das System das Ereignis an die App weiter, die zuletzt Audio lokal wiedergegeben hat. Der aktive Status, die Flags und der Wiedergabestatus einer Mediensitzung werden nicht berücksichtigt, wenn ermittelt wird, welche App Medienschaltflächenereignisse empfängt.
- Wenn die Mediensitzung der App veröffentlicht wurde, sendet das System das Medienschaltflächenereignis an
MediaButtonReceiver
, sofern vorhanden. - In allen anderen Fällen verwirft das System das Medienschaltflächenereignis.
Native Bibliotheken
In Apps, die auf Android 8.0 (API-Level 26) ausgerichtet sind, werden native Bibliotheken nicht mehr geladen, wenn sie Ladesegmente enthalten, die sowohl beschreibbar als auch ausführbar sind. Einige Anwendungen funktionieren aufgrund dieser Änderung möglicherweise nicht mehr, wenn sie native Bibliotheken mit falschen Ladesegmenten haben. Dies ist eine Maßnahme, um die Sicherheit zu erhöhen.
Weitere Informationen finden Sie unter Beschreibbare und ausführbare Segmente.
Änderungen an der Verknüpfung sind an das API-Level gebunden, auf das eine App ausgerichtet ist. Wird eine Verknüpfungsänderung auf Ziel-API-Ebene vorgenommen, kann die Anwendung die Bibliothek nicht laden. Wenn Sie Ihre Anzeigen auf eine API-Ebene ausrichten, die niedriger ist als die API-Ebene, auf der die Verknüpfungsänderung erfolgt, zeigt Logcat eine Warnung an.
Umgang mit Sammlungen
In Android 8.0 (API-Level 26) wird Collections.sort()
zusätzlich zu List.sort()
implementiert. In Android 7.x (API-Level 24 und 25) galt das umgekehrte Ergebnis: Die Standardimplementierung von List.sort()
mit dem Namen Collections.sort()
.
Durch diese Änderung kann Collections.sort()
von optimierten List.sort()
-Implementierungen profitieren. Dabei gelten jedoch folgende Einschränkungen:
Implementierungen von
List.sort()
dürfenCollections.sort()
nicht aufrufen, da dies zu einem Stacküberlauf aufgrund unendlicher Rekursion führen würde. Wenn Sie das Standardverhalten in IhrerList
-Implementierung verwenden möchten, sollten Siesort()
nicht überschreiben.Wenn eine übergeordnete Klasse
sort()
auf unangemessene Weise implementiert, kannList.sort()
in der Regel mit einer Implementierung überschrieben werden, die aufList.toArray()
,Arrays.sort()
undListIterator.set()
basiert. Beispiele:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
In den meisten Fällen kannst du
List.sort()
auch mit einer Implementierung überschreiben, die je nach API-Ebene an verschiedene Standardimplementierungen delegiert. Beispiele:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
Wenn Sie Letzteres nur durchführen möchten, um eine
sort()
-Methode auf allen API-Ebenen verfügbar zu haben, sollten Sie ihr einen eindeutigen Namen wiesortCompat()
geben, anstattsort()
zu überschreiben.-
Collections.sort()
gilt jetzt als strukturelle Änderung in Listenimplementierungen, diesort()
aufrufen. In Versionen der Plattform vor Android 8.0 (API-Ebene 26) hätte beispielsweise eine Iteration über einArrayList
und das Aufrufen vonsort()
innerhalb der Iteration einConcurrentModificationException
ausgelöst, wenn die Sortierung durch Aufrufen vonList.sort()
erfolgte.Collections.sort()
hat keine Ausnahme ausgelöst.Durch diese Änderung wird das Plattformverhalten einheitlicher: Jeder Ansatz führt jetzt zu einem
ConcurrentModificationException
.
Verhalten beim Laden von Klassen
Android 8.0 (API-Level 26) prüft, ob Klassenlader die Annahmen der Laufzeit beim Laden neuer Klassen nicht durcheinanderbringen. Diese Prüfungen werden durchgeführt, unabhängig davon, ob die Klasse in Java (von forName()
), Davik-Bytecode oder JNI referenziert wird. Die Plattform fängt weder direkte Aufrufe von Java an die Methode loadClass()
noch die Ergebnisse solcher Aufrufe ab. Dieses Verhalten sollte sich nicht auf die Funktionsweise von gut funktionierenden Klassenladeprogrammen auswirken.
Die Plattform prüft, ob der Deskriptor der Klasse, den das Klassenladeprogramm zurückgibt, mit dem erwarteten Deskriptor übereinstimmt. Wenn der zurückgegebene Deskriptor nicht übereinstimmt, gibt die Plattform den Fehler NoClassDefFoundError
aus und speichert in der Ausnahme eine detaillierte Nachricht, in der die Abweichung angegeben ist.
Die Plattform prüft außerdem, ob die Deskriptoren der angeforderten Klassen gültig sind. Mit dieser Prüfung werden JNI-Aufrufe abgefangen, die Klassen wie GetFieldID()
indirekt laden und ungültige Deskriptoren an diese Klassen übergeben. Beispielsweise wurde ein Feld mit der Signatur java/lang/String
nicht gefunden, weil die Signatur ungültig ist. Sie sollte Ljava/lang/String;
lauten.
Dies unterscheidet sich von einem JNI-Aufruf an FindClass()
, bei dem java/lang/String
ein gültiger, voll qualifizierter Name ist.
Android 8.0 (API-Level 26) unterstützt nicht, dass mehrere Klassenladeprogramme versuchen, Klassen mit demselben DexFile-Objekt zu definieren. Andernfalls gibt die Android-Laufzeit den Fehler InternalError
mit der Meldung „Versuch, die Dex-Datei <filename>
mit mehreren Klassenladegeräten zu registrieren“ aus.
Die DexFile API wurde eingestellt. Es wird dringend empfohlen, stattdessen einen der Klassenladeprogramme der Plattform zu verwenden, einschließlich PathClassLoader
oder BaseDexClassLoader
.
Hinweis: Sie können mehrere Klassenladeprogramme erstellen, die auf denselben APK- oder JAR-Dateicontainer aus dem Dateisystem verweisen. Das führt normalerweise nicht zu einem großen Speicheraufwand: Wenn DEX-Dateien im Container gespeichert und nicht komprimiert sind, kann die Plattform einen mmap
-Vorgang auf ihnen ausführen, anstatt sie direkt zu extrahieren. Wenn die Plattform jedoch die DEX-Datei aus dem Container extrahieren muss, kann ein Verweis auf eine DEX-Datei auf diese Weise viel Arbeitsspeicher verbrauchen.
Bei Android gelten alle Klassenladeprogramme als parallel-fähig. Wenn mehrere Threads im Rennen um dieselbe Klasse mit demselben Klassenladeprogramm laufen, gewinnt der erste Thread, der den Vorgang abgeschlossen hat. Das Ergebnis wird für die anderen Threads verwendet. Dieses Verhalten ist unabhängig davon, ob das Klassenladeprogramm dieselbe Klasse, eine andere Klasse oder eine Ausnahme zurückgegeben hat. Die Plattform ignoriert solche Ausnahmen automatisch.
Achtung : In Versionen der Plattform vor Android 8.0 (API-Level 26) kann das Fehlen dieser Annahmen dazu führen, dass dieselbe Klasse mehrmals definiert wird, Heap-Beschädigungen aufgrund von Klassenverwirrungen und andere unerwünschte Auswirkungen auftreten.