APIs unter Android 4.3

API-Level: 18

Android 4.3 (JELLY_BEAN_MR2) ist ein Update für die Jelly Bean-Version, das neue Funktionen für Nutzer und die App bietet. zu entwickeln. In diesem Dokument finden Sie eine Einführung in die wichtigsten neuen APIs.

Als App-Entwickler sollten Sie das Android 4.3-System-Image und die SDK-Plattform so bald wie möglich über den SDK Manager herunterladen. Wenn du kein Gerät mit Android 4.3 hast, auf dem du App testen, Android 4.3-System verwenden um Ihre App im Android Emulator zu testen. Entwickeln Sie dann Ihre Apps für die Android 4.3-Plattform, um die die neuesten APIs.

Ziel-API-Level aktualisieren

Wenn Sie Ihre App für Geräte mit Android 4.3 optimieren möchten, sollten Sie targetSdkVersion auf "18" festlegen, sie auf einem Android 4.3-System-Image installieren, testen und dann ein Update mit dieser Änderung veröffentlichen.

Sie können APIs in Android 4.3 verwenden und gleichzeitig ältere Versionen unterstützen, indem Sie Ihrem Code Bedingungen hinzufügen, die die System-API-Ebene prüfen, bevor APIs ausgeführt werden, die von Ihrer minSdkVersion nicht unterstützt werden. Weitere Informationen zur Aufrechterhaltung der Abwärtskompatibilität finden Sie unter Unterstützung verschiedener Plattformversionen.

In der Android Support Library finden Sie verschiedene APIs, mit denen Sie neuen Funktionen in älteren Versionen der Plattform.

Weitere Informationen zur Funktionsweise von API-Ebenen finden Sie unter Was ist eine API? Stufe?

Wichtige Verhaltensänderungen

Wenn Sie bereits eine App für Android veröffentlicht haben, kann es sein, dass sich die Änderungen in Android 4.3 auf Ihre App auswirken.

Wenn Ihre App implizite Intents verwendet...

Ihre App verhält sich möglicherweise in einer Umgebung mit eingeschränktem Profil nicht wie erwartet.

Nutzer in einer Umgebung mit eingeschränkten Profilen alle Android-Standard-Apps zur Verfügung stehen. In einem eingeschränkten Profil können beispielsweise der Webbrowser und die Kamera-App deaktiviert sein. Ihre App sollte also keine Annahmen darüber treffen, welche Apps verfügbar, denn wenn du startActivity() anrufst, ohne um zu prüfen, ob eine App zur Verarbeitung der Intent, kann deine App in einem eingeschränkten Profil abstürzen.

Wenn Sie einen impliziten Intent verwenden, sollten Sie immer durch Aufrufen von resolveActivity() oder queryIntentActivities() prüfen, ob eine App für die Verarbeitung des Intents verfügbar ist. Beispiel:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

Wenn Ihre App von Konten abhängig ist:

Ihre App verhält sich möglicherweise in einer eingeschränkten Profilumgebung zu Unrecht.

Nutzer in einer eingeschränkten Profilumgebung haben standardmäßig keinen Zugriff auf Nutzerkonten. Wenn deine App von einem Account abhängig ist, kann sie abstürzen oder sich verhalten wenn er in einem eingeschränkten Profil verwendet wird.

Wenn Sie gänzlich verhindern möchten, dass eingeschränkte Profile Ihre Anwendung nutzen, App von vertraulichen Kontoinformationen abhängt, geben Sie das Attribut android:requiredAccountType in der <application> Ihres Manifests an -Elements.

Wenn Sie eingeschränkten Profilen erlauben möchten, Ihre App weiterhin zu verwenden, obwohl sie dies nicht können eigene Konten erstellen, können Sie dann entweder Ihre App-Funktionen deaktivieren, für die ein Konto erforderlich ist oder eingeschränkten Profilen den Zugriff auf die vom primären Nutzer erstellten Konten erlauben. Weitere Informationen finden Sie unten im Abschnitt Unterstützung von Konten in einem eingeschränkten Profil.

Wenn Ihre App VideoView verwendet…

Unter Android 4.3 wird dein Video möglicherweise kleiner angezeigt.

In früheren Android-Versionen wurde im VideoView-Widget der "wrap_content"-Wert für layout_height und layout_width fälschlicherweise als identisch mit "match_parent" berechnet. Wenn Sie also bisher "wrap_content" für die Höhe oder Breite verwendet haben, um das gewünschte Videolayout zu erhalten, kann dies unter Android 4.3 und höher zu einem viel kleineren Video führen. Um das Problem zu beheben, "wrap_content" mit "match_parent" und bestätige, dass dein Video wie erwartet auf angezeigt wird Android 4.3 sowie ältere Versionen.

Eingeschränkte Profile

Auf Android-Tablets können Nutzer jetzt eingeschränkte Profile auf Grundlage des Hauptnutzers erstellen. Wenn Nutzer ein eingeschränktes Profil erstellen, können sie einschränken, welche Apps die für das Profil verfügbar sind. Mit einer neuen Reihe von APIs in Android 4.3 können Sie außerdem detailliertere Einschränkungen für die von Ihnen entwickelten Apps festlegen. Mit den neuen APIs können Sie beispielsweise Nutzern erlauben, festzulegen, welche Art von Inhalten in Ihrer App verfügbar ist, wenn sie in einer Umgebung mit eingeschränktem Profil ausgeführt wird.

Die Benutzeroberfläche, über die Nutzer die von Ihnen erstellten Einschränkungen steuern können, wird vom System Einstellungen. Damit die Einschränkungseinstellungen Ihrer App für den Nutzer angezeigt werden, müssen Sie die von Ihrer App bereitgestellten Einschränkungen deklarieren. Erstellen Sie dazu eine BroadcastReceiver, die die ACTION_GET_RESTRICTION_ENTRIES-Intent empfängt. Das System ruft diesen Intent auf, um eine Abfrage durchzuführen alle Apps für verfügbare Einschränkungen und erstellt dann die Benutzeroberfläche so, dass der Hauptnutzer Einschränkungen für jedes eingeschränkte Profil verwalten.

In der onReceive()-Methode Ihrer BroadcastReceiver müssen Sie für jede Einschränkung, die Ihre App bietet, eine RestrictionEntry erstellen. Jede RestrictionEntry definiert einen Titel, eine Beschreibung und eines der folgenden Datentypen:

  • TYPE_BOOLEAN für eine Einschränkung, die entweder wahr oder falsch ist.
  • TYPE_CHOICE für eine Einschränkung mit mehreren Optionen, die sich gegenseitig ausschließen (Optionsfelder).
  • TYPE_MULTI_SELECT für eine Einschränkung mit mehreren Optionen, die sich nicht gegenseitig ausschließen (Auswahlkästchen).

Dann fügen Sie alle RestrictionEntry-Objekte in ein ArrayList-Objekt ein und fügen es dem Ergebnis des Broadcast-Empfängers als Wert für den EXTRA_RESTRICTIONS_LIST extra.

Das System erstellt in der App „Einstellungen“ die Benutzeroberfläche für die Einschränkungen deiner App und speichert sie Einschränkung durch den eindeutigen Schlüssel, den Sie für jede RestrictionEntry angegeben haben -Objekt enthält. Wenn der Nutzer Ihre App öffnet, können Sie alle aktuellen Einschränkungen abfragen, indem Sie getApplicationRestrictions() wird angerufen. Dadurch wird ein Bundle zurückgegeben, das die Schlüssel/Wert-Paare für jede Einschränkung enthält. die Sie mit den RestrictionEntry-Objekten definiert haben.

Wenn Sie spezifischere Einschränkungen vorgeben möchten, die nicht mit booleschen, einfachen Auswahl- und Multi-Choice-Werte, dann können Sie eine Aktivität erstellen, in der die Nutzenden und Nutzern erlauben, diese Aktivität über die Einschränkungseinstellungen zu öffnen. Fügen Sie in Ihrem Broadcast-Empfänger das zusätzliche EXTRA_RESTRICTIONS_INTENT in das Ergebnis Bundle ein. Dieses Extra muss eine Intent angeben, die die zu startende Activity-Klasse angibt. Verwenden Sie die Methode putParcelable(), um EXTRA_RESTRICTIONS_INTENT mit der Absicht zu übergeben. Wenn der Hauptnutzer Ihre Aktivitäten eingibt, um benutzerdefinierte Einschränkungen festzulegen, muss die Aktivität dann ein Ergebnis zurückgeben, das die Einschränkungswerte in einem Extra-Element enthält, indem entweder den Schlüssel EXTRA_RESTRICTIONS_LIST oder EXTRA_RESTRICTIONS_BUNDLE, je nachdem, ob Sie RestrictionEntry-Objekte bzw. Schlüssel/Wert-Paare.

Konten in einem eingeschränkten Profil unterstützen

Alle Konten, die dem Hauptnutzer hinzugefügt wurden, sind für ein eingeschränktes Profil verfügbar. Standardmäßig ist der Zugriff auf die Konten jedoch nicht über die AccountManager APIs möglich. Wenn Sie versuchen, ein Konto mit AccountManager hinzuzufügen, erhalten Sie ein Fehlerergebnis. Aufgrund dieser Einschränkungen gilt für Sie Folgendes: drei Optionen:

  • Zugriff auf die Konten des Inhabers über ein eingeschränktes Profil erlauben.

    Wenn Sie von einem eingeschränkten Profil Zugriff auf ein Konto erhalten möchten, müssen Sie dem <application>-Tag das Attribut android:restrictedAccountType hinzufügen:

    <application ...
        android:restrictedAccountType="com.example.account.type" >

    Achtung: Wenn Sie dieses Attribut aktivieren, erhält Ihre App Zugriff auf die Konten des Hauptnutzers über eingeschränkte Profile. Sie sollten dies also nur zulassen, wenn die von Ihrer App angezeigten Informationen keine personenidentifizierbaren Informationen enthalten, die als vertraulich eingestuft werden. In den Systemeinstellungen wird der Hauptnutzer darüber informiert, dass Ihre App seinen Konten eingeschränkte Profile gewährt. Daher sollte ihm klar sein, dass der Kontozugriff für die Funktionalität Ihrer App wichtig ist. Wenn möglich, sollten Sie auch geeignete Einschränkungen für den Hauptnutzer festlegen, die definieren, wie viel Kontozugriff in Ihrer App zulässig ist.

  • Wenn Konten nicht geändert werden können, deaktivieren Sie bestimmte Funktionen.

    Wenn Sie Konten verwenden möchten, diese aber nicht als primäres Konto Ihrer App benötigen, können Sie die Kontoverfügbarkeit prüfen und Funktionen deaktivieren, wenn diese nicht verfügbar sind. Prüfen Sie zuerst, ob ein Konto vorhanden ist. Ist dies nicht der Fall, fragen Sie nach, Sie können ein neues Konto erstellen, indem Sie getUserRestrictions() aufrufen und DISALLOW_MODIFY_ACCOUNTS im Ergebnis prüfen. Wenn es true ist, sollten Sie alle Funktionen Ihrer App deaktivieren, für die Zugriff auf Konten erforderlich ist. Beispiel:

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    Hinweis:In diesem Szenario sollten Sie nicht erklären, alle neuen Attribute in Ihrer Manifestdatei.

  • Deaktivieren Sie Ihre App, wenn Sie nicht auf private Konten zugreifen können.

    Wenn es stattdessen wichtig ist, dass Ihre App nicht für eingeschränkte Profile verfügbar ist, Ihre Anwendung von vertraulichen personenbezogenen Daten in einem Konto abhängt (und weil eingeschränkte Profile kann derzeit keine neuen Konten hinzugefügt werden). Das Attribut android:requiredAccountType zum <application>-Tag:

    <application ...
        android:requiredAccountType="com.example.account.type" >

    Die Gmail App verwendet dieses Attribut beispielsweise, um sich für eingeschränkte Profile zu deaktivieren, da die private E-Mail-Adresse des Inhabers für eingeschränkte Profile nicht verfügbar sein sollte.

  • Drahtlose Verbindung und Konnektivität

    Bluetooth Low Energy (Smart Ready)

    Android unterstützt jetzt Bluetooth Low Energy (LE) mit neuen APIs in android.bluetooth. Mit den neuen APIs können Sie Android-Apps erstellen, die mit Bluetooth Low Energy-Peripheriegeräten wie Herzfrequenzmessern und Schrittzählern kommunizieren.

    Da Bluetooth LE eine Hardwarefunktion ist, die nicht auf allen Android-Geräten verfügbar ist, müssen Sie in Ihrer Manifestdatei ein <uses-feature>-Element für "android.hardware.bluetooth_le" deklarieren:

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

    Wenn Sie bereits mit den klassischen Bluetooth-APIs von Android vertraut sind, beachten Sie, dass die Verwendung der Bluetooth LE APIs unterscheiden sich in einigen Punkten. Am wichtigsten ist, dass es jetzt eine BluetoothManager-Klasse gibt, die Sie für einige übergeordnete Vorgänge verwenden sollten etwa eine BluetoothAdapter erwerben, eine Liste aller verbundenen Geräte und das Prüfen des Gerätestatus. So sollten Sie beispielsweise jetzt die BluetoothAdapter abrufen:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();

    Wenn Sie Bluetooth LE-Peripheriegeräte erkennen möchten, rufen Sie startLeScan() auf der BluetoothAdapter auf und übergeben Sie eine Implementierung der BluetoothAdapter.LeScanCallback-Schnittstelle. Wenn der Bluetooth-Adapter ein Bluetooth LE-Peripheriegerät erkennt, wird in Ihrer BluetoothAdapter.LeScanCallback-Implementierung die Methode onLeScan() aufgerufen. Mit dieser Methode erhalten Sie ein BluetoothDevice-Objekt, das das erkannte Gerät, den RSSI-Wert für das Gerät und ein Byte-Array mit dem Werbeeintrag des Geräts darstellt.

    Wenn Sie nur nach bestimmten Arten von Peripheriegeräten suchen möchten, können Sie stattdessen startLeScan() aufrufen und ein Array von UUID-Objekten hinzufügen, die die GATT-Dienste angeben, die Ihre App unterstützt.

    Hinweis:Sie können nur nach Bluetooth LE-Geräten suchen oder mit vorherigen APIs nach klassischen Bluetooth-Geräten suchen. Sie können nicht gleichzeitig nach LE und Classic suchen Bluetooth-Geräte gleichzeitig

    Rufe dann connectGatt() auf dem entsprechenden Gerät auf, um eine Verbindung zu einem Bluetooth LE-Peripheriegerät herzustellen BluetoothDevice-Objekt und übergeben Sie ihm eine Implementierung von BluetoothGattCallback Deine Implementierung von BluetoothGattCallback erhält Rückrufe zum Verbindungsstatus mit dem Gerät und zu anderen Ereignissen. Es ist während: onConnectionStateChange() -Callback, mit dem Sie mit dem Gerät kommunizieren können, wenn die Methode STATE_CONNECTED als neuen Status übergibt.

    Wenn Ihre App auf Bluetooth-Funktionen auf einem Gerät zugreifen soll, muss sie außerdem bestimmte Bluetooth-Nutzerberechtigungen anfordern. Weitere Informationen finden Sie im Bluetooth Low Energy API-Leitfaden.

    WLAN-Suchmodus

    Bei dem Versuch, den Standort des Nutzers zu ermitteln, kann Android WLAN nutzen, um indem Sie Zugangspunkte in der Nähe durchsuchen. Oft deaktivieren Nutzer die WLAN-Funktion jedoch, Dadurch wird der Akku geschont, was zu ungenauen Standortdaten führt. Android umfasst jetzt eine Nur-Scan-Modus, mit dem das WLAN des Geräts Zugangspunkte scannen kann, um den Standort zu ermitteln ohne Verbindung zu einem Zugangspunkt herstellen zu müssen. Dadurch wird der Akkuverbrauch erheblich reduziert.

    Wenn du den Standort des Nutzers abrufen möchtest, das WLAN aber derzeit deaktiviert ist, kannst du den Nutzer kann den Nur-WLAN-Scanmodus aktivieren, indem er startActivity() mit der Aktion ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE aufruft.

    WLAN-Konfiguration

    Mit den neuen WifiEnterpriseConfig APIs können unternehmensorientierte Dienste die WLAN-Konfiguration für verwaltete Geräte automatisieren.

    Schnellantwort für eingehende Anrufe

    Seit Android 4.0 können Nutzer mit der Funktion „Schnellantwort“ auf eingehende Anrufe sofort per SMS antworten, ohne den Anruf annehmen oder das Gerät entsperren zu müssen. Bisher wurden diese Kurznachrichten immer von der standardmäßigen Messaging-App verarbeitet. Jetzt für alle Apps kann seine Fähigkeit zur Verarbeitung dieser Nachrichten durch Erstellen eines Service deklarieren mit einem Intent-Filter für ACTION_RESPOND_VIA_MESSAGE.

    Wenn der Nutzer auf einen eingehenden Anruf mit einer kurzen Antwort antwortet, sendet die Telefon App Intent ACTION_RESPOND_VIA_MESSAGE mit einem URI eine Beschreibung des Empfängers (des Anrufers) und des zusätzlichen EXTRA_TEXT mit der Nachricht, die der Nutzer senden möchte. Wenn Ihr Dienst den Intent erhält, sollte er die Nachricht und beendet sich sofort von selbst (Ihre App sollte keine Aktivität anzeigen).

    Damit Sie diese Intent-Anfrage erhalten, müssen Sie die Berechtigung SEND_RESPOND_VIA_MESSAGE deklarieren.

    Multimedia

    Verbesserungen bei MediaExtractor und MediaCodec

    Android erleichtert es Ihnen jetzt, eigene DASH-Player (Dynamic Adaptive Streaming over HTTP) gemäß dem ISO/IEC 23009-1-Standard zu erstellen. Dazu können Sie vorhandene APIs in MediaCodec und MediaExtractor verwenden. Das Framework, das diesen APIs zugrunde liegt, wurde aktualisiert, um fragmentierte MP4-Dateien geparst, aber Ihre App ist weiterhin für das Parsen der MPD-Metadaten verantwortlich. und die einzelnen Streams an MediaExtractor übergeben.

    Wenn Sie DASH mit verschlüsselten Inhalten verwenden möchten, gibt die Methode getSampleCryptoInfo() die MediaCodec.CryptoInfo-Metadaten zurück, die die Struktur der einzelnen verschlüsselten Medien beschreiben Stichprobe. Außerdem wurde die getPsshInfo()-Methode zu MediaExtractor hinzugefügt, damit du auf die PSSH-Metadaten für deine DASH-Medien zugreifen kannst. Diese Methode gibt eine Zuordnung von UUID-Objekten zu Bytes zurück. Dabei gibt UUID das Kryptoschema an und die Bytes sind die Daten, die diesem Schema entsprechen.

    DRM für Medien

    Die neue MediaDrm-Klasse bietet eine modulare Lösung für digitale Rechte DRM-Schutz für Ihre Medieninhalte durch die Trennung von DRM-Angelegenheiten von der Medienwiedergabe. Für können Sie mit dieser API-Trennung Widevine-verschlüsselte Inhalte ohne das Widevine-Medienformat zu verwenden. Diese DRM-Lösung unterstützt auch die allgemeine DASH-Verschlüsselung. können Sie verschiedene DRM-Schemata für Ihre Streaminginhalte verwenden.

    Mit MediaDrm kannst du opake Schlüsselanfragenachrichten abrufen und Schlüsselantwortnachrichten vom Server für den Lizenzerwerb und die Bereitstellung verarbeiten. Ihre App ist für die Netzwerkkommunikation mit den Servern verantwortlich. Die MediaDrm-Klasse bietet nur die Möglichkeit, die Nachrichten zu generieren und zu verarbeiten.

    Die MediaDrm APIs sind für die Verwendung in Verbindung mit den MediaCodec APIs gedacht, die in Android 4.1 (API-Ebene 16) eingeführt wurden. Dazu gehören MediaCodec zum Codieren und Decodieren von Inhalten, MediaCrypto zum Umgang mit verschlüsselten Inhalten und MediaExtractor zum Extrahieren und Demultiplexen von Inhalten.

    Sie müssen zuerst MediaExtractor und MediaCodec-Objekte. Du kannst dann auf die UUID zugreifen, die das DRM-Schema identifiziert, in der Regel über Metadaten in den Inhalten, und damit mit dem Konstruktor eine Instanz eines MediaDrm-Objekts erstellen.

    Videocodierung von einem Surface

    Mit Android 4.1 (API-Ebene 16) wurde die Klasse MediaCodec für die Low-Level-Codierung und ‑Dekodierung von Medieninhalten hinzugefügt. Unter Android 4.1 mussten Sie beim Codieren von Videos den Medien ein ByteBuffer-Array zur Verfügung stellen. Unter Android 4.3 können Sie jetzt ein Surface als Eingabe für einen Encoder verwenden. So können Sie beispielsweise Eingaben aus einer vorhandenen Videodatei oder mit Frames codieren, die mit OpenGL ES generiert wurden.

    Wenn du eine Surface als Eingabe für deinen Encoder verwenden möchtest, musst du zuerst configure() für deine MediaCodec aufrufen. Rufe dann createInputSurface() auf, um die Surface zu erhalten, über die du deine Medien streamen kannst.

    Sie können z. B. das angegebene Surface als Fenster für ein OpenGL verwenden Kontext hinzu, indem er an eglCreateWindowSurface() übergeben wird. Rufen Sie dann beim Rendern der Oberfläche eglSwapBuffers() auf, um den Frame an die MediaCodec zu übergeben.

    Um mit der Codierung zu beginnen, rufen Sie start() auf dem MediaCodec auf. Wenn Sie fertig sind, geben Sie signalEndOfInputStream() ein, um die Codierung zu beenden, und release() auf der Surface.

    Medien-Muxing

    Die neue Klasse MediaMuxer ermöglicht Multiplexing zwischen einem Audiostream und einen Videostream. Diese APIs dienen als Pendant zur MediaExtractor-Klasse, die in Android 4.2 für das Demultiplexen (Demuxing) von Medien hinzugefügt wurde.

    Unterstützte Ausgabeformate sind in MediaMuxer.OutputFormat definiert. Derzeit MP4 ist das einzige Ausgabeformat und wird derzeit von MediaMuxer unterstützt jeweils nur einen Audiostream und/oder einen Videostream verwenden.

    MediaMuxer ist hauptsächlich für die Verwendung mit MediaCodec konzipiert. Sie können also die Videoverarbeitung über MediaCodec ausführen und die Ausgabe dann über MediaMuxer in einer MP4-Datei speichern. Sie können auch MediaMuxer in Kombination mit MediaExtractor verwenden, um Medien ohne Codierung oder Decodierung bearbeiten.

    Wiedergabefortschritt und Scrubbing für RemoteControlClient

    In Android 4.0 (API-Level 14) wurde die RemoteControlClient hinzugefügt, um die Medienwiedergabe über Remote-Steuerungsclients zu ermöglichen, z. B. über die Steuerelemente auf dem Sperrbildschirm. Mit Android 4.3 können solche Controller nun die Wiedergabe- und die Steuerelemente für das Scrubbing. Wenn Sie die Fernbedienung für Ihr Medien-App mit den RemoteControlClient-APIs hinzufügen, kannst du die Wiedergabe erlauben durch die Implementierung von zwei neuen Oberflächen.

    Zuerst müssen Sie das Flag FLAG_KEY_MEDIA_POSITION_UPDATE aktivieren, indem Sie es an setTransportControlsFlags().

    Implementieren Sie dann die folgenden beiden neuen Schnittstellen:

    RemoteControlClient.OnGetPlaybackPositionListener
    Dazu gehört auch der Rückruf onGetPlaybackPosition(), über den die aktuelle Position deiner Medien angefordert wird, wenn die Fernbedienung den Fortschritt auf der Benutzeroberfläche aktualisieren muss.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    Dies beinhaltet den Callback onPlaybackPositionUpdate(), der teilt Ihrer App den neuen Zeitcode für Ihre Medien mit, wenn der Nutzer die Wiedergabe mit dem UI für die Fernbedienung.

    Nachdem du deine Wiedergabe mit der neuen Position aktualisiert hast, rufe setPlaybackState() auf, um anzugeben, dass neuen Wiedergabestatus, -position und -geschwindigkeit.

    Nachdem Sie diese Schnittstellen definiert haben, können Sie sie für Ihre RemoteControlClient festlegen, indem Sie jeweils setOnGetPlaybackPositionListener() und setPlaybackPositionUpdateListener() aufrufen.

    Grafik

    Unterstützung für OpenGL ES 3.0

    Android 4.3 fügt Java-Oberflächen und native Unterstützung für OpenGL ES 3.0 hinzu. Wichtige neue Funktionen in OpenGL ES 3.0 enthalten:

    • Beschleunigung erweiterter visueller Effekte
    • Hochwertige ETC2/EAC-Texturkomprimierung als Standardfunktion
    • Eine neue Version der Schattierungssprache GLSL ES mit Unterstützung für Ganzzahl- und 32-Bit-Gleitkommazahlen
    • Erweitertes Textur-Rendering
    • Breiter gefasste Standardisierung von Texturgröße und Rendering-Zwischenspeicherformaten

    Die Java-Oberfläche für OpenGL ES 3.0 unter Android wird mit GLES30 bereitgestellt. Wenn Sie OpenGL ES 3.0 verwenden, müssen Sie dies in Ihrer Manifestdatei mit dem <uses-feature> Tag und das Attribut android:glEsVersion. Beispiel:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>

    Den OpenGL ES-Kontext geben Sie an, indem Sie setEGLContextClientVersion() aufrufen. und dabei 3 als Version übergeben.

    Weitere Informationen zur Verwendung von OpenGL ES und dazu, wie Sie prüfen können, welche OpenGL ES-Version zur Laufzeit finden Sie im OpenGL ES API-Leitfaden.

    Mipmapping für Drawables

    Die Verwendung einer Mipmap als Quelle für Ihre Bitmap oder ein Drawable ist eine einfache Möglichkeit, eine eine hohe Bildqualität und verschiedene Bildgrößen. Dies kann besonders nützlich sein, Bild, das während einer Animation skaliert werden soll.

    Mit Android 4.2 (API-Ebene 17) wurde die Unterstützung für MIPMaps in der Klasse Bitmap hinzugefügt. Android tauscht die MIP-Bilder in Ihrer Bitmap aus, wenn Sie eine MIPMap-Quelle angegeben und setHasMipMap() aktiviert haben. Unter Android 4.3 können Sie jetzt auch Mipmaps für ein BitmapDrawable-Objekt aktivieren. Dazu müssen Sie ein Mipmap-Asset bereitstellen und das android:mipMap-Attribut in einer Bitmap-Ressourcendatei festlegen oder hasMipMap() aufrufen.

    Benutzeroberfläche

    Overlays anzeigen

    Die neue ViewOverlay-Klasse bietet eine transparente Ebene über einer View, auf der Sie visuelle Inhalte hinzufügen können, ohne die Layouthierarchie zu beeinflussen. Du kannst ein ViewOverlay für jede View erhalten, indem du getOverlay() aufrufst. Das Overlay hat immer dieselbe Größe und Position wie die Hostansicht (die Ansicht, aus der es erstellt wurde). So können Sie Inhalte hinzufügen, die vor der Hostansicht angezeigt werden, aber nicht über die Grenzen dieser Hostansicht hinausgehen.

    Die Verwendung eines ViewOverlay ist besonders nützlich, wenn Sie Animationen wie das Verschieben einer Ansicht außerhalb des Containers oder das Verschieben von Elementen auf dem Bildschirm ohne Auswirkungen auf die Ansichtshierarchie zu haben. Da der nutzbare Bereich eines Overlays jedoch auf denselben Bereich wie die zugehörige Ansicht beschränkt ist, müssen Sie ein Overlay aus einer übergeordneten Ansicht verwenden, das die gewünschten Layoutgrenzen hat, wenn Sie eine Ansicht animieren möchten, die sich außerhalb ihrer Position im Layout bewegt.

    Wenn Sie ein Overlay für eine Widget-Ansicht wie Button erstellen, können Drawable-Objekte zum Overlay hinzufügen, indem sie add(Drawable) Wenn Sie getOverlay() für eine Layoutansicht wie RelativeLayout aufrufen, wird ein ViewGroupOverlay-Objekt zurückgegeben. Die Klasse ViewGroupOverlay ist eine Unterklasse von ViewOverlay, mit der Sie auch View-Objekte hinzufügen können, indem Sie add(View) aufrufen.

    Hinweis:Alle Drawables und Ansichten, die Sie einem Overlay hinzufügen. sind nur visuell. Sie können keine Fokus- oder Eingabeereignisse empfangen.

    Der folgende Code animiert beispielsweise eine Ansicht, die nach rechts gleitet, indem die Ansicht platziert wird. im Overlay der übergeordneten Ansicht und führen dann in dieser Ansicht eine Übersetzungsanimation aus:

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();

    Layout mit optischen Grenzen

    Für Ansichten, die Hintergrundbilder mit neun Patches enthalten, können Sie jetzt festlegen, dass sie auf mit benachbarten Ansichten basierend auf der "optischen" die Grenzen des Hintergrundbilds ein, als der „Clip“ die Grenzen der Ansicht.

    Zum Beispiel zeigen die Abbildungen 1 und 2 jeweils das gleiche Layout, aber die Version in Abbildung 1 ist Clipgrenzen verwenden (Standardverhalten), während in Abbildung 2 optische Grenzen verwendet werden. Da die Nine-Patch-Bilder, die für die Schaltfläche und den Bilderrahmen verwendet werden, einen Abstand an den Rändern haben, scheinen sie sich nicht zueinander oder zum Text auszurichten, wenn Sie Clip-Ränder verwenden.

    Hinweis: In den Screenshots in den Abbildungen 1 und 2 ist die Entwicklereinstellung „Layoutgrenzen anzeigen“ aktiviert. In jeder Ansicht stehen rote Linien für die optische Bänder, blaue Linien die Clip-Grenzen und Rosa die Ränder.

    Abbildung 1: Layout mit Clipgrenzen (Standardeinstellung).

    Abbildung 2: Layout mit optischen Grenzen

    Um die Ansichten anhand ihrer optischen Begrenzungen auszurichten, setzen Sie das Attribut android:layoutMode in einem der übergeordneten Layouts auf "opticalBounds". Beispiel:

    <LinearLayout android:layoutMode="opticalBounds" ... >

    Abbildung 3: Vergrößerte Ansicht des Nine-Patch-Symbols der Holo-Schaltfläche mit optischen Grenzen.

    Damit dies funktioniert, müssen die 9-Patch-Images, die auf den Hintergrund Ihrer Ansichten angewendet werden, die optischen Grenzen durch rote Linien entlang der Unter- und rechten Seite der 9-Patch-Datei (als wie in Abbildung 3 dargestellt). Die roten Linien kennzeichnen die Region, die von der der Clipgrenzen, wobei die optischen Begrenzungen des Bilds verbleiben.

    Wenn Sie optische Ränder für ein ViewGroup in Ihrem Layout aktivieren, wird der Layoutmodus für optische Ränder auf alle untergeordneten Ansichten angewendet, es sei denn, Sie überschreiben ihn für eine Gruppe, indem Sie android:layoutMode auf "clipBounds" festlegen. Alle Layoutelemente berücksichtigen auch die optischen Grenzen ihrer untergeordneten Ansichten und passen ihre eigenen Grenzen an die optischen Grenzen der Ansichten an, die sie enthalten. Layoutelemente (Unterklassen von ViewGroup) unterstützen derzeit jedoch keine optischen Grenzen für Nine-Patch-Bilder, die auf ihren eigenen Hintergrund angewendet werden.

    Wenn Sie eine benutzerdefinierte Ansicht erstellen, indem Sie View, ViewGroup oder eine Unterklasse davon abgeleitet haben, übernimmt die Ansicht diese optisch gebundenen Verhaltensweisen.

    Hinweis: Alle vom Holo-Design unterstützten Widgets wurden mit optischen Begrenzungen aktualisiert, darunter Button, Spinner und EditText. Sie können also sofort davon profitieren, Attribut android:layoutMode auf "opticalBounds", wenn in deiner App ein Holo-Design angewendet wird (Theme.Holo, Theme.Holo.Light usw.).

    Um mit dem Tool 9-Patch zeichnen optische Grenzen für Ihre eigenen Bilder mit neun Patches festzulegen, halten Sie die Strg-Taste gedrückt, auf die Rahmenpixel.

    Animation für Rechteckwerte

    Mit dem neuen RectEvaluator können Sie jetzt zwischen zwei Rect-Werten animieren. Diese neue Klasse ist eine Implementierung von TypeEvaluator, die Sie an ValueAnimator.setEvaluator() übergeben können.

    Listener für Fensteranhängen und Fokus

    Wenn Sie zuvor wissen wollten, wann Ihre Ansicht an das Fenster angehängt oder davon getrennt wurde oder sich der Fokus geändert hat, mussten Sie die View-Klasse überschreiben, um onAttachedToWindow() und onDetachedFromWindow() bzw. onWindowFocusChanged() zu implementieren.

    Wenn Sie jetzt Ereignisse vom Typ „Anhängen“ und „Trennen“ empfangen möchten, können Sie stattdessen ViewTreeObserver.OnWindowAttachListener implementieren und für eine Ansicht mit addOnWindowAttachListener(). Wenn Sie Fokusereignisse erhalten möchten, können Sie ViewTreeObserver.OnWindowFocusChangeListener implementieren und auf eine Ansicht mit addOnWindowFocusChangeListener().

    Unterstützung für Overscan auf Fernsehern

    Du kannst jetzt Overscan aktivieren, damit deine App auf jedem Fernseher den gesamten Bildschirm ausfüllt. für Ihr App-Layout. Der Overscan-Modus wird durch das Flag FLAG_LAYOUT_IN_OVERSCAN bestimmt. Sie können es mit Plattformthemen wie Theme_DeviceDefault_NoActionBar_Overscan oder durch Aktivieren des Stils windowOverscan in einem benutzerdefinierten Design aktivieren.

    Bildschirmausrichtung

    Die <activity> screenOrientation des Tags unterstützt jetzt zusätzliche Werte, um die Einstellung des Nutzers für die automatische Rotation zu berücksichtigen:

    "userLandscape"
    Verhält sich wie "sensorLandscape", außer wenn der Nutzer das automatische Drehen deaktiviert hat bleibt das Display in der normalen Ausrichtung im Querformat gesperrt und dreht sich nicht.
    "userPortrait"
    Funktioniert genauso wie "sensorPortrait", es sei denn, der Nutzer deaktiviert die automatische Drehung. In diesem Fall wird die normale Hochformatausrichtung gesperrt und das Display wird nicht gedreht.
    "fullUser"
    Funktioniert genauso wie "fullSensor" und ermöglicht die Drehung in alle vier Richtungen. Wenn der Nutzer die automatische Drehung deaktiviert, wird die bevorzugte Ausrichtung des Nutzers festgelegt.

    Außerdem können Sie jetzt auch "locked" deklarieren, um die Ausrichtung Ihrer App in aktuellen Ausrichtung des Bildschirms.

    Rotationsanimationen

    Das neue Feld rotationAnimation in Mit WindowManager können Sie zwischen drei Animationen wählen, die beim Wechsel der Bildschirmausrichtung verwendet werden soll. Die drei Animationen sind:

    Hinweis: Diese Animationen sind nur verfügbar, wenn Sie für Ihre Aktivität den Vollbildmodus festgelegt haben. Diesen können Sie mit Designs wie Theme.Holo.NoActionBar.Fullscreen aktivieren.

    So aktivieren Sie zum Beispiel die Funktion Animation:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }

    Nutzereingabe

    Neue Sensortypen

    Mit dem neuen TYPE_GAME_ROTATION_VECTOR-Sensor kannst du die Drehungen des Geräts erkennen, ohne dir Gedanken über magnetische Störungen machen zu müssen. Im Gegensatz zum TYPE_ROTATION_VECTOR-Sensor basiert TYPE_GAME_ROTATION_VECTOR nicht auf dem magnetischen Norden.

    Die neuen TYPE_GYROSCOPE_UNCALIBRATED- und TYPE_MAGNETIC_FIELD_UNCALIBRATED-Sensoren liefern Rohsensordaten ohne Berücksichtigung von Bias-Schätzungen. Das bedeutet, dass die vorhandenen TYPE_GYROSCOPE- und TYPE_MAGNETIC_FIELD-Sensoren Sensordaten liefern, die die geschätzte Abweichung durch Gyrodrift bzw. hartes Eisen im Gerät berücksichtigen. Während das neue „nicht kalibrierte“ bieten die verschiedenen Sensoren, Sensorrohdaten und stellen die geschätzten Verzerrungswerte separat bereit. Mit diesen Sensoren kannst du können Sie Ihre eigene benutzerdefinierte Kalibrierung für die Sensordaten bereitstellen, indem Sie die geschätzte Verzerrung mit externe Daten.

    Benachrichtigungs-Listener

    Android 4.3 enthält eine neue Dienstklasse, NotificationListenerService, mit der Ihre App Informationen zu neuen Benachrichtigungen erhalten kann, sobald sie vom System gepostet werden.

    Wenn Ihre App derzeit die APIs für Bedienungshilfen zum Zugriff auf Systembenachrichtigungen verwendet, sollten Sie Ihre App so aktualisieren, dass sie stattdessen diese APIs verwendet.

    Contacts Provider

    Abfrage nach „contactables“

    Die neue Anfrage des Kontaktanbieters (Contactables.CONTENT_URI) bietet eine effiziente Möglichkeit zum Abrufen einer Cursor, die alle E-Mail-Adressen und Telefonnummern aller Kontakte enthält, die der angegebenen Abfrage entsprechen.

    Kontakt-Deltas abfragen

    Zum Kontaktanbieter wurden neue APIs hinzugefügt, mit denen Sie kürzlich vorgenommene Änderungen an den Kontaktdaten effizient abfragen können. Zuvor konnte Ihre App benachrichtigt werden, wenn sich etwas in den Kontaktdaten geändert hat. Sie wussten jedoch nicht genau, was sich geändert hat, und müssten alle Kontakte abrufen und diese dann durchlaufen, um die Änderung zu erkennen.

    Um Änderungen an Einfügungen und Aktualisierungen zu verfolgen, können Sie jetzt den Parameter CONTACT_LAST_UPDATED_TIMESTAMP in Ihre Auswahl aufnehmen, um nur die Kontakte abzufragen, die sich seit Ihrer letzten Anfrage an den Anbieter geändert haben.

    In der neuen Tabelle ContactsContract.DeletedContacts finden Sie ein Protokoll der gelöschten Kontakte. Jeder gelöschte Kontakt wird jedoch nur für eine begrenzte Zeit in dieser Tabelle aufbewahrt. Ähnlich wie bei CONTACT_LAST_UPDATED_TIMESTAMP können Sie mit dem neuen Auswahlparameter CONTACT_DELETED_TIMESTAMP prüfen, welche Kontakte seit der letzten Abfrage beim Anbieter gelöscht wurden. Die Tabelle enthält auch die Konstante DAYS_KEPT_MILLISECONDS mit der Anzahl der Tage (in Millisekunden), für die das Protokoll gespeichert wird.

    Außerdem sendet der Contacts Provider jetzt die Aktion CONTACTS_DATABASE_CREATED, wenn der Nutzer den Speicher für Kontakte über das Menü „Systemeinstellungen“ löscht. Dadurch wird die Contacts Provider-Datenbank effektiv neu erstellt. Es soll Apps signalisieren, dass alle Kontaktinformationen gespeichert sind, und laden Sie sie mit einer neuen Abfrage.

    Beispielcode, in dem mit diesen APIs nach Änderungen an den Kontakten gesucht wird, finden Sie im ApiDemos-Beispiel, das im Download SDK-Beispiele verfügbar ist.

    Lokalisierung

    Verbesserte Unterstützung für bidirektionalen Text

    Frühere Android-Versionen unterstützen Sprachen und Layouts mit Leserichtung von rechts nach links (RTL), verarbeiten aber manchmal Text mit gemischter Leserichtung nicht richtig. Daher werden in Android 4.3 die BidiFormatter APIs hinzugefügt, mit denen Sie Text mit Inhalten in entgegengesetzter Richtung richtig formatieren können, ohne dass Teile davon unlesbar werden.

    Wenn Sie beispielsweise einen Satz mit einer Stringvariablen erstellen möchten, z. B. „Meinten Sie 15 Bay Street, Laurel, CA?“, übergeben Sie normalerweise eine lokalisierte Stringressource und die Variable an String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);

    Wenn die Sprache jedoch Hebräisch ist, sieht der formatierte String so aus:

    栏戠 夛WERT örtlichen Anteil 15 Bay Street, Laurel, CA?

    Das ist falsch, da die „15“ links von „Bay Street“ stehen sollte. Die Lösung besteht darin, BidiFormatter und die Methode unicodeWrap() zu verwenden. Der Code oben würde dann so aussehen:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));

    Standardmäßig verwendet unicodeWrap() die Heuristik „Erstes starkes Richtungssignal“. Das kann zu Fehlern führen, wenn das erste Signal für die Textrichtung nicht die richtige Richtung für den Inhalt insgesamt darstellt. Bei Bedarf können Sie eine andere Heuristik angeben, indem Sie eine der TextDirectionHeuristic-Konstanten aus TextDirectionHeuristics übergeben. an unicodeWrap().

    Hinweis: Diese neuen APIs sind auch für frühere Android-Versionen über die Android-Supportbibliothek mit der Klasse BidiFormatter und den zugehörigen APIs verfügbar.

    Bedienungshilfen

    Schlüsselereignisse verarbeiten

    Ein AccessibilityService kann jetzt einen Rückruf erhalten für mit der Callback-Methode onKeyEvent() angeben. So kann die Bedienungshilfe Eingaben für wie z. B. eine Tastatur, und übersetzen diese Ereignisse in spezielle Aktionen, bisher nur mit Berührungen oder den Richtungstasten des Geräts möglich gewesen wäre.

    Text auswählen und kopieren/einfügen

    Die AccessibilityNodeInfo bietet jetzt APIs, die AccessibilityService zum Auswählen, Ausschneiden, Kopieren und Einfügen Text in einem Knoten einfügen.

    Um die Auswahl des auszuschneidenden oder zu kopierenden Textes festzulegen, kann Ihre Bedienungshilfe das neue Aktion, ACTION_SET_SELECTION, bestanden die Start- und Endposition der Auswahl mit ACTION_ARGUMENT_SELECTION_START_INT und ACTION_ARGUMENT_SELECTION_END_INT. Alternativ können Sie Text auswählen, indem Sie die Cursorposition mit der vorhandenen Aktion ACTION_NEXT_AT_MOVEMENT_GRANULARITY (bisher nur zum Verschieben des Cursors) ändern und das Argument ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN hinzufügen.

    Anschließend können Sie sie mit ACTION_CUT ausschneiden oder kopieren. ACTION_COPY und später einfügen mit ACTION_PASTE

    Hinweis:Diese neuen APIs sind auch für frühere Versionen verfügbar. über den Android-Support Bibliothek mit dem AccessibilityNodeInfoCompat .

    Bedienungshilfen deklarieren

    Ab Android 4.3 muss eine Bedienungshilfe Bedienungshilfen deklarieren. in seiner Metadatendatei, um bestimmte Bedienungshilfen nutzen zu können. Wenn die Capability nicht in der Metadatendatei angefordert wurde, ist das Feature ein Null-Vorgang. Zum Deklarieren der müssen Sie XML-Attribute verwenden, die den verschiedenen „Fähigkeit“ Konstanten in AccessibilityServiceInfo .

    Wenn ein Dienst beispielsweise die flagRequestFilterKeyEvents-Funktion nicht anfordert, erhält er keine wichtigen Ereignisse.

    Testen und Debugging

    Automatisierte UI-Tests

    Die neue UiAutomation-Klasse bietet APIs, mit denen Sie Nutzeraktionen für die Testautomatisierung simulieren können. Mit den AccessibilityService APIs und den UiAutomation APIs der Plattform können Sie den Bildschirminhalt prüfen und beliebige Tastatur- und Touch-Ereignisse einschleusen.

    Rufen Sie Instrumentation.getUiAutomation() auf, um eine Instanz von UiAutomation zu erhalten. Damit dies funktioniert, müssen Sie die Option -w mit dem Befehl instrument angeben, wenn Sie InstrumentationTestCase über adb shell ausführen.

    Mit der UiAutomation-Instanz können Sie beliebige Ereignisse ausführen, um Ihre App zu testen. Rufen Sie dazu executeAndWaitForEvent() auf und übergeben Sie ihm eine auszuführende Runnable, eine Zeitüberschreitung für den Vorgang und eine Implementierung der UiAutomation.AccessibilityEventFilter-Schnittstelle. In Ihrer UiAutomation.AccessibilityEventFilter-Implementierung erhalten Sie einen Aufruf, mit dem Sie die Ereignisse herausfiltern und den Erfolg oder Misserfolg eines bestimmten Testfalls bestimmen können.

    Wenn du während eines Tests alle Ereignisse beobachten möchtest, erstelle eine Implementierung von UiAutomation.OnAccessibilityEventListener und übergib sie an setOnAccessibilityEventListener(). Ihre Listener-Benutzeroberfläche erhält dann jedes Mal, wenn ein Ereignis auftritt, einen Aufruf von onAccessibilityEvent() und ein AccessibilityEvent-Objekt, das das Ereignis beschreibt.

    Es gibt eine Vielzahl anderer Vorgänge, die die UiAutomation APIs verfügbar machen auf sehr niedriger Ebene, um die Entwicklung von UI-Testtools wie uiautomator zu fördern. Beispiel: UiAutomation kann auch:

    • Eingabeereignisse einfügen
    • Ausrichtung des Displays ändern
    • Screenshots erstellen

    Und was für UI-Testtools am wichtigsten ist: Die UiAutomation APIs funktionieren im Gegensatz zu den APIs in Instrumentation sitzungsübergreifend.

    Systrace-Ereignisse für Apps

    Android 4.3 fügt die Trace-Klasse mit zwei statischen Methoden hinzu: beginSection() und endSection(), mit denen Sie Codeblöcke definieren können, die in den Systrace-Bericht aufgenommen werden sollen. Durch Erstellen mit nachverfolgbarem Code in Ihrer App enthält, liefern Ihnen die Systrace-Logs Analyse dessen, wo in Ihrer App eine Verlangsamung auftritt.

    Informationen zur Verwendung des Systrace-Tools finden Sie unter Display und Leistung mit Systrace analysieren.

    Sicherheit

    Android-Schlüsselspeicher für App-private Schlüssel

    Android bietet jetzt einen benutzerdefinierten Java Security Provider in der KeyStore an Android Key Store, mit dem Sie private Schlüssel generieren und speichern können, möglicherweise nur von Ihrer App gesehen und verwendet werden. Um den Android Key Store zu laden, "AndroidKeyStore" bis KeyStore.getInstance().

    Generiere zum Verwalten der privaten Anmeldedaten deiner App im Android Key Store einen neuen Schlüssel mit KeyPairGenerator mit KeyPairGeneratorSpec. Zuerst durch Aufrufen von getInstance() eine Instanz von KeyPairGenerator abrufen Rufen Sie dann initialize() auf und übergeben Sie eine Instanz von KeyPairGeneratorSpec, die Sie mit KeyPairGeneratorSpec.Builder abrufen können. Rufen Sie abschließend generateKeyPair() auf, um Ihre KeyPair abzurufen.

    Speichern von Anmeldedaten auf der Hardware

    Android unterstützt jetzt auch hardwaregestützten Speicherplatz für KeyChain Anmeldedaten. Dies erhöht die Sicherheit, da die Schlüssel nicht zur Extraktion bereitstehen. Das heißt, sobald sich Schlüssel in einem hardwarebasierten Schlüsselspeicher (Secure Element, TPM oder TrustZone) befinden, können sie für kryptografische Vorgänge verwendet werden, das Material des privaten Schlüssels kann jedoch nicht exportiert werden. Sogar der Betriebssystem-Kernel kann nicht auf dieses Schlüsselmaterial zugreifen. Nicht alle Android-Geräte unterstützen den Speicher auf Hardware. Sie können jedoch zur Laufzeit prüfen, ob hardwaregestützter Speicher verfügbar ist, indem Sie KeyChain.IsBoundKeyAlgorithm() aufrufen.

    Manifestdeklarationen

    Erforderliche deklarative Funktionen

    Die folgenden Werte werden jetzt im Element <uses-feature> unterstützt. So können Sie dafür sorgen, dass Ihre App nur auf Geräten installiert wird, die die für Ihre App erforderlichen Funktionen bieten.

    FEATURE_APP_WIDGETS
    Erklärt, dass deine App ein App-Widget bietet und nur auf Geräten installiert werden sollte, die einen Startbildschirm oder eine ähnliche Stelle zu integrieren, an der Nutzer App-Widgets einbetten können. Beispiel:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    FEATURE_HOME_SCREEN
    Hiermit wird erklärt, dass Ihre App als Ersatz für den Startbildschirm dient und nur auf Geräten installiert werden sollte, die Startbildschirm-Apps von Drittanbietern unterstützen. Beispiel:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    FEATURE_INPUT_METHODS
    Hiermit wird erklärt, dass Ihre App eine benutzerdefinierte Eingabemethode (eine mit InputMethodService erstellte Tastatur) bietet und nur auf Geräten installiert werden sollte, die Eingabemethoden von Drittanbietern unterstützen. Beispiel:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    FEATURE_BLUETOOTH_LE
    Hiermit wird erklärt, dass Ihre App Bluetooth Low Energy APIs verwendet und nur auf Geräten installiert werden sollte, die über Bluetooth Low Energy mit anderen Geräten kommunizieren können. Beispiel:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />

    Nutzerberechtigungen

    Die folgenden Werte werden jetzt in <uses-permission> unterstützt, um die Berechtigungen anzugeben, die Ihre App für den Zugriff auf bestimmte APIs benötigt.

    BIND_NOTIFICATION_LISTENER_SERVICE
    Erforderlich, um die neuen NotificationListenerService APIs zu verwenden.
    SEND_RESPOND_VIA_MESSAGE
    Erforderlich, um den ACTION_RESPOND_VIA_MESSAGE-Intent zu empfangen.

    Eine detaillierte Übersicht über alle API-Änderungen in Android 4.3 finden Sie im API-Unterschiedsbericht.