Verhaltensänderungen unter Android 7.0

Neben neuen Funktionen und Fähigkeiten enthält Android 7.0 eine Vielzahl von Änderungen am System- und API-Verhalten. In diesem Dokument werden einige der wichtigsten Änderungen hervorgehoben, die Sie kennen und in Ihren Apps berücksichtigen sollten.

Wenn Sie bereits eine App für Android veröffentlicht haben, kann diese von diesen Änderungen an der Plattform betroffen sein.

Akku und Arbeitsspeicher

Android 7.0 enthält Änderungen am Systemverhalten, die die Akkulaufzeit von Geräten verbessern und die RAM-Nutzung reduzieren sollen. Diese Änderungen können sich auf den Zugriff Ihrer App auf Systemressourcen sowie auf die Interaktion Ihrer App über bestimmte implizite Intents mit anderen Apps auswirken.

Stromsparmodus

Der in Android 6.0 (API-Level 23) eingeführte Ruhemodus verbessert die Akkulaufzeit, indem CPU- und Netzwerkaktivitäten verschoben werden, wenn ein Nutzer ein Gerät nicht nutzt, es nicht angeschlossen ist und das Display ausgeschaltet ist. Android 7.0 bietet weitere Verbesserungen für den Ruhemodus, indem eine Teilmenge der CPU- und Netzwerkeinschränkungen angewendet wird, wenn das Gerät nicht angeschlossen ist, das Display ausgeschaltet ist, es aber nicht unbedingt stationär ist, z. B. wenn sich ein Smartphone in der Tasche eines Nutzers befindet.

Illustration, wie der Stromsparmodus eine erste Ebene von Einschränkungen für Systemaktivitäten anwendet, um die Akkulaufzeit zu verbessern

Abbildung 1. Abbildung, die zeigt, wie Doze eine erste Ebene von Einschränkungen der Systemaktivität zur Verbesserung der Akkulaufzeit anwendet

Wenn ein Gerät mit Akku betrieben wird und das Display eine bestimmte Zeit lang aus war, wechselt es in den Ruhemodus und die erste Gruppe von Einschränkungen wird angewendet: Der Netzwerkzugriff für Apps wird deaktiviert und Jobs und Synchronisierungen werden verschoben. Wenn sich das Gerät nach dem Eintritt in den Ruhemodus eine bestimmte Zeit lang nicht bewegt, werden die restlichen Einschränkungen des Ruhemodus auf PowerManager.WakeLock, AlarmManager-Wecker, GPS und WLAN-Scans angewendet. Unabhängig davon, ob einige oder alle Doze-Einschränkungen angewendet werden, weckt das System das Gerät für kurze Wartungsfenster, in denen Anwendungen den Netzwerkzugriff erhalten und alle verschobenen Jobs/Synchronisierungen ausführen können.

Illustration, wie der Stromsparmodus eine zweite Ebene von Systemaktivitätsbeschränkungen anwendet, nachdem das Gerät eine bestimmte Zeit lang inaktiv war

Abbildung 2. Abbildung, wie Doze eine zweite Ebene von Einschränkungen der Systemaktivität anwendet, nachdem das Gerät eine bestimmte Zeit lang inaktiv war.

Wenn Sie den Bildschirm einschalten oder das Gerät anschließen, wird der Ruhemodus beendet und diese Verarbeitungseinschränkungen werden aufgehoben. Das zusätzliche Verhalten hat keine Auswirkungen auf die Empfehlungen und Best Practices zur Anpassung Ihrer App an die vorherige Version von Doze, die in Android 6.0 (API-Level 23) eingeführt wurde. Weitere Informationen finden Sie unter Optimierung für Doze und App-Standby. Sie sollten diese Empfehlungen trotzdem befolgen und beispielsweise Firebase Cloud Messaging (FCM) zum Senden und Empfangen von Nachrichten verwenden und mit der Planung von Aktualisierungen beginnen, um dem zusätzlichen Stromsparverhalten Rechnung zu tragen.

Project Svelte: Hintergrundoptimierungen

In Android 7.0 wurden drei implizite Broadcasts entfernt, um sowohl die Arbeitsspeichernutzung als auch den Energieverbrauch zu optimieren. Diese Änderung ist erforderlich, da durch implizite Übertragungen häufig Apps gestartet werden, die sich im Hintergrund für die Übertragung registriert haben. Das Entfernen dieser Übertragungen kann sich erheblich auf die Geräteleistung und Nutzerfreundlichkeit auswirken.

Bei Mobilgeräten kommt es häufig zu Verbindungsänderungen, z. B. wenn zwischen WLAN und mobilen Daten gewechselt wird. Derzeit können Apps Änderungen bei der Konnektivität überwachen, indem sie in ihrem Manifest einen Empfänger für die implizite CONNECTIVITY_ACTION-Ausstrahlung registrieren. Da sich viele Apps für den Empfang dieser Übertragung registrieren, kann ein einzelner Netzwerk-Switch dazu führen, dass alle Apps gleichzeitig aktiviert und die Übertragung verarbeitet werden.

In früheren Android-Versionen konnten sich Apps auch registrieren, um implizite ACTION_NEW_PICTURE- und ACTION_NEW_VIDEO-Broadcasts von anderen Apps wie der Kamera zu empfangen. Wenn ein Nutzer ein Foto mit der Kamera App aufnimmt, werden diese Apps aktiviert, um die Übertragung zu verarbeiten.

Um diese Probleme zu beheben, werden in Android 7.0 die folgenden Optimierungen angewendet:

Wenn Ihre App einen dieser Intents verwendet, sollten Sie die Abhängigkeiten so schnell wie möglich entfernen, damit Sie Ihre App richtig auf Android 7.0-Geräte ausrichten können. Das Android-Framework bietet mehrere Lösungen, um die Notwendigkeit dieser impliziten Übertragungen zu verringern. Die JobScheduler API bietet beispielsweise einen robusten Mechanismus zum Planen von Netzwerkvorgängen, wenn bestimmte Bedingungen erfüllt sind, z. B. eine Verbindung zu einem unbegrenzten Netzwerk. Mit JobScheduler kannst du sogar auf Änderungen bei Contentanbietern reagieren.

Weitere Informationen zu Hintergrundoptimierungen in Android 7.0 (API-Level 24) und zur Anpassung Ihrer App finden Sie unter Hintergrundoptimierungen.

Berechtigungsänderungen

Android 7.0 enthält Änderungen an Berechtigungen, die sich auf Ihre App auswirken können.

Änderungen an Dateisystemberechtigungen

Um die Sicherheit privater Dateien zu verbessern, hat der Zugriff auf das private Verzeichnis von Apps, die auf Android 7.0 oder höher ausgerichtet sind, eingeschränkten Zugriff (0700). Diese Einstellung verhindert den Verlust von Metadaten privater Dateien, z. B. deren Größe oder Existenz. Diese Berechtigungsänderung hat mehrere Nebenwirkungen:

Dateien zwischen Apps teilen

Bei Apps, die auf Android 7.0 ausgerichtet sind, erzwingt das Android-Framework die StrictMode API-Richtlinie, die die Freigabe von file://-URIs außerhalb Ihrer App verbietet. Wenn ein Intent mit einem Datei-URI Ihre App verlässt, schlägt die App mit einer FileUriExposedException-Ausnahme fehl.

Wenn Sie Dateien zwischen Anwendungen freigeben möchten, sollten Sie einen content://-URI senden und eine temporäre Zugriffsberechtigung für den URI gewähren. Am einfachsten gewähren Sie diese Berechtigung mit der Klasse FileProvider. Weitere Informationen zu Berechtigungen und zur Freigabe von Dateien finden Sie im Hilfeartikel Dateien freigeben.

Verbesserte Bedienungshilfen

Android 7.0 enthält Änderungen, die die Nutzerfreundlichkeit der Plattform für Nutzer mit eingeschränktem Sehvermögen verbessern sollen. Im Allgemeinen sollten diese Änderungen keine Codeänderungen in deiner App erfordern. Du solltest diese Funktion jedoch überprüfen und mit deiner App testen, um mögliche Auswirkungen auf die Nutzerfreundlichkeit zu bewerten.

Bildschirmzoom

Unter Android 7.0 können Nutzer die Anzeigegröße festlegen, mit der alle Elemente auf dem Bildschirm vergrößert oder verkleinert werden. Dadurch wird die Barrierefreiheit des Geräts für Nutzer mit eingeschränktem Sehvermögen verbessert. Nutzer können den Bildschirm nicht über eine Mindestbildschirmbreite von sw320dp hinaus zoomen. Diese entspricht der Breite des Nexus 4, einem gängigen mittelgroßen Smartphone.

Bildschirm mit der nicht herangezoomten Displaygröße eines Geräts mit einem Android 7.0-System-Image
Bildschirm, der die Auswirkungen der Vergrößerung der Displaygröße eines Geräts mit einem Android 7.0-System-Image zeigt

Abbildung 3 Auf dem rechten Bildschirm ist die Wirkung der Vergrößerung der Displaygröße eines Geräts mit einem Android 7.0-System-Image zu sehen.

Wenn sich die Gerätedichte ändert, benachrichtigt das System ausgeführte Apps so:

  • Wenn eine App auf API-Level 23 oder niedriger ausgerichtet ist, werden alle Hintergrundprozesse automatisch vom System beendet. Wenn ein Nutzer also von einer solchen App zum Bildschirm Einstellungen wechselt und die Einstellung Displaygröße ändert, wird die App vom System genauso beendet wie bei wenig Arbeitsspeicher. Wenn die App Prozesse im Vordergrund hat, benachrichtigt das System diese Prozesse über die Konfigurationsänderung, wie unter Laufzeitänderungen verarbeiten beschrieben, so, als ob die Ausrichtung des Geräts geändert worden wäre.
  • Wenn eine App auf Android 7.0 ausgerichtet ist, werden alle Prozesse (Vor- und Hintergrund) über die Konfigurationsänderung benachrichtigt, wie unter Umgang mit Laufzeitänderungen beschrieben.

Bei den meisten Apps müssen keine Änderungen vorgenommen werden, um diese Funktion zu unterstützen, sofern die Apps den Android-Best Practices entsprechen. Prüfen Sie Folgendes:

  • Testen Sie Ihre App auf einem Gerät mit einer Bildschirmbreite von sw320dp und achten Sie darauf, dass sie ordnungsgemäß funktioniert.
  • Wenn sich die Gerätekonfiguration ändert, aktualisieren Sie alle dichteabhängigen im Cache gespeicherten Informationen, z. B. Bitmaps oder Ressourcen, die aus dem Netzwerk geladen werden. Prüfen Sie, ob Konfigurationsänderungen vorgenommen wurden, wenn die App nach der Pause fortgesetzt wird.

    Hinweis:Wenn Sie konfigurationsabhängige Daten im Cache speichern, sollten Sie relevante Metadaten wie die entsprechende Bildschirmgröße oder Pixeldichte für diese Daten angeben. Wenn Sie diese Metadaten speichern, können Sie entscheiden, ob Sie die im Cache gespeicherten Daten nach einer Konfigurationsänderung aktualisieren müssen.

  • Vermeiden Sie die Angabe von Abmessungen in Pixel, da diese nicht mit der Bildschirmdichte skaliert werden. Geben Sie sie stattdessen mit dichteunabhängigen Pixeleinheiten (dp) an.

Einstellungen für Sehbehinderte im Einrichtungsassistenten

Unter Android 7.0 finden Sie auf dem Begrüßungsbildschirm Einstellungen für Sehbehinderte, über die Nutzer auf einem neuen Gerät die folgenden Einstellungen für Bedienungshilfen einrichten können: Vergrößerungsbewegung, Schriftgröße, Anzeigegröße und TalkBack. Durch diese Änderung werden Fehler, die mit unterschiedlichen Bildschirmeinstellungen zusammenhängen, besser sichtbar. Um die Auswirkungen dieser Funktion zu beurteilen, sollten Sie Ihre Apps mit aktivierten Einstellungen testen. Sie finden die Einstellungen unter Einstellungen > Bedienungshilfen.

Verknüpfung von NDK-Apps mit Plattformbibliotheken

Ab Android 7.0 verhindert das System, dass Apps dynamisch mit Bibliotheken ohne NDK verknüpft werden, was zum Absturz deiner App führen kann. Ziel dieser Verhaltensänderung ist es, die Nutzung von Apps über Plattformupdates und verschiedene Geräte hinweg einheitlich zu gestalten. Auch wenn Ihr Code möglicherweise nicht mit privaten Bibliotheken verknüpft ist, kann dies bei einer statischen Bibliothek eines Drittanbieters in Ihrer App der Fall sein. Daher sollten alle Entwickler prüfen, ob ihre Apps auf Geräten mit Android 7.0 nicht abstürzen. Wenn Ihre App nativen Code verwendet, sollten Sie nur öffentliche NDK APIs verwenden.

Es gibt drei Möglichkeiten, wie Ihre App versucht, auf private Plattform-APIs zuzugreifen:

  • Ihre App greift direkt auf private Plattformbibliotheken zu. Sie sollten Ihre Anwendung so aktualisieren, dass sie eine eigene Kopie dieser Bibliotheken enthält, oder die öffentlichen NDK APIs verwenden.
  • Ihre App verwendet eine Bibliothek von Drittanbietern, die auf private Plattformbibliotheken zugreift. Auch wenn Sie sicher sind, dass Ihre App nicht direkt auf private Bibliotheken zugreift, sollten Sie Ihre App auf dieses Szenario testen.
  • Ihre App verweist auf eine Bibliothek, die nicht im APK enthalten ist. Das kann beispielsweise passieren, wenn Sie versucht haben, Ihre eigene Kopie von OpenSSL zu verwenden, aber vergessen haben, sie mit dem APK Ihrer App zu bündeln. Die App wird möglicherweise normal auf Versionen der Android-Plattform ausgeführt, die libcrypto.so enthalten. Unter neueren Android-Versionen, die diese Bibliothek nicht enthalten (z. B. Android 6.0 und höher), kann die App jedoch abstürzen. Um dieses Problem zu beheben, müssen Sie alle nicht-NDK-Bibliotheken in Ihr APK einbinden.

Apps sollten keine nativen Bibliotheken verwenden, die nicht im NDK enthalten sind, da sie sich zwischen verschiedenen Android-Versionen ändern oder entfernt werden können. Der Wechsel von OpenSSL zu BoringSSL ist ein Beispiel für eine solche Änderung. Da es keine Kompatibilitätsanforderungen für Plattformbibliotheken gibt, die nicht im NDK enthalten sind, können verschiedene Geräte unterschiedliche Kompatibilitätsstufen bieten.

Um die Auswirkungen dieser Einschränkung auf derzeit veröffentlichte Apps zu verringern, sind einige häufig verwendete Bibliotheken wie libandroid_runtime.so, libcutils.so, libcrypto.so und libssl.so vorübergehend auf Android 7.0 (API-Level 24) für Apps verfügbar, die auf API-Level 23 oder niedriger ausgerichtet sind. Wenn Ihre App eine dieser Bibliotheken lädt, generiert logcat eine Warnung und auf dem Zielgerät wird eine Toast-Benachrichtigung angezeigt. Wenn Sie diese Warnungen sehen, sollten Sie Ihre App aktualisieren, um entweder eine eigene Kopie dieser Bibliotheken einzubinden oder nur die öffentlichen NDK APIs zu verwenden. In zukünftigen Releases der Android-Plattform wird die Verwendung privater Bibliotheken möglicherweise vollständig eingeschränkt und Ihre App stürzt ab.

Alle Apps generieren einen Laufzeitfehler, wenn sie eine API aufrufen, die weder öffentlich noch vorübergehend zugänglich ist. Das Ergebnis ist, dass sowohl System.loadLibrary als auch dlopen(3) NULL zurückgeben und Ihre App möglicherweise zum Absturz bringen. Sie sollten Ihren App-Code prüfen, um die Verwendung privater Plattform-APIs zu entfernen, und Ihre Apps gründlich mit einem Gerät oder Emulator mit Android 7.0 (API-Level 24) testen. Wenn Sie sich nicht sicher sind, ob Ihre App private Bibliotheken verwendet, können Sie logcat prüfen, um den Laufzeitfehler zu ermitteln.

In der folgenden Tabelle wird das Verhalten beschrieben, das Sie bei einer App erwarten können, je nachdem, ob sie private native Bibliotheken verwendet und welches Ziel-API-Level (android:targetSdkVersion) sie hat.

Bibliotheken Ziel-API-Level Laufzeitzugriff über dynamische Verknüpfung Verhalten unter Android 7.0 (API-Ebene 24) Zukünftiges Verhalten der Android-Plattform
NDK öffentlich Gibt es Zugänglich Funktioniert wie erwartet Funktioniert wie erwartet
Privat (vorübergehend zugängliche private Bibliotheken) 23 oder weniger Vorübergehend zugänglich Funktioniert wie erwartet, Sie erhalten jedoch eine Logcat-Warnung. Laufzeitfehler
Privat (vorübergehend zugängliche private Bibliotheken) 24 oder höher Eingeschränkt Laufzeitfehler Laufzeitfehler
Privat (Sonstiges) Gibt es Eingeschränkt Laufzeitfehler Laufzeitfehler

Prüfen, ob Ihre App private Bibliotheken verwendet

Um Probleme beim Laden privater Bibliotheken zu identifizieren, generiert logcat möglicherweise eine Warnung oder einen Laufzeitfehler. Wenn Ihre App beispielsweise auf API-Level 23 oder niedriger ausgerichtet ist und versucht, auf eine private Bibliothek auf einem Gerät mit Android 7.0 zuzugreifen, wird möglicherweise eine Warnung ähnlich der folgenden angezeigt:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

Diese Logcat-Warnungen geben Aufschluss darüber, welche Bibliothek versucht, auf eine private Plattform-API zuzugreifen, führen aber nicht zum Absturz Ihrer App. Wenn die App jedoch auf API-Level 24 oder höher ausgerichtet ist, generiert Logcat den folgenden Laufzeitfehler und deine App kann abstürzen:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)

Diese Logcat-Ausgaben können auch angezeigt werden, wenn Ihre App Drittanbieterbibliotheken verwendet, die dynamisch mit privaten Plattform-APIs verknüpft sind. Mit dem readelf-Tool in Android 7.0DK können Sie eine Liste aller dynamisch verknüpften freigegebenen Bibliotheken einer bestimmten .so-Datei generieren. Dazu führen Sie den folgenden Befehl aus:

aarch64-linux-android-readelf -dW libMyLibrary.so

App aktualisieren

So können Sie diese Art von Fehlern beheben und dafür sorgen, dass Ihre App bei zukünftigen Plattformupdates nicht abstürzt:

  • Wenn Ihre App private Plattformbibliotheken verwendet, sollten Sie sie so aktualisieren, dass sie eine eigene Kopie dieser Bibliotheken enthält, oder die öffentlichen NDK APIs verwenden.
  • Wenn deine App eine Bibliothek eines Drittanbieters verwendet, die auf private Symbole zugreift, wende dich an den Autor der Bibliothek, um sie zu aktualisieren.
  • Achten Sie darauf, dass Sie alle Nicht-NDK-Bibliotheken mit Ihrem APK verpacken.
  • Verwenden Sie standardmäßige JNI-Funktionen anstelle von getJavaVM und getJNIEnv aus libandroid_runtime.so:
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • Verwenden Sie __system_property_get anstelle des privaten property_get-Symbols aus libcutils.so. Dazu verwenden Sie __system_property_get mit Folgendem:
    #include <sys/system_properties.h>

    Hinweis:Verfügbarkeit und Inhalt von Systemeigenschaften werden nicht über CTS geprüft. Besser ist es, diese Properties ganz zu vermeiden.

  • Verwende eine lokale Version des SSL_ctrl-Symbols von libcrypto.so. Sie sollten libcyrpto.a beispielsweise statisch in Ihrer .so-Datei verknüpfen oder eine dynamisch verknüpfte Version von libcrypto.so aus BoringSSL/OpenSSL einschließen und in Ihrem APK verpacken.

Android for Work

Android 7.0 enthält Änderungen für Apps, die auf Android for Work ausgerichtet sind. Dazu gehören Änderungen an der Installation von Zertifikaten, dem Zurücksetzen von Passwörtern, der sekundären Nutzerverwaltung und dem Zugriff auf Gerätekennungen. Wenn Sie Apps für Android for Work-Umgebungen entwickeln, sollten Sie diese Änderungen prüfen und Ihre App entsprechend anpassen.

  • Sie müssen einen delegierten Zertifikats-Installer installieren, bevor der DPC ihn festlegen kann. Für Apps von Profil- und Geräteeigentümern, die auf Android 7.0 (API-Level 24) ausgerichtet sind, sollten Sie das Installationsprogramm für delegierte Zertifikate installieren, bevor der Device Policy Controller (DPC) DevicePolicyManager.setCertInstallerPackage() aufruft. Wenn das Installationsprogramm noch nicht installiert ist, gibt das System eine IllegalArgumentException zurück.
  • Einschränkungen für das Zurücksetzen von Passwörtern für Geräteadministratoren gelten jetzt auch für Profilinhaber. Geräteadministratoren können DevicePolicyManager.resetPassword() nicht mehr verwenden, um Passwörter zu löschen oder bereits festgelegte Passwörter zu ändern. Geräteadministratoren können weiterhin ein Passwort festlegen, aber nur, wenn das Gerät kein Passwort, keine PIN oder kein Muster hat.
  • Geräte- und Profilinhaber können Konten auch dann verwalten, wenn Einschränkungen festgelegt sind. Geräte- und Profilinhaber können die Account Management APIs auch dann aufrufen, wenn DISALLOW_MODIFY_ACCOUNTS-Nutzerbeschränkungen gelten.
  • Geräteeigentümer können sekundäre Nutzer einfacher verwalten. Wenn ein Gerät im Modus „Geräteeigentümer“ ausgeführt wird, wird die Einschränkung DISALLOW_ADD_USER automatisch festgelegt. So wird verhindert, dass Nutzer nicht verwaltete sekundäre Nutzer erstellen. Außerdem werden die Methoden CreateUser() und createAndInitializeUser() eingestellt. Sie werden durch die neue Methode DevicePolicyManager.createAndManageUser() ersetzt.
  • Geräteeigentümer können auf Geräte-IDs zugreifen. Ein Geräteinhaber kann mit DevicePolicyManager.getWifiMacAddress() auf die WLAN-MAC-Adresse eines Geräts zugreifen. Wenn auf dem Gerät noch nie WLAN aktiviert war, gibt diese Methode den Wert null zurück.
  • Mit der Einstellung „Arbeitsmodus“ wird der Zugriff auf geschäftliche Apps gesteuert. Wenn der Arbeitsmodus deaktiviert ist, werden geschäftliche Apps im System-Launcher ausgegraut, um anzuzeigen, dass sie nicht verfügbar sind. Wenn Sie den Arbeitsmodus wieder aktivieren, wird das normale Verhalten wiederhergestellt.
  • Wenn Sie eine PKCS #12-Datei mit einer Clientzertifikatskette und dem entsprechenden privaten Schlüssel über die Einstellungen installieren, wird das CA-Zertifikat in der Kette nicht mehr im Speicher für vertrauenswürdige Anmeldedaten installiert. Das Ergebnis von KeyChain.getCertificateChain() wird dadurch nicht beeinflusst, wenn Apps später versuchen, die Clientzertifikatskette abzurufen. Falls erforderlich, sollte das CA-Zertifikat über die Einstellungs-UI separat im Speicher für vertrauenswürdige Anmeldedaten mit einem DER-codierten Format unter der Dateiendung „.crt“ oder „.cer“ installiert werden.
  • Ab Android 7.0 werden die Registrierung und Speicherung von Fingerabdrücken pro Nutzer verwaltet. Wenn der Device Policy Client (DPC) eines Profilinhabers auf API-Level 23 (oder niedriger) auf einem Gerät mit Android 7.0 (API-Level 24) ausgerichtet ist, kann der Nutzer zwar den Fingerabdruck auf dem Gerät festlegen, geschäftliche Anwendungen können jedoch nicht auf den Fingerabdruck des Geräts zugreifen. Wenn die DPC auf API-Ebene 24 oder höher ausgerichtet ist, kann der Nutzer den Fingerabdruck speziell für das Arbeitsprofil unter Einstellungen > Sicherheit > Sicherheit für Arbeitsprofile festlegen.
  • DevicePolicyManager.getStorageEncryptionStatus() gibt einen neuen Verschlüsselungsstatus ENCRYPTION_STATUS_ACTIVE_PER_USER zurück, um anzugeben, dass die Verschlüsselung aktiv ist und der Verschlüsselungsschlüssel mit dem Nutzer verknüpft ist. Der neue Status wird nur zurückgegeben, wenn der DPC auf API-Level 24 oder höher ausgerichtet ist. Für Anwendungen, die auf frühere API-Ebenen ausgerichtet sind, wird ENCRYPTION_STATUS_ACTIVE zurückgegeben, auch wenn der Verschlüsselungsschlüssel nutzer- oder profilspezifisch ist.
  • Unter Android 7.0 verhalten sich mehrere Methoden, die normalerweise das gesamte Gerät betreffen, anders, wenn auf dem Gerät ein Arbeitsprofil mit einer separaten geschäftlichen Herausforderung installiert ist. Diese Methoden wirken sich nicht auf das gesamte Gerät aus, sondern nur auf das Arbeitsprofil. Eine vollständige Liste dieser Methoden finden Sie in der DevicePolicyManager.getParentProfileInstance()-Dokumentation. DevicePolicyManager.lockNow() sperrt beispielsweise nur das Arbeitsprofil, nicht das gesamte Gerät. Bei jeder dieser Methoden können Sie das alte Verhalten aufrufen, indem Sie die Methode auf der übergeordneten Instanz der DevicePolicyManager aufrufen. Sie können diese übergeordnete Instanz durch Aufrufen von DevicePolicyManager.getParentProfileInstance() abrufen. Wenn Sie beispielsweise die Methode lockNow() der übergeordneten Instanz aufrufen, wird das gesamte Gerät gesperrt.

Bindung durch Anmerkungen

In Android 7.0 wurde ein Fehler behoben, durch den die Sichtbarkeit von Anmerkungen ignoriert wurde. Aufgrund dieses Problems konnte die Laufzeit auf Anmerkungen zugreifen, auf die sie eigentlich keinen Zugriff haben sollte. Zu diesen Anmerkungen gehörten:

  • VISIBILITY_BUILD: Sie sollen nur zur Buildzeit sichtbar sein.
  • VISIBILITY_SYSTEM: Sie sollen zur Laufzeit sichtbar sein, aber nur für das zugrunde liegende System.

Wenn Ihre App auf dieses Verhalten angewiesen ist, fügen Sie Anmerkungen eine Aufbewahrungsrichtlinie hinzu, die zur Laufzeit verfügbar sein muss. Verwenden Sie dazu @Retention(RetentionPolicy.RUNTIME).

Änderungen an der Standardkonfiguration von TLS/SSL

In Android 7.0 wurden die folgenden Änderungen an der Standard-TLS/SSL-Konfiguration vorgenommen, die von Apps für HTTPS und anderen TLS/SSL-Traffic verwendet wird:

  • RC4-Verschlüsselungssammlungen sind jetzt deaktiviert.
  • CHACHA20-POLY1305-Chiffrensammlungen sind jetzt aktiviert.

Wenn RC4 standardmäßig deaktiviert ist, kann es zu Unterbrechungen der HTTPS- oder TLS/SSL-Verbindung kommen, wenn der Server keine modernen Chiffrensammlungen aushandelt. Die bevorzugte Lösung besteht darin, die Serverkonfiguration zu verbessern, um stärkere und modernere Chiffren-Suiten und Protokolle zu aktivieren. Idealerweise sollten TLSv1.2 und AES-GCM aktiviert und Forward Secrecy Cipher Suites (ECDHE) aktiviert und bevorzugt sein.

Alternativ können Sie die App so ändern, dass eine benutzerdefinierte SSLSocketFactory für die Kommunikation mit dem Server verwendet wird. Die Factory sollte so konzipiert sein, dass SSLSocket-Instanzen erstellt werden, bei denen zusätzlich zu den standardmäßigen Cipher Suites einige der für den Server erforderlichen Chiffresammlungen aktiviert sind.

Hinweis:Diese Änderungen betreffen nicht WebView.

Apps für Android 7.0

Diese Verhaltensänderungen gelten ausschließlich für Apps, die auf Android 7.0 (API-Level 24) oder höher ausgerichtet sind. Apps, die für Android 7.0 kompiliert werden oder für targetSdkVersion die Version „Android 7.0 oder höher“ festgelegt haben, müssen entsprechend angepasst werden, um diese Funktionen ordnungsgemäß zu unterstützen.

Änderungen bei der Serialisierung

In Android 7.0 (API-Level 24) wurde ein Fehler bei der Berechnung der Standard-serialVersionUID behoben, der dazu führte, dass sie nicht der Spezifikation entsprach.

Bei Klassen, die Serializable implementieren und kein explizites serialVersionUID-Feld angeben, wird möglicherweise eine Änderung in der serialVersionUID festgestellt. Dies würde dazu führen, dass eine Ausnahme ausgelöst wird, wenn versucht wird, Instanzen der Klasse zu deserialisieren, die in einer früheren Version serialisiert oder von einer Anwendung serialisiert wurden, die auf eine frühere Version abzielt. Die Fehlermeldung sieht in etwa so aus:

local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567

Um diese Probleme zu beheben, müssen Sie jeder betroffenen Klasse das Feld serialVersionUID mit dem Wert stream classdesc serialVersionUID aus der Fehlermeldung hinzufügen, z.B. in diesem Fall 1234. Diese Änderung entspricht allen Best Practices für das Schreiben von Serialization-Code und funktioniert auf allen Android-Versionen.

Der behobene Fehler bezog sich auf das Vorhandensein von statischen Initialisiermethoden, d.h. <clinit>. Gemäß der Spezifikation wirkt sich das Vorhandensein oder Fehlen einer statischen Initialisiermethode in der Klasse auf die für diese Klasse berechnete Standard-serialVersionUID aus. Vor der Fehlerbehebung wurde bei der Berechnung auch die Superklasse auf einen statischen Initializer geprüft, wenn eine Klasse keinen hatte.

Zur Klarstellung: Diese Änderung wirkt sich nicht auf Apps aus, die auf API-Level 23 oder niedriger ausgerichtet sind, auf Klassen mit einem serialVersionUID-Feld oder auf Klassen mit einer statischen Initialisierungsmethode.

Weitere wichtige Punkte

  • Wenn eine App auf Android 7.0 ausgeführt wird, aber auf eine niedrigere API-Ebene ausgerichtet ist, und der Nutzer die Displaygröße ändert, wird der App-Prozess beendet. Die App muss mit diesem Szenario umgehen können. Andernfalls stürzt die App ab, wenn der Nutzer sie aus den letzten Aktivitäten wiederherstellt.

    Sie sollten Ihre App testen, um sicherzustellen, dass dieses Verhalten nicht auftritt. Sie können dies tun, indem Sie einen identischen Absturz verursachen, wenn Sie die App manuell über DDMS beenden.

    Apps, die auf Android 7.0 (API-Level 24) und höher ausgerichtet sind, werden bei Änderungen der Dichte nicht automatisch beendet. Sie reagieren jedoch möglicherweise immer noch schlecht auf Konfigurationsänderungen.

  • Apps unter Android 7.0 sollten Konfigurationsänderungen problemlos verarbeiten und bei nachfolgenden Starts nicht abstürzen. Sie können das App-Verhalten prüfen, indem Sie die Schriftgröße ändern (Einstellungen > Display > Schriftgröße) und die App dann aus den letzten Apps wiederherstellen.
  • Aufgrund eines Fehlers in früheren Android-Versionen hat das System das Schreiben in einen TCP-Socket im Hauptthread nicht als Verstoß gegen den strengen Modus gekennzeichnet. Android 7.0 behebt diesen Fehler. Bei Apps, die dieses Verhalten zeigen, wird jetzt eine android.os.NetworkOnMainThreadException geworfen. Im Allgemeinen ist es keine gute Idee, Netzwerkvorgänge im Hauptthread auszuführen, da diese Vorgänge in der Regel eine hohe Latenz haben, die zu ANRs und Rucklern führt.
  • Die Debug.startMethodTracing()-Methodenfamilie speichert die Ausgabe jetzt standardmäßig im paketspezifischen Verzeichnis im freigegebenen Speicher, nicht mehr auf der obersten Ebene der SD-Karte. Das bedeutet, dass Apps die Berechtigung WRITE_EXTERNAL_STORAGE nicht mehr anfordern müssen, um diese APIs zu verwenden.
  • Viele Plattform-APIs prüfen jetzt auf große Nutzlasten, die über Binder-Transaktionen gesendet werden. Das System wirft TransactionTooLargeExceptions jetzt als RuntimeExceptions zurück, anstatt sie stillschweigend zu protokollieren oder zu unterdrücken. Ein häufiges Beispiel ist das Speichern zu vieler Daten in Activity.onSaveInstanceState(). Dadurch wird von ActivityThread.StopInfo eine RuntimeException geworfen, wenn Ihre App auf Android 7.0 ausgerichtet ist.
  • Wenn eine App Runnable-Aufgaben an eine View sendet und die View nicht mit einem Fenster verknüpft ist, stellt das System die Runnable-Aufgabe mit der View in die Warteschlange. Die Runnable-Aufgabe wird erst ausgeführt, wenn die View mit einem Fenster verknüpft ist. Durch dieses Verhalten werden die folgenden Fehler behoben:
    • Wenn eine App eine View aus einem anderen Thread als dem UI-Thread des Fensters postet, wird die Runnable möglicherweise im falschen Thread ausgeführt.
    • Wenn die Runnable-Aufgabe von einem anderen Thread als einem Looper-Thread gepostet wurde, kann die App die Runnable-Aufgabe freigeben.Runnable
  • Wenn eine App unter Android 7.0 mit der Berechtigung DELETE_PACKAGES versucht, ein Paket zu löschen, das aber von einer anderen App installiert wurde, ist die Bestätigung des Nutzers erforderlich. In diesem Szenario sollten Apps STATUS_PENDING_USER_ACTION als Rückgabestatus erwarten, wenn sie PackageInstaller.uninstall() aufrufen.
  • Der JCA-Anbieter Crypto wurde verworfen, da sein einziger Algorithmus, SHA1PRNG, kryptografisch schwach ist. Apps können SHA1PRNG nicht mehr zum (unsicheren) Ableiten von Schlüsseln verwenden, da dieser Anbieter nicht mehr verfügbar ist. Weitere Informationen finden Sie im Blogpost Security "Crypto" provider deprecated in Android N.