Funktionen und APIs unter Android 8.1

Android 8.1 (API-Level 27) bietet Nutzern und Entwicklern eine Vielzahl neuer Funktionen und Möglichkeiten. In diesem Dokument wird erläutert, was es für Entwickler Neues gibt.

Android Oreo (Go-Edition)

Android Go ist unsere Initiative, die die Android-Nutzung für Milliarden von Menschen auf der ganzen Welt optimiert. Ab Android 8.1 machen wir Android zu einer großartigen Plattform für Einsteigergeräte. Zu den Funktionen der Konfiguration von Android Oreo (Go-Edition) gehören:

  • Speicheroptimierungen: Die Arbeitsspeichernutzung auf der gesamten Plattform wurde verbessert, damit Apps auf Geräten mit maximal 1 GB RAM effizient ausgeführt werden können.
  • Flexible Ausrichtungsoptionen: Neue Konstanten der Hardwarefunktionen, mit denen Sie Ihre Apps über Google Play auf Geräte mit normalem oder niedrigem RAM bereitstellen können.
  • Google Play.Obwohl alle Apps auf Geräten mit Android Oreo (Go-Edition) verfügbar sein werden, bietet Google Play Einblick in Apps, die speziell von Entwicklern optimiert wurden, um Milliarden von Menschen mit der Entwicklung für Milliarden von Nutzern ein großartiges Erlebnis zu bieten.

Wir haben die Richtlinien für Milliarden von Nutzern aktualisiert. Es enthält zusätzliche Informationen zur Optimierung deiner App für Geräte mit Android Oreo (Go-Edition). Für die meisten Entwickler ist es die beste Möglichkeit, sich auf Geräte mit Android Oreo (Go-Edition) vorzubereiten, indem Sie Ihr vorhandenes APK optimieren oder die Funktion für mehrere APKs von Google Play verwenden, um eine Version Ihres APKs auf Geräte mit niedrigem RAM auszurichten. Denken Sie daran, dass eine leichtere und effizientere App für Ihre gesamte Zielgruppe unabhängig vom Gerät genutzt werden kann.

API für neuronale Netzwerke

Die Neural Networks API ermöglicht eine beschleunigte Berechnung und Inferenz von Frameworks für maschinelles Lernen auf dem Gerät wie TensorFlow Lite – die plattformübergreifende ML-Bibliothek für Mobilgeräte von Google – sowie Caffe2 und andere. Im Open-Source-Repository von TensorFlow Lite finden Sie Downloads und Dokumente. TensorFlow Lite arbeitet mit der Neural Networks API, um Modelle wie MobileNets, Inception v3 und Intelligente Antwort effizient auf Ihrem Mobilgerät auszuführen.

Updates des Autofill-Frameworks

Android 8.1 (API-Level 27) bietet mehrere Verbesserungen des Autofill-Frameworks, die Sie in Ihre Apps integrieren können.

Die Klasse BaseAdapter enthält jetzt die Methode setAutofillOptions(), mit der Sie Stringdarstellungen der Werte in einem Adapter bereitstellen können. Dies ist nützlich für Spinner-Steuerelemente, die die Werte in ihren Adaptern dynamisch generieren. Mit der Methode setAutofillOptions() können Sie beispielsweise eine Stringdarstellung der Liste der Jahre bereitstellen, die Nutzer für das Ablaufdatum ihrer Kreditkarte auswählen können. Autofill-Dienste können die Stringdarstellung verwenden, um die Ansichten, für die die Daten erforderlich sind, korrekt auszufüllen.

Darüber hinaus enthält die Klasse AutofillManager die Methode notifyViewVisibilityChanged(View, int, boolean), die Sie aufrufen können, um das Framework über Änderungen der Sichtbarkeit einer Ansicht in einer virtuellen Struktur zu informieren. Es gibt auch eine Überlastung der Methode für nicht virtuelle Strukturen. Bei nicht virtuellen Strukturen müssen Sie das Framework jedoch in der Regel nicht explizit benachrichtigen, da die Methode bereits von der Klasse View aufgerufen wird.

Mit Android 8.1 haben Autofill-Dienste außerdem mehr Möglichkeiten, das Speicherangebot der Benutzeroberfläche anzupassen. Dazu wird CustomDescription and Validator innerhalb von SaveInfo unterstützt.

Benutzerdefinierte Beschreibungen sind nützlich, damit der Autofill-Service verdeutlicht, was gespeichert wird. Wenn auf dem Bildschirm beispielsweise eine Kreditkarte zu sehen ist, könnten dort das Logo der Kreditkartenbank, die letzten vier Ziffern der Kreditkartennummer und die Ablaufnummer angezeigt werden. Weitere Informationen finden Sie in der Klasse CustomDescription.

Mit Validator-Objekten wird verhindert, dass die UI zum Speichern von Autofill-Daten angezeigt wird, wenn die Bedingung des Validators nicht erfüllt ist. Weitere Informationen finden Sie unter der Klasse Validator und ihrer Unterklassen LuhnChecksumValidator und RegexValidator.

Benachrichtigungen

Unter Android 8.1 wurden folgende Änderungen an Benachrichtigungen vorgenommen:

  • Apps können jetzt nur einmal pro Sekunde einen Benachrichtigungston ausgeben. Benachrichtigungstöne, die diese Häufigkeit überschreiten, werden nicht in die Warteschlange gestellt und gehen verloren. Diese Änderung hat keine Auswirkungen auf andere Aspekte des Benachrichtigungsverhaltens. Benachrichtigungen werden weiterhin wie erwartet veröffentlicht.
  • NotificationListenerService und ConditionProviderService werden auf Android-Geräten mit niedrigem RAM, die true zurückgeben, wenn ActivityManager.isLowRamDevice() aufgerufen wird, nicht unterstützt.

EditText aktualisieren

Ab API-Level 27 gibt die Methode EditText.getText() ein Editable zurück. Zuvor wurde ein CharSequence zurückgegeben. Diese Änderung ist abwärtskompatibel, da Editable CharSequence implementiert.

Die Editable-Schnittstelle bietet wertvolle zusätzliche Funktionen. Da Editable beispielsweise auch die Spannable-Schnittstelle implementiert, können Sie Markup auf Inhalte in einer Instanz von EditText anwenden.

Programmatic Safe Browsing-Aktionen

Mithilfe der WebView-Implementierung der Safe Browsing API kann deine Anwendung erkennen, wenn eine Instanz von WebView versucht, eine URL aufzurufen, die Google als bekannte Bedrohung klassifiziert hat. Standardmäßig wird im WebView ein Interstitial angezeigt, das Nutzer vor der bekannten Bedrohung warnt. Auf diesem Bildschirm haben Nutzer die Möglichkeit, die URL trotzdem zu laden oder zu einer vorherigen, sicheren Seite zurückzukehren.

In Android 8.1 können Sie programmatisch definieren, wie Ihre App auf eine bekannte Bedrohung reagiert:

  • Sie können festlegen, ob Ihre App bekannte Bedrohungen an Safe Browsing meldet.
  • Sie können festlegen, dass Ihre App jedes Mal automatisch eine bestimmte Aktion ausführt, z. B. das Zurückkehren zu sicherer Website, wenn sie auf eine URL stößt, die von Safe Browsing als bekannte Bedrohung eingestuft wird.

Hinweis:Für optimalen Schutz vor bekannten Bedrohungen sollten Sie warten, bis Safe Browsing initialisiert ist, bevor Sie die Methode loadUrl() eines WebView-Objekts aufrufen.

Die folgenden Code-Snippets zeigen, wie Sie die WebView-Instanzen Ihrer App anweisen können, nach dem Auftreten einer bekannten Bedrohung immer wieder in Sicherheit zu kommen:

AndroidManifest.xml

<manifest>
    <application>
        ...
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="true" />
    </application>
</manifest>

MyWebActivity.java

Kotlin

private var superSafeWebView: WebView? = null
private var safeBrowsingIsInitialized: Boolean = false

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    superSafeWebView = WebView(this).apply {
        webViewClient = MyWebViewClient()
        safeBrowsingIsInitialized = false
        startSafeBrowsing(this@SafeBrowsingActivity, { success ->
            safeBrowsingIsInitialized = true
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!")
            }
        })
    }
}

Java

private WebView superSafeWebView;
private boolean safeBrowsingIsInitialized;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    superSafeWebView = new WebView(this);
    superSafeWebView.setWebViewClient(new MyWebViewClient());
    safeBrowsingIsInitialized = false;

    superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() {
        @Override
        public void onReceiveValue(Boolean success) {
            safeBrowsingIsInitialized = true;
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!");
            }
        }
    });
}

MyWebViewClient.java

Kotlin

class MyWebViewClient : WebViewClient() {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    override fun onSafeBrowsingHit(
            view: WebView,
            request: WebResourceRequest,
            threatType: Int,
            callback: SafeBrowsingResponse
    ) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true)
        Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show()
    }
}

Java

public class MyWebViewClient extends WebViewClient {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    @Override
    public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
            int threatType, SafeBrowsingResponse callback) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true);
        Toast.makeText(view.getContext(), "Unsafe web page blocked.",
                Toast.LENGTH_LONG).show();
    }
}

Video-Miniaturansicht-Extrahierer

Die Klasse MediaMetadataRetriever hat eine neue Methode, getScaledFrameAtTime(), die einen Frame in der Nähe einer bestimmten Zeitposition findet und eine Bitmap mit demselben Seitenverhältnis wie der Quellframe zurückgibt, aber skaliert, um in ein Rechteck mit einer bestimmten Breite und Höhe zu passen. Dies ist hilfreich, um aus Videos Miniaturansichten zu generieren.

Wir empfehlen, diese Methode anstelle von getFrameAtTime() zu verwenden, da dadurch Arbeitsspeicher verschwendet wird, da eine Bitmap mit derselben Auflösung wie das Quellvideo zurückgegeben wird. Ein Frame aus einem 4K-Video wäre beispielsweise eine 16 MB-Bitmap, also viel größer als für ein Thumbnail-Bild.

Shared Memory API

Mit Android 8.1 (API-Level 27) wird eine neue SharedMemory API eingeführt. Mit dieser Klasse können Sie eine anonyme SharedMemory-Instanz erstellen, zuordnen und verwalten. Sie legen den Arbeitsspeicherschutz für ein SharedMemory-Objekt zum Lesen und/oder Schreiben fest. Da das SharedMemory-Objekt parelable ist, können Sie es einfach über AIDL an einen anderen Prozess übergeben.

Die API SharedMemory interagiert mit der Funktion ASharedMemory im NDK. ASharedMemory gewährt Zugriff auf einen Dateideskriptor, der dann Lese- und Schreibzugriff zugeordnet werden kann. So lassen sich große Datenmengen zwischen Anwendungen oder zwischen mehreren Prozessen innerhalb einer Anwendung teilen.

HintergründeColors-API

Mit Android 8.1 (API-Level 27) können über den Live-Hintergrund Farbinformationen an die System-UI gesendet werden. Dazu erstellst du ein WallpaperColors-Objekt aus einer Bitmap oder einem Drawable oder verwendest drei manuell ausgewählte Farben. Sie können diese Farbinformationen auch abrufen.

So erstellen Sie ein WallpaperColors-Objekt:

  • Um ein WallpaperColors-Objekt mit drei Farben zu erstellen, müssen Sie eine Instanz der WallpaperColors-Klasse erstellen. Dazu übergeben Sie die primäre, sekundäre und tertiäre Farbe. Die Hauptfarbe darf nicht null sein.
  • Wenn Sie ein WallpaperColors-Objekt aus einer Bitmap erstellen möchten, rufen Sie die Methode fromBitmap() auf, indem Sie die Bitmapquelle als Parameter übergeben.
  • Wenn du ein WallpaperColors-Objekt aus einem Drawable erstellen möchtest, rufe die Methode fromDrawable() auf, indem du die Drawable-Quelle als Parameter übergibst.

Rufen Sie die folgenden Methoden auf, um die primären, sekundären oder tertiären Farbdetails aus dem Hintergrund abzurufen:

Wenn du das System über größere Farbänderungen in deinem Live-Hintergrund informieren möchtest, rufe die Methode notifyColorsChanged() auf. Diese Methode löst ein onComputeColors()-Lebenszyklusereignis aus, bei dem Sie die Möglichkeit haben, ein neues WallpaperColors-Objekt anzugeben.

Um einen Listener für Farbänderungen hinzuzufügen, können Sie die Methode addOnColorsChangedListener() aufrufen. Sie können auch die Methode getWallpaperColors() aufrufen, um die Primärfarben eines Hintergrunds abzurufen.

Fingerabdruck-Aktualisierung

Bei der Klasse FingerprintManager wurden folgende Fehlercodes eingeführt:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT: Der Nutzer hat zu oft versucht, sein Gerät mit dem Fingerabdrucklesegerät zu entsperren.
  • FINGERPRINT_ERROR_VENDOR: Ein anbieterspezifischer Fehler beim Fingerabdrucklesegerät ist aufgetreten.

Updates zur Kryptografie

Mit Android 8.1 wurden eine Reihe von Änderungen an der Kryptografie vorgenommen:

  • In Conscrypt wurden neue Algorithmen implementiert. Die Conscrypt-Implementierung wird gegenüber der vorhandenen Bouncy Castle-Implementierung bevorzugt verwendet. Zu den neuen Algorithmen gehören:
    • AlgorithmParameters:GCM
    • KeyGenerator:AES
    • KeyGenerator:DESEDE
    • KeyGenerator:HMACMD5
    • KeyGenerator:HMACSHA1
    • KeyGenerator:HMACSHA224
    • KeyGenerator:HMACSHA256
    • KeyGenerator:HMACSHA384
    • KeyGenerator:HMACSHA512
    • SecretKeyFactory:DESEDE
    • Signature:NONEWITHECDSA
  • Cipher.getParameters().getParameterSpec(IvParameterSpec.class) funktioniert nicht mehr für Algorithmen, die GCM verwenden. Verwenden Sie stattdessen getParameterSpec(GCMParameterSpec.class).
  • Viele interne Conscrypt-Klassen, die mit TLS verknüpft sind, wurden refaktoriert. Da Entwickler manchmal auf diese Elemente zugreifen, wurden Shims zur Unterstützung der vorherigen Nutzung beibehalten, einige Details haben sich jedoch geändert. Früher waren Sockets beispielsweise vom Typ OpenSSLSocketImpl, jetzt sind sie aber vom Typ ConscryptFileDescriptorSocket oder ConscryptEngineSocket, die beide den Typ OpenSSLSocketImpl erweitern.
  • Mit SSLSession-Methoden zum Auslösen von IllegalArgumentException wird bei Übergabe eines Nullverweises jetzt NullPointerException ausgegeben.
  • Der RSA-KeyFactory lässt keine Generierung von Schlüsseln aus Bytearrays mehr zu, die größer als der codierte Schlüssel sind. Aufrufe von generatePrivate() und generatePublic() mit einer KeySpec, bei denen die Schlüsselstruktur nicht den gesamten Zwischenspeicher füllt, führen zu einem InvalidKeySpecException.
  • Wenn ein Socket-Lesevorgang durch den geschlossenen Socket unterbrochen wird, gab Conscrypt vom Lesevorgang -1 zurück. Der Lesevorgang gibt jetzt SocketException aus.
  • Der Satz von Root-CA-Zertifikaten wurde geändert. Dabei wurden zumeist zahlreiche veraltete Zertifikate entfernt. Gleichzeitig wurden aber auch die Root-Zertifikate für WoSign und StartCom entfernt. Weitere Informationen zu dieser Entscheidung finden Sie im Google Security-Blogpost Finale Removal of Trust in WoSign and StartCom Certificates.