APIs unter Android 4.2

API-Level: 17

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

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

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

Ich APIs in Android 4.2 verwenden und gleichzeitig ältere Versionen unterstützen, indem hinzufügen, die vor der Ausführung auf die API-Ebene des Systems prüfen. APIs werden von deinem minSdkVersion nicht unterstützt. Weitere Informationen über Informationen zur Aufrechterhaltung der Abwärtskompatibilität finden Sie unter Abwärtskompatibilität erstellen Benutzeroberflächen.

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

Wichtige Änderungen am Verhalten

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

  • Contentanbieter werden nicht mehr standardmäßig exportiert. 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 du android:targetSdkVersion oder android:minSdkVersion auf 17 oder höher setzt. 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 Ihre App die Berechtigung ACCESS_COARSE_LOCATION anfordert, aber nicht die Berechtigung ACCESS_FINE_LOCATION.

    Um die Datenschutzerwartungen der Nutzer zu erfüllen, wenn Ihre App Berechtigungen für ungefähren Standort (und keinen genauen Standort) haben, erstellt das System keine Standortschätzung. genauer als ein Häuserblock.

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

    Auch wenn Ihr Wert für android:targetSdkVersion und android:minSdkVersion niedriger als 17 ist, kann Ihre App die Einstellungen nicht ändern, die auf Settings.Global verschoben, wenn das Gerät mit Android 4.2 und höher ausgeführt wird.

  • Wenn deine App WebView verwendet, fügt Android 4.2 eine zusätzliche Sicherheit, damit Sie JavaScript sicherer an Ihre Android-Code. Wenn Sie targetSdkVersion auf 17 oder höher festgelegt haben, müssen Sie jetzt jeder Methode, die für Ihr JavaScript verfügbar sein soll, die @JavascriptInterface-Anmerkung hinzufügen. Die Methode muss außerdem öffentlich sein. Wenn Sie die Anmerkung, diese Methode kann von einer Webseite in WebView nicht aufgerufen werden. wenn sie unter Android 4.2 oder höher laufen. Wenn Sie die targetSdkVersion 16 oder niedriger ist, ist die Anmerkung nicht erforderlich, wir empfehlen jedoch, die Zielversion zu aktualisieren. und fügen Sie die Anmerkung hinzu, um die Sicherheit zu erhöhen.

    Weitere Informationen zum Binden JavaScript-Code in Android-Code umwandeln.

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 sich im inaktiven Zustand befindet, während es an ein Ladegerät angeschlossen ist (anstelle des Ausschaltens des Displays). Daydream zeigt einen Traum nach dem anderen an, ein rein visuelles, passives Display, das sich bei Berührung schließt oder interaktiv und responsiv sein kann zur gesamten Suite von Eingabeereignissen. Dreams werden im Prozess Ihrer App ausgeführt und haben vollen Zugriff auf das Android-UI-Toolkit, einschließlich Ansichten, Layouts und Animationen. Sie sind daher flexibler und leistungsfähiger als Live-Hintergründe oder App-Widgets.

Sie können einen Dream für Daydream erstellen, indem Sie eine untergeordnete Klasse von DreamService implementieren. Die DreamService APIs sind so konzipiert, dass sie denen von Activity ähneln. Wenn Sie die Benutzeroberfläche für Ihren Dream festlegen möchten, übergeben Sie nach dem Öffnen eines Fensters eine Layout-Ressourcen-ID oder View an setContentView(), z. B. über den onAttachedToWindow()-Callback.

Die Klasse DreamService bietet zusätzlich zu den Basis-Service APIs weitere wichtige Lebenszyklus-Callback-Methoden, z. B. onDreamingStarted(), onDreamingStopped() und onDetachedFromWindow(). Sie können keinen DreamService aus Ihrem wird sie 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 zu leiten, um mehr Details oder Einstellungen zu sehen. Sie können finish() verwenden, um den Traum zu beenden, damit der Nutzer die neue Aktivität.

Deklariere DreamService mit einem <service>-Element, um deinen Daydream für das System verfügbar zu machen in Ihrer Manifest-Datei. Sie müssen dann einen Intent-Filter mit der Aktion "android.service.dreams.DreamService" einfügen. Beispiel:

<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>

DreamService bietet noch weitere nützliche Methoden:

  • Mit setInteractive(boolean) wird festgelegt, ob der Dream Input-Ereignisse empfängt oder bei Nutzereingaben sofort beendet wird. Wenn der Traum interaktiv ist, kann der Nutzer die Schaltflächen Zurück oder Start verwenden, um den Traum zu beenden. Du kannst auch finish() aufrufen, um den Traum zu beenden.
  • Wenn Sie das Display vollständig nutzen möchten, können Sie die Statusleiste durch Drücken von setFullscreen() ausblenden.
  • Bevor Daydream gestartet wird, wird das Display gedimmt, um dem Nutzer zu signalisieren, dass die Zeitüberschreitung für die Inaktivität bald erreicht ist. Wenn du setScreenBright(true) aufrufst, kannst du stattdessen die Helligkeit des Displays auf die übliche Helligkeit einstellen.

Weitere Informationen finden Sie in der DreamService-Dokumentation.

Sekundäre Displays

Android ermöglicht es deiner App jetzt, einzigartige Inhalte auf weiteren, verbundenen Bildschirmen anzuzeigen per Kabel oder WLAN mit dem Gerät des Nutzers verbunden. Wenn Sie eindeutige Inhalte für ein sekundäres Display erstellen möchten, erweitern Sie die Presentation-Klasse und implementieren Sie den onCreate()-Callback. Innerhalb von onCreate(), gib deine UI für den sekundären Bildschirm an indem du setContentView() anrufst. Als Erweiterung der Klasse Dialog gibt die Klasse Presentation die Region an, in der Ihre App auf dem sekundären Display eine eindeutige Benutzeroberfläche anzeigen kann.

Wenn Sie sekundäre Displays erkennen möchten, auf denen Sie Ihre Presentation präsentieren können, verwenden Sie entweder die DisplayManager- oder die MediaRouter-API. Mit den DisplayManager APIs können Sie zwar mehrere Bildschirme auflisten, die gleichzeitig angeschlossen sein können, Sie sollten jedoch in der Regel MediaRouter verwenden, um schnell auf das Standarddisplay des Systems für Präsentationen zuzugreifen.

Wenn Sie das Standarddisplay für Ihre Präsentation abrufen möchten, rufen Sie MediaRouter.getSelectedRoute() auf und übergeben Sie ROUTE_TYPE_LIVE_VIDEO. Dadurch wird ein MediaRouter.RouteInfo-Objekt zurückgegeben, das die aktuell ausgewählte Route des Systems beschreibt. für Videopräsentationen. Wenn MediaRouter.RouteInfo nicht null ist, rufe getPresentationDisplay() auf, um die Display für das verbundene Display abzurufen.

Sie können die Präsentation dann anzeigen lassen, indem Sie das Display-Objekt an einen Konstruktor für die Presentation-Klasse übergeben. Ihre Präsentation wird jetzt auf dem sekundären Display angezeigt.

Um während der Laufzeit zu erkennen, wann eine neue Anzeige verbunden wurde, erstellen Sie eine Instanz von MediaRouter.SimpleCallback, in der Sie die Callback-Methode onRoutePresentationDisplayChanged() implementieren, die das System aufruft, wenn ein neues Display Präsentationsdisplay ist verbunden. 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 auf onRoutePresentationDisplayChanged() erhalten, rufen Sie einfach MediaRouter.getSelectedRoute() an, wie oben beschrieben.

Wenn Sie die Benutzeroberfläche in Ihrer 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 mit dem Gerät der Nutzenden verbundene Bildschirme oft eine größere Bildschirmgröße haben und wahrscheinlich eine andere Bildschirmdichte. Da die Bildschirmmerkmale unterschiedlich sein können, sollten Sie stellen Ressourcen bereit, die speziell für solche größeren Bildschirme optimiert sind. Bei Bedarf Wenn Sie zusätzliche Ressourcen von Ihrem Presentation anfordern möchten, rufen Sie getContext().getResources() auf, um das Resources-Objekt für die Anzeige abzurufen. Damit erhalten Sie Ressourcen aus Ihrer App, die sich am besten für das die Bildschirmgröße und -dichte des sekundären Bildschirms.

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

Sperrbildschirm-Widgets

Unter Android können Nutzer jetzt App-Widgets zum Sperrbildschirm hinzufügen. Wenn Sie Ihr App-Widget auf dem Sperrbildschirm verwenden möchten, fügen Sie Ihrer XML-Datei das Attribut android:widgetCategory hinzu, das die AppWidgetProviderInfo angibt. Dieses Attribut unterstützt zwei Werte: home_screen und keyguard. Standardmäßig ist das Attribut auf home_screen festgelegt, damit Nutzer Ihr App-Widget dem Startbildschirm hinzufügen können. Wenn Ihr 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>

Sie sollten auch ein Anfangslayout für Ihr App-Widget auf dem Sperrbildschirm mit dem Attribut android:initialKeyguardLayout angeben. Das funktioniert genauso wie das android:initialLayout, da sie Folgendes bereitstellt: ein Layout, das sofort angezeigt werden kann, bis Ihr App-Widget initialisiert ist und in der Lage ist, Layout.

Weitere Informationen zum Erstellen von App-Widgets für den Sperrbildschirm die Größe des App-Widgets auf dem Sperrbildschirm anpassen. Weitere Informationen

Mehrere Nutzer

Android erlaubt nun mehrere Nutzerbereiche auf gemeinsam nutzbaren Geräten wie Tablets. Jeder Nutzer einer Gerät verfügt über eigene Konten, Apps, Systemeinstellungen, Dateien und andere nutzerbezogenen Daten.

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

Daten in einer Umgebung mit mehreren Nutzern speichern

Immer wenn Ihre App Nutzereinstellungen speichert, eine Datenbank erstellt oder eine Datei im internen oder externen Speicherplatz haben, sind diese Daten nur verfügbar, wenn sie als dieser Nutzer ausgeführt werden.

Damit Ihre App in einer Umgebung mit mehreren Nutzern ordnungsgemäß funktioniert, sollten Sie nicht über hartcodierte Pfade auf Ihr internes App-Verzeichnis oder Ihren externen Speicherort verweisen, sondern immer die entsprechenden APIs verwenden:

Unabhängig davon, welche dieser APIs Sie zum Speichern von Daten für einen bestimmten Nutzer verwenden, werden die Daten nicht wenn sie unter einem anderen Nutzer ausgeführt werden. Aus der Sicht Ihrer App führt jeder Nutzer auf einem völlig anderen Gerät.

Nutzer in einer Umgebung mit mehreren Nutzern identifizieren

Wenn Sie in Ihrer App einzelne Nutzer identifizieren möchten, um beispielsweise Analysen zu erheben oder andere Kontoverknüpfungen zu erstellen, sollten Sie die empfohlenen Praktiken zur Identifizierung einzelner Installationen befolgen. Wenn Sie beim ersten Start Ihrer App eine neue UUID erstellen, erhalten Sie eine eindeutige ID für die Verfolgung jedes Nutzers, unabhängig davon, wie viele Nutzer Ihre App auf einem einzelnen Gerät installieren. Alternativ können Sie ein lokales Token speichern, das von Ihrem Server abgerufen wurde, oder die Registrierungs-ID von Google Cloud Messaging verwenden.

Wenn Ihre App eine der Hardwaregeräte-IDs (z. B. WLAN-MAC) anfordert, Adresse oder die SERIAL-Nummer), geben sie für jede Telefonnummer den gleichen Wert an da diese mit der Hardware und nicht mit dem Nutzer verknüpft sind. Ganz zu schweigen von den anderen Problemen, die diese IDs mit sich bringen, wie im Blogpost App-Installationen identifizieren beschrieben.

Neue globale Einstellungen

Die Systemeinstellungen wurden aktualisiert, sodass jetzt mehrere Nutzer unterstützt werden. Settings.Global wurde hinzugefügt. Diese Einstellungen ähneln den Settings.Secure-Einstellungen, da sie nur lesbar 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), funktionieren diese Änderungen auf Geräten mit Android 4.2 oder höher möglicherweise nicht mehr, wenn diese Einstellungen zu Settings.Global verschoben wurden. Sie können weiterhin Einstellungen in Settings.Global lesen. Da die Einstellungen jedoch nicht mehr als sicher für die Änderung durch Apps eingestuft werden, schlägt ein entsprechender Versuch stumm 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 linksläufiges Layout

Android bietet jetzt mehrere APIs, mit denen Sie Benutzeroberflächen erstellen können, Anpassen der Layoutausrichtung zur Unterstützung von Sprachen, die von rechts nach links gelesene UIs und Lesefunktionen verwenden wie Arabisch und Hebräisch.

Um RTL-Layouts in deiner App zu unterstützen, setze das Attribut android:supportsRtl in deiner Manifestdatei auf das Element <application> und lege ihn auf “true" fest. Wenn Sie diese Option aktivieren, werden verschiedene RTL-APIs aktiviert, um Ihre App mit RTL-Layouts anzuzeigen. In der Aktionsleiste werden beispielsweise das Symbol und der Titel auf der rechten Seite und die Aktionsschaltflächen auf der linken Seite angezeigt. Alle Layouts, die Sie mit den vom Framework bereitgestellten View-Klassen erstellt haben, werden ebenfalls umgekehrt.

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

  1. Links- und rechtsorientierte Layouteigenschaften in start- und endorientiertes Layout umwandeln Eigenschaften.

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

    Die Klasse RelativeLayout bietet auch die entsprechenden Layoutattribute, um die Positionen „links“ und „rechts“ zu ersetzen, z. B. android:layout_alignParentStart anstelle von android:layout_alignParentLeft und android:layout_toStartOf anstelle von android:layout_toLeftOf.

  2. Für eine vollständige Optimierung von RTL-Layouts können Sie auch komplett separate Layoutdateien, die den Ressourcenqualifizierer ldrtl verwenden (ldrtl steht für Layout-direction-right-to-left}). Sie können beispielsweise Ihre Standardlayoutdateien in res/layout/ und Ihre für RTL optimierten Layouts in res/layout-ldrtl/ speichern.

    Der ldrtl-Qualifikator eignet sich hervorragend für Zeichnenstile. So können Sie Grafiken bereitstellen, die in der Richtung ausgerichtet sind, die der Leserichtung entspricht.

Verschiedene weitere APIs stehen im Framework zur Verfügung, um RTL-Layouts zu unterstützen, z. B. View, damit Sie die richtigen Verhaltensweisen für benutzerdefinierte und in Configuration, um die aktuelle Layoutrichtung abzufragen.

Hinweis: Wenn Sie SQlite verwenden und Tabellen- oder Spaltennamen vorhanden sind, die „nur Zahl“, sein Achtung: Die Verwendung von String.format(String, Object...) kann zu Fehlern führen, da die Zahlen in ihre arabischen Entsprechungen umgewandelt, wenn auf Ihrem Gerät die arabische Sprache eingestellt wurde. Sie müssen String.format(Locale,String,Object...) verwenden, damit die Zahlen als ASCII beibehalten. Verwenden Sie zum Formatieren von Zahlen außerdem String.format("%d", int) anstelle von String.valueOf(int).

Verschachtelte Fragmente

Sie können jetzt Fragmente in Fragmente einbetten. Dies ist in einer Vielzahl von Situationen nützlich, in denen Sie dynamische und wiederverwendbare UI-Komponenten in eine UI-Komponente einfügen möchten, die selbst dynamisch und wiederverwendbar ist. Wenn Sie beispielsweise mit ViewPager Fragmente erstellen, die nach links und rechts wischen und den Großteil des Bildschirms einnehmen, können Sie jetzt Fragmente in jede Fragmentseite einfügen.

Um ein Fragment zu verschachteln, rufen Sie einfach getChildFragmentManager() auf Die Fragment, in die Sie ein Fragment einfügen möchten. Dadurch wird ein FragmentManager zurückgegeben, das du wie gewohnt über die Aktivität der obersten Ebene verwenden kannst, um Fragmenttransaktionen zu erstellen. Hier ist beispielsweise Code, mit dem ein Fragment innerhalb 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 über getParentFragment() einen Verweis auf das übergeordnete Fragment abrufen.

Die Android-Unterstützungsbibliothek unterstützt jetzt auch verschachtelte Fragmente. Sie können also verschachtelte Fragmentdesigns unter Android 1.6 und höher implementieren.

Hinweis: Sie können ein Layout nicht in ein Fragment aufblähen, wenn es ein <fragment> enthält. Verschachtelte Fragmente werden nur unterstützt, wenn sie einem dynamisch fragmentiert.

RenderScript

Die Renderscript-Berechnungsfunktionen wurden um folgende Funktionen erweitert:

Intrinsische Scripts

Sie können die integrierten Skript-Intrinsiken von Renderscript nutzen, gängige Abläufe für Sie, wie zum Beispiel:

Um ein intrinsisches Skript zu verwenden, rufen Sie die statische create()-Methode jedes einzelnen um eine Instanz des Skripts zu erstellen. Anschließend rufen Sie die verfügbare set() auf. jedes intrinsische Skript, um die notwendigen Eingaben und Optionen festzulegen. Rufen Sie abschließend forEach() auf. zum Ausführen des Skripts.

Skriptgruppen

Mit ScriptGroups kannst du verwandte Renderscripts miteinander verketten. und führen sie mit einem Aufruf aus.

Verwenden Sie ein ScriptGroup.Builder, um der Gruppe alle Scripts hinzuzufügen, indem Sie addKernel() aufrufen. Nachdem Sie alle Scripts hinzugefügt haben, erstellen Sie die Verbindungen zwischen den Scripts, indem Sie addConnection() aufrufen. Wenn Sie alle Verbindungen hinzugefügt haben, rufen Sie create() auf um die Skriptgruppe zu erstellen. Geben Sie vor dem Ausführen der Skriptgruppe die Eingabe an Allocation und erstes Skript für die Ausführung mit dem setInput(Script.KernelID, Allocation)-Methode und geben Sie die Ausgabe an Allocation, in den das Ergebnis geschrieben wird, und das endgültige Skript in mit setOutput() durchführen. Rufen Sie schließlich execute(), um die Skriptgruppe auszuführen.

Filterscript

Filterscript definiert Einschränkungen für die vorhandenen Renderscript APIs, die es ermöglichen, den resultierenden Code auf einer größeren Vielfalt von Prozessoren (CPUs, GPUs und DSPs) auszuführen. Wenn Sie Filterscriptdateien erstellen möchten, erstellen Sie .fs-Dateien anstelle von .rs-Dateien und geben Sie #pragma rs_fp_relaxed an, um der Renderscript-Laufzeit mitzuteilen, dass Ihre Scripts keine strenge IEEE 754-2008-Gleitkommapräzision erfordern. Diese Genauigkeit ermöglicht eine Leerung auf null für Denorme und das Runden in Richtung Null. Außerdem kann Ihr Filterscript Skripte dürfen keine integrierten 32-Bit-Typen verwenden und müssen mithilfe der Methode __attribute__((kernel))-Attribut, da Filterscript keine Cursor unterstützt, die die Standardsignatur der Funktion root().

Hinweis:Filterscript wird zwar in der Plattform unterstützt, Unterstützung wird in SDK Tools Version 21.0.1 verfügbar sein.

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