APIs unter Android 4.1

API-Level: 16

Android 4.1 (JELLY_BEAN) ist eine Weiterentwicklung der Plattform, die sowohl Leistung als auch Nutzerfreundlichkeit verbessert. Sie bietet neue Funktionen für Nutzer und App-Entwickler. Dieses Dokument bietet eine Einführung in die wichtigsten und nützlichsten neuen APIs für App-Entwickler.

Als App-Entwickler steht Ihnen Android 4.1 über den SDK-Manager als System-Image zur Verfügung, das Sie im Android-Emulator und als SDK-Plattform ausführen können, mit der Sie Ihre App erstellen können. Laden Sie das System-Image und die Plattform so schnell wie möglich herunter, um Ihre App unter Android 4.1 zu erstellen und zu testen.

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

Sie können APIs in Android 4.1 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?

Anwendungskomponenten

Isolierte Dienste

Wenn Sie android:isolatedProcess="true" im <service>-Tag angeben, wird Service mit einem eigenen isolierten Nutzer-ID-Prozess ausgeführt, der keine eigenen Berechtigungen hat.

Speicherverwaltung

Neue ComponentCallbacks2-Konstanten wie TRIM_MEMORY_RUNNING_LOW und TRIM_MEMORY_RUNNING_CRITICAL liefern Vordergrundprozesse mehr Informationen zum Arbeitsspeicherstatus, bevor das System onLowMemory() aufruft.

Mit der neuen Methode getMyMemoryState(ActivityManager.RunningAppProcessInfo) können Sie den allgemeinen Arbeitsspeicherstatus abrufen.

Contentanbieter

Mit der neuen Methode acquireUnstableContentProviderClient() kannst du auf eine ContentProviderClient zugreifen, die möglicherweise „instabil“ ist, sodass deine App nicht abstürzt, wenn der Contentanbieter dies tut. Das ist nützlich, wenn Sie mit Contentanbietern in einer separaten App interagieren.

Live-Hintergründe

Neues Intent-Protokoll zum direkten Starten der Vorschau für den Live-Hintergrund, damit Nutzer den Live-Hintergrund einfach auswählen können, ohne dass sie deine App verlassen und durch die Auswahl für den Startbildschirm navigieren müssen.

Um die Auswahl für den Live-Hintergrund zu starten, rufe startActivity() mit einem Intent auf, indem du ACTION_CHANGE_LIVE_WALLPAPER und ein weiteres Element verwendest, das deinen Live-Hintergrund ComponentName als String in EXTRA_LIVE_WALLPAPER_COMPONENT angibt.

Navigation im App-Stack

Mit Android 4.1 ist es viel einfacher, die richtigen Designmuster für die Nach-oben-Navigation zu implementieren. Du musst lediglich jedem <activity>-Element in der Manifestdatei das android:parentActivityName-Element hinzufügen. Das System verwendet diese Informationen, um die entsprechende Aktivität zu öffnen, wenn der Nutzer die Schaltfläche „Nach oben“ in der Aktionsleiste drückt. Gleichzeitig wird die aktuelle Aktivität beendet. Wenn Sie also android:parentActivityName für jede Aktivität deklarieren, benötigen Sie die Methode onOptionsItemSelected() nicht, um Klickereignisse auf dem App-Symbol der Aktionsleiste zu verarbeiten. Das System verarbeitet dieses Ereignis jetzt und setzt die entsprechende Aktivität fort oder erstellt sie.

Dies ist besonders nützlich bei Szenarien, in denen der Nutzer eine der Aktivitäten Ihrer App über einen detaillierten Intent eingibt, z. B. über eine Benachrichtigung oder einen Intent von einer anderen App (wie in der Designanleitung unter Zwischen Apps navigieren beschrieben). Wenn der Nutzer Ihre Aktivität auf diese Weise eingibt, verfügt Ihre Anwendung möglicherweise nicht über einen Back-Stack von Aktivitäten, die fortgesetzt werden können, während der Nutzer nach oben navigiert. Wenn Sie jedoch das Attribut android:parentActivityName für Ihre Aktivitäten angeben, erkennt das System, ob Ihre App bereits einen Back-Stack übergeordneter Aktivitäten enthält, und erstellt, falls nicht, einen synthetischen Back-Stack, der alle übergeordneten Aktivitäten enthält.

Hinweis: Wenn der Nutzer in Ihrer App eine intensive Aktivität eingibt und eine neue Aufgabe für die App erstellt, fügt das System den Stapel übergeordneter Aktivitäten in die Aufgabe ein. Durch Drücken der Zurück-Taste können Sie somit auch zurück durch den Stapel übergeordneter Aktivitäten blättern.

Wenn das System einen synthetischen Back-Stack für Ihre App erstellt, erstellt es eine einfache Intent, um eine neue Instanz jeder übergeordneten Aktivität zu erstellen. Es gibt also keinen gespeicherten Status für die übergeordneten Aktivitäten, wie Sie es vom Nutzer erwarten würden, wenn er die einzelnen Aktivitäten natürlich durchläuft. Wenn eine der übergeordneten Aktivitäten normalerweise eine UI anzeigt, die vom Kontext des Nutzers abhängig ist, fehlen diese Kontextinformationen. Sie sollten sie bereitstellen, wenn der Nutzer im Stapel zurückkehrt. Wenn sich ein Nutzer beispielsweise ein Album in einer Musik-App ansieht und er nach oben navigiert, gelangt er zu einer Aktivität, in der alle Alben eines ausgewählten Musikgenres aufgelistet sind. Wenn in diesem Fall der Stapel erstellt werden muss, müssen Sie der übergeordneten Aktivität mitteilen, zu welchem Genre das aktuelle Album gehört, damit das übergeordnete Element die richtige Liste anzeigen kann, als ob der Nutzer tatsächlich von dieser Aktivität stammt. Wenn Sie solche Informationen an eine synthetische übergeordnete Aktivität senden möchten, müssen Sie die Methode onPrepareNavigateUpTaskStack() überschreiben. Dadurch erhalten Sie ein TaskStackBuilder-Objekt, das vom System erstellt wurde, um die übergeordneten Aktivitäten zu synthetisieren. Das TaskStackBuilder enthält Intent-Objekte, mit denen das System die einzelnen übergeordneten Aktivitäten erstellt. Bei der Implementierung von onPrepareNavigateUpTaskStack() können Sie die entsprechende Intent ändern, um zusätzliche Daten hinzuzufügen. Die übergeordnete Aktivität kann dann den entsprechenden Kontext ermitteln und die entsprechende UI anzeigen.

Wenn das System die TaskStackBuilder erstellt, werden die Intent-Objekte zum Erstellen der übergeordneten Aktivitäten in ihrer logischen Reihenfolge hinzugefügt, beginnend am Anfang der Aktivitätsstruktur. Der letzte Intent, der dem internen Array hinzugefügt wurde, ist also das direkte übergeordnete Element der aktuellen Aktivität. Wenn Sie die Intent für die übergeordnete Aktivität ändern möchten, ermitteln Sie zuerst die Länge des Arrays mit getIntentCount() und übergeben Sie diesen Wert an editIntentAt().

Wenn Ihre Anwendungsstruktur komplexer ist, stehen mehrere andere APIs zur Verfügung, mit denen Sie das Verhalten der Nach-oben-Navigation steuern und den synthetischen Back-Stack vollständig anpassen können. Zu den APIs mit zusätzlichen Kontrollen gehören unter anderem:

onNavigateUp()
Wenn Sie diese Einstellung überschreiben, wird eine benutzerdefinierte Aktion ausgeführt, wenn der Nutzer auf die Schaltfläche „Nach oben“ drückt.
navigateUpTo(Intent)
Hiermit wird die aktuelle Aktivität beendet und zur im angegebenen Intent angegebenen Aktivität gewechselt. Wenn die Aktivität im Back-Stack vorhanden ist, aber nicht die nächste übergeordnete Aktivität ist, werden auch alle anderen Aktivitäten zwischen der aktuellen Aktivität und der mit dem Intent angegebenen Aktivität beendet.
getParentActivityIntent()
Mit diesem Aufruf erhalten Sie das Intent-Element, mit dem das logische übergeordnete Element für die aktuelle Aktivität gestartet wird.
shouldUpRecreateTask(Intent)
Mit dieser Option können Sie abfragen, ob ein synthetischer Back-Stack erstellt werden muss, um nach oben zu wechseln. Gibt „true“ zurück, wenn ein synthetischer Stack erstellt werden muss, und „false“, wenn der entsprechende Stack bereits vorhanden ist.
finishAffinity()
Rufen Sie diese Option auf, um die aktuelle Aktivität und alle übergeordneten Aktivitäten mit derselben Aufgabenaffinität, die an die aktuelle Aktivität verkettet sind, abzuschließen. Wenn Sie die Standardverhalten wie onNavigateUp() überschreiben, sollten Sie diese Methode aufrufen, wenn Sie beim Erstellen eines synthetischen Back-Stacks in der Nach-oben-Navigation einen synthetischen Back-Stack erstellen.
onCreateNavigateUpTaskStack
Überschreiben Sie diese Einstellung, wenn Sie die Erstellung des synthetischen Task-Stacks vollständig kontrollieren müssen. Wenn Sie den Intents für Ihren Back-Stack einfach zusätzliche Daten hinzufügen möchten, sollten Sie stattdessen onPrepareNavigateUpTaskStack() überschreiben.

Die meisten Apps benötigen diese APIs jedoch nicht und implementieren onPrepareNavigateUpTaskStack() nicht. Das richtige Verhalten lässt sich jedoch erzielen, indem Sie jedem <activity>-Element android:parentActivityName hinzufügen.

Multimedia

Medien-Codecs

Die Klasse MediaCodec bietet Zugriff auf Low-Level-Medien-Codecs zum Codieren und Decodieren Ihrer Medien. Sie können ein MediaCodec instanziieren, indem Sie createEncoderByType() zum Codieren von Medien oder createDecoderByType() aufrufen, um Medien zu decodieren. Jede dieser Methoden verwendet einen MIME-Typ für den Medientyp, den Sie codieren oder decodieren möchten, z. B. "video/3gpp" oder "audio/vorbis".

Nachdem eine Instanz von MediaCodec erstellt wurde, können Sie dann configure() aufrufen, um Attribute wie das Medienformat oder anzugeben, ob der Inhalt verschlüsselt ist.

Unabhängig davon, ob Sie Ihre Medien codieren oder decodieren, ist der Rest des Vorgangs der gleiche, nachdem Sie das MediaCodec erstellt haben. Rufen Sie zuerst getInputBuffers() auf, um ein Array von ByteBuffer-Eingabeobjekten zu erhalten, und getOutputBuffers(), um ein Array von ByteBuffer-Ausgabeobjekten zu erhalten.

Wenn Sie bereit zum Codieren oder Decodieren sind, rufen Sie dequeueInputBuffer() auf, um die Indexposition des ByteBuffer (aus dem Array der Eingabezwischenspeicher) abzurufen, den Sie für den Feed in Ihrem Quellmedium verwenden sollten. Nachdem Sie ByteBuffer mit dem Quellmedium gefüllt haben, geben Sie die Inhaberschaft des Zwischenspeichers frei, indem Sie queueInputBuffer() aufrufen.

Ebenso können Sie für den Ausgabezwischenspeicher dequeueOutputBuffer() aufrufen, um die Indexposition von ByteBuffer abzurufen, wo Sie die Ergebnisse erhalten. Nachdem Sie die Ausgabe aus dem ByteBuffer gelesen haben, geben Sie die Inhaberschaft durch Aufrufen von releaseOutputBuffer() frei.

Sie können verschlüsselte Mediendaten in den Codecs verarbeiten, indem Sie queueSecureInputBuffer() anstelle des normalen queueInputBuffer() in Verbindung mit den MediaCrypto APIs aufrufen.

Weitere Informationen zur Verwendung von Codecs finden Sie in der MediaCodec-Dokumentation.

Audio am Cue aufnehmen

Mit der neuen Methode startRecording() können Sie die Audioaufnahme basierend auf einem durch MediaSyncEvent definierten Hinweis starten. Das MediaSyncEvent gibt eine Audiositzung an (z. B. eine, die durch MediaPlayer definiert ist). Wenn der Vorgang abgeschlossen ist, beginnt der Audiorekorder mit der Aufzeichnung. Sie können diese Funktion beispielsweise verwenden, um einen Ton abzuspielen, der den Beginn einer Aufnahmesitzung anzeigt und die Aufnahme automatisch beginnt, sodass Sie Ton und Beginn der Aufnahme nicht manuell synchronisieren müssen.

Zeitgesteuerte Texttracks

MediaPlayer verarbeitet jetzt sowohl In-Band- als auch Out-of-Band-Texttracks. In-Band-Textspuren sind Textspuren in einer MP4- oder 3GPP-Medienquelle. Out-of-Band-Textspuren können als externe Textquelle über die Methode addTimedTextSource() hinzugefügt werden. Nachdem alle externen Textspurquellen hinzugefügt wurden, sollte getTrackInfo() aufgerufen werden, um die aktualisierte Liste aller verfügbaren Tracks in einer Datenquelle abzurufen.

Um den Track festzulegen, der mit MediaPlayer verwendet werden soll, müssen Sie selectTrack() unter Verwendung der Indexposition für den zu verwendenden Track aufrufen.

Wenn Sie benachrichtigt werden möchten, wenn der Text-Track abgespielt werden kann, implementieren Sie die MediaPlayer.OnTimedTextListener-Schnittstelle und übergeben Sie sie an setOnTimedTextListener().

Audio-Effekte

Die Klasse AudioEffect unterstützt jetzt zusätzliche Typen zur Audiovorverarbeitung bei der Audioaufnahme:

  • Acoustic Echo Deleteer (AEC) mit AcousticEchoCanceler entfernt den Beitrag des von der Remote-Party empfangenen Signals zum aufgenommenen Audiosignal.
  • Die automatische Verstärkungsregelung (Automatic Gain Control, AGC) mit AutomaticGainControl normalisiert die Ausgabe des erfassten Signals automatisch.
  • Mit dem Noise Suppressor (NS) mit NoiseSuppressor werden Hintergrundgeräusche aus dem erfassten Signal entfernt.

Sie können diese Präprozessor-Effekte auf das mit einem AudioRecord aufgenommene Audio anwenden. Verwenden Sie dazu eine der untergeordneten AudioEffect-Klassen.

Hinweis:Es kann nicht garantiert werden, dass alle Geräte diese Effekte unterstützen. Sie sollten daher immer zuerst die Verfügbarkeit prüfen, indem Sie isAvailable() für die entsprechende Audioeffektklasse aufrufen.

Lückenlose Wiedergabe

Sie können jetzt eine lückenlose Wiedergabe zwischen zwei separaten MediaPlayer-Objekten ausführen. Wenn der erste MediaPlayer beendet ist, können Sie jederzeit setNextMediaPlayer() aufrufen. Android versucht dann, den zweiten Spieler in dem Moment zu starten, in dem der erste aufhört.

Medienrouter. Die neuen APIs MediaRouter, MediaRouteActionProvider und MediaRouteButton bieten Standardmechanismen und UI für die Auswahl, wo Medien wiedergegeben werden.

Kamera

Bewegung mit Autofokus

Über die neue Benutzeroberfläche Camera.AutoFocusMoveCallback kannst du auf Änderungen der Autofokusbewegung warten. Sie können Ihre Schnittstelle bei setAutoFocusMoveCallback() registrieren. Wenn sich die Kamera im kontinuierlichen Autofokusmodus (FOCUS_MODE_CONTINUOUS_VIDEO oder FOCUS_MODE_CONTINUOUS_PICTURE) befindet, erhalten Sie einen Aufruf von onAutoFocusMoving(). Dieser gibt an, ob der Autofokus sich bewegt oder aufgehört hat.

Kameratöne

Die Klasse MediaActionSound bietet einen einfachen Satz von APIs zum Erzeugen von Standardtönen, die von der Kamera oder anderen Medienaktionen erzeugt werden. Sie sollten diese APIs verwenden, um beim Erstellen eines benutzerdefinierten Standbilds oder einer Videokamera den entsprechenden Ton abzuspielen.

Zur Wiedergabe eines Tons instanziieren Sie einfach ein MediaActionSound-Objekt. Rufen Sie dann load() auf, um den gewünschten Ton vorab zu laden, und rufen Sie dann zum entsprechenden Zeitpunkt play() auf.

Konnektivität

Android Beam

Android BeamTM unterstützt jetzt die Übertragung großer Nutzlasten über Bluetooth. Wenn Sie die zu übertragenden Daten entweder mit der neuen setBeamPushUris()-Methode oder der neuen Callback-Schnittstelle NfcAdapter.CreateBeamUrisCallback definieren, übergibt Android die Datenübertragung an Bluetooth oder eine andere alternative Übertragung, um schnellere Übertragungsgeschwindigkeiten zu erzielen. Dies ist besonders nützlich bei großen Nutzlasten wie Bild- und Audiodateien und erfordert keine sichtbare Kopplung zwischen den Geräten. Deine App muss nichts weiter tun, um die Übertragung über Bluetooth nutzen zu können.

Die Methode setBeamPushUris() verwendet ein Array von Uri-Objekten, die die Daten angeben, die Sie von der Anwendung übertragen möchten. Alternativ können Sie die Schnittstelle NfcAdapter.CreateBeamUrisCallback implementieren, die Sie für Ihre Aktivität durch Aufrufen von setBeamPushUrisCallback() angeben können.

Bei Verwendung der Callback-Schnittstelle ruft das System die Methode createBeamUris() der Schnittstelle auf, wenn der Nutzer eine Freigabe mit Android Beam ausführt, sodass Sie die URIs definieren können, die zur Freigabezeit geteilt werden sollen. Dies ist nützlich, wenn die zu teilenden URIs je nach Nutzerkontext in der Aktivität variieren können. Das Aufrufen von setBeamPushUris() ist hingegen sinnvoll, wenn sich die zu teilenden URIs nicht ändern und Sie sie im Voraus sicher definieren können.

Diensterkennung

Android 4.1 unterstützt jetzt die DNS-basierte Multicast-Diensterkennung, mit der Sie Dienste suchen und eine Verbindung zu Diensten herstellen können, die von Peer-Geräten über WLAN angeboten werden, z. B. Mobilgeräte, Drucker, Kameras, Mediaplayer und andere, die im lokalen Netzwerk registriert sind.

Das neue Paket android.net.nsd enthält die neuen APIs, mit denen Sie Ihre Dienste über das lokale Netzwerk übertragen, lokale Geräte im Netzwerk erkennen und eine Verbindung zu Geräten herstellen können.

Wenn Sie Ihren Dienst registrieren möchten, müssen Sie zuerst ein NsdServiceInfo-Objekt erstellen und die verschiedenen Attribute des Dienstes mit Methoden wie setServiceName(), setServiceType() und setPort() definieren.

Anschließend müssen Sie NsdManager.RegistrationListener implementieren und mit Ihrem NsdServiceInfo an registerService() übergeben.

Implementieren Sie NsdManager.DiscoveryListener und übergeben Sie es an discoverServices(), um Dienste im Netzwerk zu finden.

Wenn das NsdManager.DiscoveryListener Callbacks zu gefundenen Diensten empfängt, müssen Sie den Dienst auflösen. Dazu rufen Sie resolveService() auf und übergeben ihm eine Implementierung von NsdManager.ResolveListener, die ein NsdServiceInfo-Objekt mit Informationen zum erkannten Dienst empfängt, mit dem Sie die Verbindung initiieren können.

WLAN-P2P-Diensterkennung

Die Wi-Fi P2P APIs wurden in Android 4.1 optimiert, um die Erkennung von Diensten vor der Verknüpfung in WifiP2pManager zu unterstützen. So können Sie Geräte in der Nähe über Wi-Fi P2P ermitteln und filtern, bevor Sie eine Verbindung zu einem herstellen. Mit der Netzwerkdiensterkennung können Sie einen Dienst in einem vorhandenen verbundenen Netzwerk (z. B. einem lokalen WLAN) ermitteln.

Wenn du deine App als Dienst über WLAN übertragen möchtest, damit andere Geräte deine App finden und eine Verbindung dazu herstellen können, rufe addLocalService() mit einem WifiP2pServiceInfo-Objekt auf, das deine App-Dienste beschreibt.

Damit Geräte in der Nähe über WLAN gefunden werden können, müssen Sie zuerst entscheiden, ob Sie über Bonjour oder Upnp kommunizieren. Wenn du Bonjour verwenden möchtest, musst du zuerst einige Callback-Listener mit setDnsSdResponseListeners() einrichten, für das sowohl WifiP2pManager.DnsSdServiceResponseListener als auch WifiP2pManager.DnsSdTxtRecordListener verwendet werden. Wenn Sie Upnp verwenden möchten, rufen Sie setUpnpServiceResponseListener() auf. Dafür wird ein WifiP2pManager.UpnpServiceResponseListener-Wert benötigt.

Bevor Sie Dienste auf lokalen Geräten finden können, müssen Sie auch addServiceRequest() aufrufen. Wenn das an diese Methode übergebene WifiP2pManager.ActionListener einen erfolgreichen Callback empfängt, können Sie discoverServices() aufrufen, um Dienste auf lokalen Geräten zu finden.

Wenn lokale Dienste gefunden werden, erhalten Sie einen Callback von WifiP2pManager.DnsSdServiceResponseListener oder WifiP2pManager.UpnpServiceResponseListener, je nachdem, ob Sie sich für die Verwendung von Bonjour oder Upnp registriert haben. Der in beiden Fällen empfangene Callback enthält ein WifiP2pDevice-Objekt, das das Peer-Gerät darstellt.

Netzwerknutzung

Mit der neuen Methode isActiveNetworkMetered() können Sie prüfen, ob das Gerät derzeit mit einem kostenpflichtigen Netzwerk verbunden ist. Indem Sie diesen Status überprüfen, bevor Sie intensive Netzwerktransaktionen ausführen, können Sie die Datennutzung verwalten, die für Ihre Nutzer möglicherweise Geld kosten kann, und fundierte Entscheidungen darüber treffen, ob die Transaktionen jetzt oder später ausgeführt werden sollen, z. B. wenn das Gerät mit einem WLAN verbunden wird.

Barrierefreiheit

Accessibility Service APIs

Die Reichweite von Bedienungshilfen-APIs wurde in Android 4.1 deutlich erhöht. Sie können jetzt Dienste erstellen, die weitere Eingabeereignisse überwachen und darauf reagieren, z. B. komplexe Gesten mit onGesture() und anderen Eingabeereignissen, indem sie die Klassen AccessibilityEvent, AccessibilityNodeInfo und AccessibilityRecord hinzufügen.

Bedienungshilfen können auch Aktionen im Namen des Nutzers ausführen, z. B. Klicken, Scrollen und Scrollen durch Text mithilfe von performAction und setMovementGranularities. Mit der Methode performGlobalAction() können Dienste auch Aktionen wie „Zurück“ und „Startbildschirm“ ausführen sowie zuletzt verwendete Apps und Benachrichtigungen öffnen.

Anpassbare App-Navigation

Beim Erstellen einer Android-App können Sie jetzt Navigationsschemas anpassen, indem Sie mit findFocus() und focusSearch() nach fokussierbaren Elementen und Eingabe-Widgets suchen und den Fokus mit setAccessibilityFocused() festlegen.

Besser zugängliche Widgets

Mit der neuen Klasse android.view.accessibility.AccessibilityNodeProvider können Sie komplexe benutzerdefinierte Ansichten für Bedienungshilfen aufrufen, um die Informationen auf zugänglichere Weise zu präsentieren. Mit android.view.accessibility.AccessibilityNodeProvider kann ein Nutzerwidget mit erweiterten Inhalten, z. B. einem Kalenderraster, eine logische semantische Struktur für Bedienungshilfendienste darstellen, die vollständig von der Layoutstruktur des Widgets getrennt ist. Mit dieser semantischen Struktur können Bedienungshilfen ein nützlicheres Interaktionsmodell für sehbehinderte Nutzer bieten.

Copy and Paste

Mit Intents kopieren und einfügen

Mit der Methode setClipData() können Sie jetzt ein ClipData-Objekt mit einem Intent verknüpfen. Dies ist besonders nützlich, wenn Sie mit einem Intent mehrere content:-URIs an eine andere Anwendung übertragen möchten, z. B. bei der Freigabe mehrerer Dokumente. Die so angegebenen content:-URIs berücksichtigen auch die Flags des Intents und bieten damit Lese- oder Schreibzugriff, sodass Sie mehreren URIs in einem Intent Zugriff gewähren können. Beim Starten eines ACTION_SEND- oder ACTION_SEND_MULTIPLE-Intents werden die im Intent angegebenen URIs jetzt automatisch an ClipData weitergegeben, damit der Empfänger Zugriff darauf erhält.

Unterstützung von HTML- und String-Stilen

Die Klasse ClipData unterstützt jetzt Text mit benutzerdefinierten Stilen (entweder als HTML- oder als Android-Strings). Mit newHtmlText() können Sie dem ClipData Text im HTML-Stil hinzufügen.

RenderScript

Die Renderscript-Berechnungsfunktion wurde um folgende Funktionen erweitert:

  • Unterstützung mehrerer Kernel in einem Skript.
  • Unterstützung für das Lesen aus der Zuweisung mit gefilterten Samplern aus Computing-Ressourcen in der neuen Skript-API rsSample.
  • Unterstützung verschiedener Ebenen der FP-Genauigkeit in #pragma.
  • Unterstützung für das Abfragen zusätzlicher Informationen aus RS-Objekten aus einem Compute-Skript.
  • Zahlreiche Leistungsverbesserungen.

Neue Pragma sind ebenfalls verfügbar, um die Gleitkomma-Genauigkeit zu definieren, die von Ihren Computing-Renderscripts benötigt wird. Auf diese Weise können Sie NEON-ähnliche Operationen wie schnelle Vektorberechnungen im CPU-Pfad aktivieren, die mit dem vollständigen IEEE 754-2008-Standard nicht möglich wären.

Hinweis:Das experimentelle Renderscript-Grafikmodul wurde eingestellt.

Animation

Animationen zum Starten von Aktivitäten

Sie können jetzt ein Activity mit Zoomanimationen oder Ihren eigenen benutzerdefinierten Animationen starten. Verwenden Sie zum Angeben der gewünschten Animation die ActivityOptions APIs, um eine Bundle zu erstellen, die Sie dann an eine der Methoden zum Starten einer Aktivität übergeben können, z. B. startActivity().

Die Klasse ActivityOptions enthält für jede Art von Animation, die angezeigt werden soll, wenn sich die Aktivität öffnet, eine andere Methode:

makeScaleUpAnimation()
Erstellt eine Animation, bei der das Aktivitätsfenster von einer bestimmten Startposition auf dem Bildschirm und einer angegebenen Startgröße vergrößert wird. Auf dem Startbildschirm unter Android 4.1 wird dies beispielsweise beim Öffnen einer App verwendet.
makeThumbnailScaleUpAnimation()
Erstellt eine Animation, bei der das Aktivitätsfenster ab einer bestimmten Position und einer bereitgestellten Miniaturansicht vergrößert wird. So wird es beispielsweise im Fenster „Zuletzt verwendete Apps“ in Android 4.1 verwendet, wenn zu einer App zurückgekehrt wird.
makeCustomAnimation()
Es wird eine von Ihren eigenen Ressourcen definierte Animation erstellt. Eine, die die Animation für die Öffnung der Aktivität definiert, und eine weitere für die beendete Aktivität.

Zeitanimation

Das neue TimeAnimator bietet einen einfachen Callback-Mechanismus mit dem TimeAnimator.TimeListener, der Sie bei jedem Frame der Animation benachrichtigt. Mit diesem Animator können keine Dauer, Interpolation oder Objektwerteinstellung festgelegt werden. Der Callback des Listeners erhält Informationen für jeden Frame, einschließlich der gesamten verstrichenen Zeit und der seit dem vorherigen Animationsframe verstrichenen Zeit.

Benutzeroberfläche

Benachrichtigungen

In Android 4.1 können Sie Benachrichtigungen mit größeren Inhaltsbereichen, Vorschauen großer Bilder, mehreren Aktionsschaltflächen und konfigurierbarer Priorität erstellen.

Benachrichtigungsstile

Mit der neuen Methode setStyle() kannst du einen von drei neuen Stilen für Benachrichtigungen angeben, die jeweils einen größeren Inhaltsbereich bieten. Übergeben Sie setStyle() eines der folgenden Objekte, um den Stil für Ihren großen Inhaltsbereich anzugeben:

Notification.BigPictureStyle
Für Benachrichtigungen mit einem großen Bildanhang
Notification.BigTextStyle
Für Benachrichtigungen, die viel Text enthalten, z. B. eine einzelne E-Mail.
Notification.InboxStyle
Für Benachrichtigungen, die eine Liste von Strings enthalten, z. B. Snippets aus mehreren E-Mails.
Benachrichtigungsaktionen

Es werden jetzt bis zu zwei Aktionsschaltflächen unterstützt, die am unteren Rand der Benachrichtigung angezeigt werden, unabhängig davon, ob für die Benachrichtigung der normale oder größere Stil verwendet wird.

Rufen Sie addAction() auf, um eine Aktionsschaltfläche hinzuzufügen. Diese Methode verwendet drei Argumente: eine Drawable-Ressource für ein Symbol, Text für die Schaltfläche und ein PendingIntent, das die Aktion definiert, die ausgeführt werden soll.

Prioritäten

Du kannst dem System jetzt einen Hinweis darauf geben, wie wichtig deine Benachrichtigung ist, um die Reihenfolge der Benachrichtigungen in der Liste zu beeinflussen. Dazu legst du die Priorität mit setPriority() fest. Sie können diese von fünf verschiedenen Prioritätsstufen übergeben, die durch PRIORITY_*-Konstanten in der Klasse Notification definiert werden. Die Standardeinstellung ist PRIORITY_DEFAULT. Es gibt zwei höhere und zwei niedrigere Ebenen.

Benachrichtigungen mit hoher Priorität sind Dinge, auf die Nutzer im Allgemeinen schnell reagieren möchten, z. B. neue Chatnachrichten, SMS oder anstehende Ereigniserinnerungen. Benachrichtigungen mit niedriger Priorität sind beispielsweise abgelaufene Kalendertermine oder App-Promotions.

Steuerelemente für System-UI

In Android 4.0 (Ice Cream Sandwich) wurden neue Flags hinzugefügt, um die Sichtbarkeit der System-UI-Elemente zu steuern. So kann beispielsweise die Systemleiste gedimmt oder auf Mobilgeräten vollständig ausgeblendet werden. In Android 4.1 wurden einige weitere Flags hinzugefügt, mit denen Sie die Darstellung von System-UI-Elementen und das Aktivitätslayout im Verhältnis zu ihnen genauer steuern können. Dazu rufen Sie setSystemUiVisibility() auf und übergeben die folgenden Flags:

SYSTEM_UI_FLAG_FULLSCREEN
Blendet unkritische System-UI aus, z. B. die Statusleiste. Wenn Ihre Aktivität die Aktionsleiste im Overlay-Modus verwendet (durch Aktivieren von android:windowActionBarOverlay), blendet dieses Flag auch die Aktionsleiste aus und koordiniert dies mit einer koordinierten Animation, wenn die beiden aus- und eingeblendet werden.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Mit dieser Option wird für das Layout der Aktivität derselbe Bildschirmbereich verwendet, der auch verfügbar ist, wenn SYSTEM_UI_FLAG_FULLSCREEN aktiviert ist, auch wenn die Elemente der System-UI noch sichtbar sind. Auch wenn Teile Ihres Layouts von der System-UI überlagert werden, ist dies nützlich, wenn die System-UI in Ihrer App häufig mit SYSTEM_UI_FLAG_FULLSCREEN aus- und eingeblendet wird. So wird verhindert, dass sich das Layout jedes Mal an die neuen Layoutgrenzen anpasst, wenn die System-UI aus- oder eingeblendet wird.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Legt fest, dass für das Aktivitätslayout derselbe Bildschirmbereich verwendet wird, der auch dann zur Verfügung steht, wenn die Elemente der System-UI weiterhin sichtbar sind, wenn SYSTEM_UI_FLAG_HIDE_NAVIGATION (in Android 4.0 hinzugefügt) aktiviert wurde. Auch wenn Teile Ihres Layouts von der Navigationsleiste überlagert werden, ist dies nützlich, wenn die Navigationsleiste in Ihrer App häufig mit SYSTEM_UI_FLAG_HIDE_NAVIGATION aus- und eingeblendet wird. So wird verhindert, dass sich das Layout jedes Mal an die neuen Layoutgrenzen anpasst, wenn die Navigationsleiste ein- oder ausgeblendet wird.
SYSTEM_UI_FLAG_LAYOUT_STABLE
Dieses Flag empfiehlt sich, wenn Sie SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN und/oder SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION verwenden. So sorgen Sie beim Aufrufen von fitSystemWindows() für eine Ansicht dafür, dass die definierten Grenzen in Bezug auf den verfügbaren Bildschirmbereich konsistent bleiben. Wenn dieses Flag gesetzt ist, verhält sich fitSystemWindows() also so, als wäre die Sichtbarkeit der System-UI-Elemente unverändert, auch nachdem Sie alle System-UIs ausgeblendet haben.

Weitere Informationen zu den anderen zugehörigen System-UI-Flags finden Sie in den Artikeln zu den in Android 4.0 hinzugefügten Flags.

Abgelegene Ansichten

GridLayout und ViewStub sind jetzt austauschbare Ansichten, sodass Sie sie in Layouts für Ihre App-Widgets und benutzerdefinierten Benachrichtigungslayouts verwenden können.

Schriftfamilien

Unter Android 4.1 werden weitere Varianten des Roboto-Schriftstils hinzugefügt. Insgesamt gibt es zehn Varianten, die alle von Apps verwendet werden können. Ihre Anwendungen haben jetzt Zugriff auf alle leichten und komprimierten Varianten.

Hier sehen Sie alle verfügbaren Varianten der Roboto-Schriftart:

  • Regulär
  • Kursiv
  • Fett
  • Fett-kursiv
  • Leicht
  • Hell-kursiv
  • Komprimiertes Normalformat
  • Komprimierte Kursivschrift
  • Komprimiertes Fettdruck
  • Komprimiert (fett-kursiv)

Sie können jede dieser Eigenschaften mit dem neuen Attribut fontFamily in Kombination mit dem Attribut textStyle anwenden.

Unterstützte Werte für fontFamily sind:

  • "sans-serif" für normales Roboto-Format
  • "sans-serif-light" für Roboto Light
  • "sans-serif-condensed" für Roboto Condensed

Anschließend können Sie Fett- und/oder Kursivdruck mit den textStyle-Werten "bold" und "italic" anwenden. Sie können beide so anwenden: android:textStyle="bold|italic".

Sie können auch Typeface.create() verwenden. z. B. Typeface.create("sans-serif-light", Typeface.NORMAL).

Input Framework

Mehrere Eingabegeräte

Mit der neuen InputManager-Klasse können Sie die aktuell verbundenen Eingabegeräte abfragen und registrieren, um benachrichtigt zu werden, wenn ein neues Gerät hinzugefügt, geändert oder entfernt wird. Dies ist besonders nützlich, wenn Sie ein Spiel entwickeln, das mehrere Spieler unterstützt, und feststellen möchten, wie viele Controller verbunden sind und wenn sich die Anzahl der Controller ändert.

Sie können alle verbundenen Eingabegeräte abfragen, indem Sie getInputDeviceIds() aufrufen. Dadurch wird ein Array mit Ganzzahlen zurückgegeben, von denen jede eine ID für ein anderes Eingabegerät ist. Sie können dann getInputDevice() aufrufen, um eine InputDevice für eine angegebene Eingabegeräte-ID abzurufen.

Wenn Sie informiert werden möchten, wenn neue Eingabegeräte verbunden, geändert oder getrennt werden, implementieren Sie die InputManager.InputDeviceListener-Schnittstelle und registrieren Sie sie bei registerInputDeviceListener().

Vibration für Eingabe-Controller

Wenn verbundene Eingabegeräte eigene Vibrationsfunktionen haben, können Sie die Vibration dieser Geräte jetzt mithilfe der vorhandenen Vibrator APIs steuern. Dazu rufen Sie einfach getVibrator() im InputDevice auf.

Berechtigungen

Dies sind neue Berechtigungen:

READ_EXTERNAL_STORAGE
Bietet geschützten Lesezugriff auf externe Speicher. In Android 4.1 haben alle Anwendungen standardmäßig weiterhin Lesezugriff. Dies wird in einer zukünftigen Version geändert werden, sodass Anwendungen mit dieser Berechtigung explizit Lesezugriff anfordern müssen. Wenn Ihre Anwendung bereits Schreibzugriff anfordert, erhält sie automatisch auch Lesezugriff. Es gibt eine neue Option für Entwickler zur Aktivierung der Einschränkung des Lesezugriffs, mit der sie ihre Apps mit dem zukünftigen Verhalten von Android vergleichen können.
android.Manifest.permission.READ_USER_DICTIONARY
Ermöglicht einer Anwendung, Ihr Wörterbuch zu lesen. Dies sollte nur von einer IMEI oder einem Wörterbucheditor wie der App „Einstellungen“ erforderlich sein.
READ_CALL_LOG
Eine Anwendung kann die Anrufliste des Systems lesen, die Informationen über ein- und ausgehende Anrufe enthält.
WRITE_CALL_LOG
Ermöglicht einer App, die auf Ihrem Smartphone gespeicherte Anrufliste des Systems zu ändern
android.Manifest.permission.WRITE_USER_DICTIONARY
Ermöglicht einer Anwendung, in das Wortwörterbuch des Nutzers zu schreiben.

Gerätefunktionen

Android 4.1 enthält eine neue Funktionsdeklaration für Geräte, die ausschließlich für die Anzeige der Benutzeroberfläche auf einem Fernsehbildschirm vorgesehen sind: FEATURE_TELEVISION. Um zu deklarieren, dass deine App eine TV-Schnittstelle erfordert, deklarieren Sie diese Funktion in der Manifestdatei mit dem Element <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

Diese Funktion definiert „Fernsehen“ als typisches Fernseherlebnis im Wohnzimmer: Es wird auf einem großen Bildschirm angezeigt, wo der Nutzer weit weg sitzt und die dominante Eingabemethode in Form eines Steuerkreuzes und in der Regel nicht durch Berührung oder eine Maus oder einen Zeiger erfolgt.