APIs unter Android 4.2

API-Level: 17

Android 4.2 (JELLY_BEAN_MR1) ist ein Update der Jelly Bean-Version, das neue Funktionen für Nutzer und App-Entwickler bietet. Dieses Dokument bietet eine Einführung in die wichtigsten und nützlichsten neuen APIs für Entwickler.

Als App-Entwickler sollten Sie das System-Image und die SDK-Plattform für Android 4.2 so schnell wie möglich aus dem SDK-Manager herunterladen. Wenn Sie zum Testen Ihrer App kein Gerät mit Android 4.2 haben, testen Sie Ihre App mit dem System-Image von Android 4.2 im Android-Emulator. Erstellen Sie dann Ihre Apps für die Plattform Android 4.2, um die neuesten APIs zu nutzen.

Wenn du deine App besser für Geräte mit Android 4.2 optimieren möchtest, solltest du targetSdkVersion auf "17" setzen, sie auf einem Android 4.2-System-Image installieren, testen und dann ein Update mit dieser Änderung veröffentlichen.

Sie können APIs in Android 4.2 verwenden und gleichzeitig ältere Versionen unterstützen. Fügen Sie Ihrem Code dazu Bedingungen hinzu, die vor der Ausführung von APIs, die von Ihrem minSdkVersion nicht unterstützt werden, auf das API-Level des Systems prüfen. Weitere Informationen zum Aufrechterhalten der Abwärtskompatibilität finden Sie unter Abwärtskompatible UIs erstellen.

Weitere Informationen zur Funktionsweise von API-Levels finden Sie unter Was ist ein API-Level?

Wichtige Verhaltensänderungen

Wenn Sie bereits eine App für Android veröffentlicht haben, sollten Sie sich der folgenden Änderungen bewusst sein, die sich auf das Verhalten Ihrer App auswirken können:

  • Contentanbieter werden nicht mehr standardmäßig exportiert. Das heißt, der Standardwert für das Attribut android:exported ist jetzt “false". Wenn es wichtig ist, dass andere Apps auf Ihren Contentanbieter zugreifen können, müssen Sie jetzt explizit android:exported="true" festlegen.

    Diese Änderung wird nur wirksam, wenn Sie für android:targetSdkVersion oder android:minSdkVersion mindestens 17 festgelegt haben. Andernfalls ist der Standardwert immer noch “true", auch unter Android 4.2 und höher.

  • Im Vergleich zu früheren Android-Versionen sind die Ergebnisse für den Nutzerstandort möglicherweise weniger genau, wenn deine App die Berechtigung ACCESS_COARSE_LOCATION, aber nicht die Berechtigung ACCESS_FINE_LOCATION anfordert.

    Um die Erwartungen der Nutzer in Bezug auf den Datenschutz zu erfüllen, wenn Ihre App die Berechtigung für den ungefähren (und nicht den genauen Standort) anfordert, gibt das System keine genauere Standortschätzung als die eines Häuserblocks aus.

  • Einige durch Settings.System definierte Geräteeinstellungen sind jetzt schreibgeschützt. Wenn deine App versucht, Änderungen an den in Settings.System definierten Einstellungen zu schreiben, die in Settings.Global verschoben wurden, schlägt der Schreibvorgang unter Android 4.2 und höher automatisch fehl.

    Auch wenn der Wert für android:targetSdkVersion und android:minSdkVersion niedriger als 17 ist, kann deine App unter Android 4.2 und höher die auf Settings.Global verschobenen Einstellungen nicht ändern.

  • Wenn deine App WebView verwendet, bietet Android 4.2 eine zusätzliche Sicherheitsebene, damit du JavaScript sicherer an deinen Android-Code binden kannst. Wenn Sie targetSdkVersion auf 17 oder höher festlegen, müssen Sie jetzt jeder Methode, die für Ihr JavaScript verfügbar sein soll, die Annotation @JavascriptInterface hinzufügen. Die Methode muss ebenfalls öffentlich sein. Wenn Sie die Annotation nicht angeben, kann unter Android 4.2 oder höher über eine Webseite in Ihrem WebView nicht auf die Methode zugegriffen werden. Wenn Sie targetSdkVersion auf 16 oder niedriger festlegen, ist die Annotation nicht erforderlich. Wir empfehlen jedoch, die Zielversion zu aktualisieren und die Annotation hinzuzufügen, um die Sicherheit zu erhöhen.

    Weitere Informationen zum Binden von JavaScript-Code an Android-Code

Daydream

Daydream ist ein neuer interaktiver Bildschirmschonermodus für Android-Geräte. Sie wird automatisch aktiviert, wenn das Gerät in ein Dock eingesetzt wird oder wenn es inaktiv bleibt, während es an ein Ladegerät angeschlossen ist, anstatt den Bildschirm auszuschalten. Daydream zeigt Träume nacheinander an. Dabei kann es sich um ein reines visuelles, passives Display handeln, das bei Berührung geschlossen wird, oder interaktiv und responsiv auf alle Eingabeereignisse reagieren. Deine Träume werden in deiner App umgesetzt und haben vollständigen Zugriff auf das Android-UI-Toolkit, einschließlich Ansichten, Layouts und Animationen, damit sie flexibler und leistungsfähiger sind als Live-Hintergründe oder App-Widgets.

Du kannst einen Traum für Daydream erstellen, indem du eine Unterklasse von DreamService implementierst. Die DreamService APIs ähneln denen von Activity. Wenn Sie die UI für Ihren Traum festlegen möchten, übergeben Sie nach Ablauf eines Fensters, z. B. vom onAttachedToWindow()-Callback, eine Layout-Ressourcen-ID oder View an setContentView().

Die DreamService-Klasse bietet zusätzlich zu den Basis-Service-APIs weitere wichtige Lebenszyklus-Callback-Methoden, z. B. onDreamingStarted(), onDreamingStopped() und onDetachedFromWindow(). Sie können einen DreamService nicht über die Anwendung initiieren. Er wird automatisch vom System gestartet.

Wenn Ihr Traum interaktiv ist, können Sie eine Aktivität aus dem Traum starten, um den Nutzer zur vollständigen Benutzeroberfläche Ihrer App für mehr Details oder Kontrolle weiterzuleiten. Sie können finish() verwenden, um den Dream zu beenden, damit der Nutzer die neue Aktivität sehen kann.

Damit Daydream für das System verfügbar ist, musst du DreamService mit einem <service>-Element in der Manifestdatei deklarieren. Anschließend müssen Sie der Aktion "android.service.dreams.DreamService" einen Intent-Filter hinzufügen. Beispiele:

<service android:name=".MyDream" android:exported="true"
    android:icon="@drawable/dream_icon" android:label="@string/dream_label" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

In DreamService gibt es einige andere nützliche Methoden:

  • setInteractive(boolean) legt fest, ob der Traum Eingabeereignisse erhält oder sofort nach der Nutzereingabe beendet wird. Ist der Dream interaktiv, kann er ihn mit den Schaltflächen Zurück oder Startseite schließen. Alternativ können Sie finish() aufrufen, um ihn zu beenden.
  • Wenn du ein immersives Display verwenden möchtest, kannst du setFullscreen() aufrufen, um die Statusleiste auszublenden.
  • Bevor Daydream startet, wird das Display gedimmt, um dem Nutzer zu signalisieren, dass sich die Zeitüberschreitung bei der Inaktivität nähert. Wenn du setScreenBright(true) anrufst, kannst du das Display auf die übliche Helligkeit einstellen.

Weitere Informationen finden Sie in der Dokumentation zu DreamService.

Sekundäre Displays

Android ermöglicht deiner App jetzt, individuelle Inhalte auf zusätzlichen Bildschirmen anzuzeigen, die über eine Kabel- oder WLAN-Verbindung mit dem Gerät des Nutzers verbunden sind. Erweitere die Presentation-Klasse und implementiere den onCreate()-Callback, um eindeutige Inhalte für einen sekundären Bildschirm zu erstellen. Geben Sie innerhalb von onCreate() die UI für die sekundäre Anzeige an, indem Sie setContentView() aufrufen. Als Erweiterung der Klasse Dialog bietet die Klasse Presentation die Region, in der Ihre App eine eindeutige UI auf dem sekundären Bildschirm anzeigen kann.

Wenn Sie sekundäre Bildschirme ermitteln möchten, auf denen Ihr Presentation angezeigt werden kann, verwenden Sie entweder die DisplayManager oder die MediaRouter API. Mit den DisplayManager APIs können Sie mehrere Bildschirme auflisten, die gleichzeitig verbunden sein können. Normalerweise sollten Sie stattdessen MediaRouter verwenden, um schnell auf die Standardanzeige des Systems für Präsentationen zuzugreifen.

Um die Standardanzeige für Ihre Präsentation zu erhalten, rufen Sie MediaRouter.getSelectedRoute() auf und übergeben Sie ROUTE_TYPE_LIVE_VIDEO. Es wird ein MediaRouter.RouteInfo-Objekt zurückgegeben, das die aktuell ausgewählte Route des Systems für Videopräsentationen beschreibt. Wenn MediaRouter.RouteInfo nicht null ist, rufe getPresentationDisplay() auf, um die Display für das verbundene Display zu erhalten.

Anschließend können Sie Ihre Präsentation anzeigen lassen. Dazu übergeben Sie das Display-Objekt an einen Konstruktor für Ihre Presentation-Klasse. Ihre Präsentation erscheint nun auf dem zweiten Display.

Um während der Laufzeit zu erkennen, wenn ein neues Display verbunden wurde, erstellen Sie eine Instanz von MediaRouter.SimpleCallback, in der Sie die Callback-Methode onRoutePresentationDisplayChanged() implementieren, die vom System aufgerufen wird, wenn ein neues Präsentationsdisplay verbunden ist. Registrieren Sie dann die MediaRouter.SimpleCallback, indem Sie sie zusammen mit dem Routentyp ROUTE_TYPE_LIVE_VIDEO an MediaRouter.addCallback() übergeben. Wenn Sie einen Anruf von onRoutePresentationDisplayChanged() erhalten, rufen Sie einfach MediaRouter.getSelectedRoute() wie oben beschrieben auf.

Wenn Sie die Benutzeroberfläche in Presentation für sekundäre Bildschirme weiter optimieren möchten, können Sie ein anderes Design anwenden. Geben Sie dazu das Attribut android:presentationTheme in der <style> an, die Sie auf Ihre Anwendung oder Aktivität angewendet haben.

Denken Sie daran, dass Bildschirme, die mit dem Gerät der Nutzenden verbunden sind, oft eine größere Bildschirmgröße und wahrscheinlich eine andere Bildschirmdichte haben. Da die Bildschirmmerkmale unterschiedlich sein können, solltest du Ressourcen bereitstellen, die speziell für solche größeren Bildschirme optimiert sind. Wenn Sie zusätzliche Ressourcen aus dem Presentation anfordern müssen, rufen Sie getContext().getResources() auf, um das Resources-Objekt zu erhalten, das der Anzeige entspricht. Dadurch werden die entsprechenden Ressourcen aus Ihrer App bereitgestellt, die für die Bildschirmgröße und -dichte des sekundären Bildschirms am besten geeignet sind.

Weitere Informationen und einige Codebeispiele finden Sie in der Dokumentation zur Klasse Presentation.

Sperrbildschirm-Widgets

Unter Android können Nutzer jetzt App-Widgets zum Sperrbildschirm hinzufügen. Damit dein App-Widget auf dem Sperrbildschirm verwendet werden kann, füge deiner XML-Datei das Attribut android:widgetCategory hinzu, in der AppWidgetProviderInfo angegeben ist. Dieses Attribut unterstützt zwei Werte: home_screen und keyguard. Das Attribut ist standardmäßig auf home_screen gesetzt, sodass Nutzer Ihr App-Widget dem Startbildschirm hinzufügen können. Wenn das App-Widget auch auf dem Sperrbildschirm verfügbar sein soll, fügen Sie den Wert keyguard hinzu:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

Außerdem solltest du mit dem Attribut android:initialKeyguardLayout ein anfängliches Layout für dein App-Widget auf dem Sperrbildschirm angeben. Dies funktioniert auf die gleiche Weise wie das android:initialLayout-Objekt, da es ein Layout bereitstellt, das sofort angezeigt werden kann, bis das App-Widget initialisiert ist und das Layout aktualisieren kann.

Weitere Informationen zum Erstellen von App-Widgets für den Sperrbildschirm, etwa zur richtigen Größe des App-Widgets auf dem Sperrbildschirm, finden Sie im Leitfaden zu App-Widgets.

Mehrere Nutzer

Android ermöglicht jetzt mehrere Nutzerbereiche auf gemeinsam nutzbaren Geräten wie Tablets. Jeder Nutzer eines Geräts hat seine eigenen Konten, Apps, Systemeinstellungen, Dateien und andere nutzerbezogene Daten.

Als App-Entwickler müssen Sie nichts weiter tun, damit Ihre App für mehrere Nutzer auf einem einzigen Gerät ordnungsgemäß funktioniert. Unabhängig davon, wie viele Nutzer auf einem Gerät vorhanden sind, werden die Daten, die Ihre App für einen bestimmten Nutzer speichert, von den Daten getrennt, die Ihre App für andere Nutzer speichert. Das System verfolgt, welche Nutzerdaten zum Nutzerprozess gehören, in dem Ihre Anwendung ausgeführt wird, und gewährt Ihrer Anwendung nur Zugriff auf die Daten dieses Nutzers. Der Zugriff auf die Daten anderer Nutzer ist nicht möglich.

Daten in einer Umgebung mit mehreren Nutzern speichern

Wenn Ihre Anwendung Nutzereinstellungen speichert, eine Datenbank erstellt oder eine Datei in den internen oder externen Speicherplatz des Nutzers schreibt, sind diese Daten nur verfügbar, während sie als dieser Nutzer ausgeführt werden.

Damit Ihre Anwendung in einer Umgebung mit mehreren Nutzern ordnungsgemäß funktioniert, verwenden Sie nicht das interne Anwendungsverzeichnis oder den externen Speicherort mit hartcodierten Pfaden, sondern immer die entsprechenden APIs:

Unabhängig davon, welche dieser APIs Sie zum Speichern der Daten eines bestimmten Nutzers verwenden, sind diese nicht zugänglich, während sie als ein anderer Nutzer ausgeführt werden. Aus der Sicht Ihrer App verwendet jeder Nutzer ein völlig separates Gerät.

Nutzer in einer Umgebung mit mehreren Nutzern identifizieren

Wenn Ihre App einzelne Nutzer identifizieren möchte, z. B. um Analysen abzurufen oder andere Kontoverknüpfungen zu erstellen, sollten Sie die empfohlenen Vorgehensweisen zum Identifizieren von einzelnen Installationen befolgen. Wenn Sie beim ersten Start Ihrer App eine neue UUID erstellen, erhalten Sie auf jeden Fall eine eindeutige ID für das Tracking jedes Nutzers, unabhängig davon, wie viele Nutzer Ihre App auf einem einzelnen Gerät installieren. Alternativ kannst du ein von deinem Server abgerufenes lokales Token speichern oder die von Google Cloud Messaging bereitgestellte Registrierungs-ID verwenden.

Wenn Ihre App eine der Hardware-Gerätekennungen anfordert (z. B. die WLAN-MAC-Adresse oder die SERIAL-Nummer), wird für jeden Nutzer derselbe Wert zurückgegeben, da diese Kennungen an die Hardware und nicht an den Nutzer gebunden sind. Ganz zu schweigen von den anderen Problemen, mit denen diese Kennungen verbunden sind, wie im Blogpost App-Installationen identifizieren erläutert.

Neue globale Einstellungen

Die Systemeinstellungen wurden aktualisiert, um mit Settings.Global mehrere Nutzer zu unterstützen. Diese Sammlung von Einstellungen ähnelt den Settings.Secure-Einstellungen, weil sie schreibgeschützt sind, aber global für alle Nutzerbereiche auf dem Gerät gelten.

Mehrere vorhandene Einstellungen wurden entweder von Settings.System oder Settings.Secure hierher verschoben. Wenn in Ihrer App derzeit Änderungen an Einstellungen vorgenommen werden, die zuvor in Settings.System definiert wurden (z. B. AIRPLANE_MODE_ON), sollten diese Einstellungen auf einem Gerät mit Android 4.2 oder höher nicht mehr funktionieren, wenn diese Einstellungen in Settings.Global verschoben werden. Sie können die Einstellungen in Settings.Global weiterhin lesen. Da sie jedoch nicht mehr als sicher gelten, dass Apps geändert werden können, schlägt ein solcher Versuch fehl und das System schreibt eine Warnung in das Systemprotokoll, wenn Ihre App unter Android 4.2 oder höher ausgeführt wird.

Unterstützung für RTL-Layout

Android bietet jetzt mehrere APIs, mit denen Sie Benutzeroberflächen erstellen können, die die Layoutausrichtung angewandt verändern. So werden Sprachen unterstützt, die von rechts nach links (Rechts nach links) (RTL) ausgerichtete UI-Elemente und Leserichtungen wie Arabisch und Hebräisch unterstützen.

Damit RTL-Layouts in Ihrer App unterstützt werden, legen Sie das Attribut android:supportsRtl auf das <application>-Element in Ihrer Manifestdatei und dann “true" fest. Wenn Sie diese Option aktivieren, aktiviert das System verschiedene RTL APIs, um Ihre App mit RTL-Layouts anzuzeigen. Die Aktionsleiste zeigt beispielsweise das Symbol und den Titel auf der rechten Seite und Aktionsschaltflächen auf der linken Seite an. Alle Layouts, die Sie mit den vom Framework bereitgestellten View-Klassen erstellt haben, werden ebenfalls umgekehrt.

Wenn Sie das Erscheinungsbild Ihrer App bei der Darstellung mit einem RTL-Layout weiter optimieren möchten, gibt es zwei grundlegende Optimierungsebenen:

  1. Konvertieren Sie links- und rechts ausgerichtete Layouteigenschaften in am Anfang und Ende ausgerichtete Layouteigenschaften.

    Verwenden Sie beispielsweise android:layout_marginStart anstelle von android:layout_marginLeft und android:layout_marginEnd anstelle von android:layout_marginRight.

    Die Klasse RelativeLayout stellt auch die entsprechenden Layoutattribute zum Ersetzen linker und rechter Positionen bereit, z. B. android:layout_alignParentStart, um android:layout_alignParentLeft und android:layout_toStartOf anstelle von android:layout_toLeftOf zu ersetzen.

  2. Für eine vollständige Optimierung von RTL-Layouts können Sie auch vollkommen separate Layoutdateien mit dem Ressourcenqualifizierer ldrtl bereitstellen. ldrtl steht für „layout-direction-right-to-left}“. Beispielsweise können Sie Ihre Standardlayoutdateien in res/layout/ und Ihre für RTL optimierten Layouts in res/layout-ldrtl/ speichern.

    Der Qualifizierer ldrtl eignet sich hervorragend für Drawable-Ressourcen. So können Sie Grafiken bereitstellen, die in der Leserichtung ausgerichtet sind.

Im Framework sind verschiedene andere APIs zur Unterstützung von RTL-Layouts verfügbar, z. B. in der Klasse View, damit Sie die richtigen Verhaltensweisen für benutzerdefinierte Ansichten und in Configuration zur Abfrage der aktuellen Layoutrichtung implementieren können.

Hinweis:Wenn Sie SQlite verwenden und Tabellen- oder Spaltennamen mit „Nur Zahlen“ haben, sollten Sie vorsichtig sein: Die Verwendung von String.format(String, Object...) kann zu Fehlern führen, da die Zahlen in ihre arabischen Äquivalente konvertiert wurden, wenn für Ihr Gerät die Sprache Arabisch festgelegt wurde. Sie müssen String.format(Locale,String,Object...) verwenden, damit Zahlen als ASCII beibehalten werden. Verwenden Sie zum Formatieren von Zahlen auch String.format("%d", int) anstelle von String.valueOf(int).

Verschachtelte Fragmente

Sie können jetzt Fragmente in Fragmente einbetten. Dies ist in vielen Situationen nützlich, in denen Sie dynamische und wiederverwendbare UI-Komponenten in eine selbst dynamisch und wiederverwendbare UI-Komponente platzieren möchten. Wenn Sie beispielsweise ViewPager verwenden, um Fragmente zu erstellen, die nach links und rechts wischen und einen Großteil des Bildschirms einnehmen, können Sie jetzt Fragmente auf jeder Fragmentseite einfügen.

Um ein Fragment zu verschachteln, rufen Sie einfach getChildFragmentManager() für die Fragment auf, in der Sie ein Fragment hinzufügen möchten. Dadurch wird ein FragmentManager zurückgegeben, das Sie wie gewohnt bei der Aktivität der obersten Ebene verwenden können, um Fragmenttransaktionen zu erstellen. Hier ist beispielsweise Code, mit dem ein Fragment aus einer vorhandenen Fragment-Klasse hinzugefügt wird:

Kotlin

val videoFragment = VideoPlayerFragment()
childFragmentManager.beginTransaction().apply {
    add(R.id.video_fragment, videoFragment)
    commit()
}

Java

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();

Innerhalb eines verschachtelten Fragments können Sie durch Aufrufen von getParentFragment() einen Verweis auf das übergeordnete Fragment abrufen.

Die Android-Supportbibliothek unterstützt jetzt auch verschachtelte Fragmente, sodass Sie unter Android 1.6 und höher verschachtelte Fragmentdesigns implementieren können.

Hinweis:Sie können ein Layout nicht in ein Fragment überführen, wenn dieses Layout eine <fragment> enthält. Verschachtelte Fragmente werden nur unterstützt, wenn sie einem Fragment dynamisch hinzugefügt werden.

RenderScript

Die Renderscript-Berechnungsfunktion wurde um folgende Funktionen erweitert:

Skriptfunktionen

Mit den integrierten Skriptfunktionen von Renderscript können Sie gängige Operationen implementieren, z. B.:

Wenn Sie ein integriertes Skript verwenden möchten, rufen Sie die statische create()-Methode jeder Datei auf, um eine Instanz des Skripts zu erstellen. Anschließend rufen Sie die verfügbaren set()-Methoden jedes integrierten Skripts auf, um alle erforderlichen Eingaben und Optionen festzulegen. Rufen Sie schließlich die Methode forEach() auf, um das Skript auszuführen.

Skriptgruppen

Mit ScriptGroups lassen sich verwandte Renderscript-Skripts verketten und mit einem Aufruf ausführen.

Verwenden Sie ScriptGroup.Builder, um der Gruppe alle Skripts hinzuzufügen. Rufen Sie dazu addKernel() auf. Nachdem Sie alle Skripts hinzugefügt haben, erstellen Sie die Verbindungen zwischen den Skripts, indem Sie addConnection() aufrufen. Wenn Sie alle Verbindungen hinzugefügt haben, rufen Sie create() auf, um die Skriptgruppe zu erstellen. Legen Sie vor dem Ausführen der Skriptgruppe das Eingabe-Allocation und das ursprüngliche Skript fest, das mit der Methode setInput(Script.KernelID, Allocation) ausgeführt werden soll. Geben Sie außerdem die Ausgabe-Allocation an, in die das Ergebnis geschrieben wird. Das letzte Skript wird dann mit setOutput() ausgeführt. Rufen Sie zuletzt execute() auf, um die Skriptgruppe auszuführen.

Filterscript

Filterscript definiert Einschränkungen für die vorhandenen Renderscript APIs, durch die der resultierende Code auf einer größeren Vielzahl von Prozessoren (CPUs, GPUs und DSPs) ausgeführt werden kann. Erstellen Sie zum Erstellen von Filterscript-Dateien .fs-Dateien anstelle von .rs-Dateien und geben Sie #pragma rs_fp_relaxed an, damit die Renderscript-Laufzeit darüber informiert wird, dass Ihre Skripts keine strikte Gleitkommazahl in IEEE 754-2008 erfordern. Diese Genauigkeit ermöglicht eine Bereinigung auf null für Denorms und eine Rundung auf null. Außerdem dürfen Ihre Filterscript-Skripts keine integrierten 32-Bit-Typen verwenden und müssen mithilfe des Attributs __attribute__((kernel)) eine benutzerdefinierte Stammfunktion angeben, da Filterscript keine Zeiger unterstützt, die durch die Standardsignatur der Funktion root() definiert werden.

Hinweis:Die Filterscript-Unterstützung ist zwar in der Plattform enthalten, Entwickler erhalten aber erst ab SDK-Tools-Version 21.0.1.

Eine detaillierte Ansicht aller API-Änderungen in Android 4.2 finden Sie im Bericht zu API-Unterschieden.