Features von KitKat
Android 4.4 (KitKat) bietet ein Füllhorn an Features für Benutzer und Entwickler. Dieser Leitfaden stellt verschiedene dieser Features vor und bietet Codebeispiele sowie Implementierungsdetails, um Sie dabei zu unterstützen, KitKat optimal zu nutzen.
Übersicht
Android 4.4 (API-Ebene 19), auch als „KitKat“ bezeichnet, wurde Ende 2013 veröffentlicht. KitKat bietet eine Vielzahl neuer Features und Verbesserungen, einschließlich der folgenden:
Benutzererfahrung – Einfache Animationen mit Übergangsframework, transluzentem Status und Navigationsleisten und immersivem Vollbildmodus helfen dem Benutzer dabei, eine bessere Benutzererfahrung zu erzielen.
Benutzerinhalte – Die Verwaltung von Benutzerdateien wurde mit dem Speicherzugriffsframework vereinfacht. Das Drucken von Bildern, Websites und anderen Inhalten ist mit verbesserten Druck-APIs einfacher.
Hardware – Verwandeln Sie jede App in eine NFC-Karte mit DER HOST-basierten NFC-Kartenemulation; führen Sie Low-Power-Sensoren mit dem
SensorManager
.Entwicklertools – Screencast-Anwendungen in Aktion mit dem Android Debug Bridge-Client, der als Teil des Android SDK verfügbar ist.
Der vorliegende Leitfaden bietet Anleitungen zum Migrieren einer vorhandenen Xamarin.Android-Anwendung zu KitKat sowie einen allgemeinen Überblick über KitKat für Xamarin.Android-Entwickler.
Anforderungen
Um Xamarin.Android-Anwendungen für KitKat zu entwickeln, müssen Sie über Xamarin.Android 4.11.0 oder höher verfügen und Android 4.4 (API-Ebene 19) über den Android-SDK-Manager installiert haben, wie im folgenden Screenshot gezeigt:
Migrieren Ihrer App zu KitKat
In diesem Abschnitt werden einige wichtige Aspekte beleuchtet, die Sie beim Migrieren vorhandener Apps zu Android 4.4 unterstützen.
Überprüfen der Systemversion
Wenn eine Anwendung mit älteren Android-Versionen kompatibel sein muss, umschließen Sie jeglichen KitKat-spezifischen Code mit einer Überprüfung der Systemversion, wie im folgenden Code veranschaulicht:
if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) {
//KitKat only code here
}
Batchverarbeitung von Alarmen
Android verwendet Alarmdienste, um eine App im Hintergrund zu einem bestimmten Zeitpunkt zu aktivieren. KitKat erweitert diese Funktionalität, indem Alarme in Batches verarbeitet werden, um Strom zu sparen. Das bedeutet Folgendes: Anstatt jede App zu einem exakten Zeitpunkt zu aktivieren, gruppiert KitKat verschiedene Anwendungen, die für eine Aktivierung im selben Zeitintervall registriert sind, und aktiviert diese alle gleichzeitig.
Um Android anzuweisen, eine App während eines bestimmten Zeitintervalls zu aktivieren, rufen Sie SetWindow
im AlarmManager
auf, und übergeben Sie den minimalen und maximalen Zeitraum in Millisekunden, der vor der Aktivierung einer App vergehen darf, sowie den Vorgang, der bei der Aktivierung ausgeführt werden soll.
Der folgende Code bietet ein Beispiel für eine Anwendung, die eine halbe bis eine Stunde nach dem festgelegten Zeitpunkt des Fensters aktiviert werden soll:
AlarmManager alarmManager = (AlarmManager)GetSystemService(AlarmService);
alarmManager.SetWindow (AlarmType.Rtc, AlarmManager.IntervalHalfHour, AlarmManager.IntervalHour, pendingIntent);
Um eine App weiterhin zu einem exakten Zeitpunkt zu aktivieren, verwenden Sie SetExact
und übergeben den exakten Zeitpunkt der Aktivierung der App sowie den auszuführenden Vorgang:
alarmManager.SetExact (AlarmType.Rtc, AlarmManager.IntervalDay, pendingIntent);
Unter KitKat können Sie keinen exakten Wiederholungsalarm mehr festlegen. Bei Anwendungen, die verwendenSetRepeating
und genaue Alarme für die Arbeit benötigen, müssen jetzt jeden Alarm manuell auslösen.
Externer Speicher
Externer Speicher ist jetzt in zwei Typen unterteilt: eindeutiger Speicher für eine Anwendung und von mehreren Anwendungen gemeinsam genutzte Daten. Für das Lesen und Schreiben im App-spezifischen Speicherort eines externen Speichers sind keine besonderen Berechtigungen erforderlich. Die Interaktion mit Daten in gemeinsam genutztem Speicher ist jetzt die Berechtigung READ_EXTERNAL_STORAGE
oder WRITE_EXTERNAL_STORAGE
erforderlich. Die beiden Typen können folgendermaßen klassifiziert werden:
Wenn Sie eine Datei oder einen Verzeichnispfad erhalten, indem Sie eine Methode
Context
aufrufen – z. B.GetExternalFilesDir
oderGetExternalCacheDirs
- benötigt Ihre App keine zusätzlichen Berechtigungen.
Wenn Sie eine Datei oder einen Verzeichnispfad abrufen, indem Sie auf eine Eigenschaft zugreifen oder eine Methode
Environment
aufrufen, z. B.GetExternalStorageDirectory
OderGetExternalStoragePublicDirectory
, für die Ihre App die Berechtigung oderWRITE_EXTERNAL_STORAGE
dieREAD_EXTERNAL_STORAGE
Berechtigung erforderlich ist.
Hinweis
WRITE_EXTERNAL_STORAGE
impliziert die Berechtigung READ_EXTERNAL_STORAGE
, sodass Sie immer nur eine Berechtigung festlegen müssen.
SMS-Konsolidierung
KitKat vereinfacht das Messaging für die Benutzer durch Aggregieren sämtlicher SMS-Inhalte in eine vom Benutzer ausgewählte Standard-App. Der Entwickler ist dafür zuständig, dass die App als Standard-App für das Messaging ausgewählt werden kann und ein geeignetes Verhalten im Code und in der Praxis zeigt, wenn die App nicht ausgewählt ist. Weitere Informationen zum Migrieren Ihrer SMS-App zu KitKat finden Sie im Leitfaden Getting Your SMS Apps Ready for KitKat (Vorbereiten Ihrer SMS-App auf KitKat) von Google.
WebView-Apps
WebView wurde in KitKat gründlich überarbeitet. Die größte Änderung betrifft die zusätzliche Sicherheit beim Laden von Inhalten in einen WebView
. Die meisten Anwendungen, die für ältere API-Versionen entwickelt wurden, sollten erwartungsgemäß funktionieren. Allerdings empfiehlt es sich dringend, Anwendungen zu testen, die die WebView
-Klasse verwenden. Weitere Informationen zu den betroffenen WebView-APIs finden Sie in der Android-Dokumentation Migrating to WebView in Android 4.4 (Migrieren zu WebView in Android 4.4).
Benutzererfahrung
KitKat enthält verschiedene neue APIs zur Verbesserung der Benutzerfreundlichkeit, einschließlich eines neuen Übergangsframeworks zum Verarbeiten von Eigenschaftsanimationen und eine Option für durchsichtige Benutzeroberflächenelemente für Themes. Diese Änderungen werden im Folgenden erläutert.
Übergangsframework
Mit dem Übergangsframework lassen sich Animationen einfacher implementieren. In KitKat können Sie eine einfache Eigenschaftsanimation mit einer einzigen Codezeile ausführen oder Übergänge mithilfe von Szenen anpassen.
Einfache Eigenschaftsanimationen
Die neue Android-Bibliothek für Übergänge vereinfacht den Code für Eigenschaftsanimationen. Das Framework ermöglicht die Ausführung einfacher Animationen mit minimalem Codeaufwand. Das folgende Codebeispiel verwendet ,TransitionManager.BeginDelayedTransition
zum Animieren von Ein- und Ausblenden eines TextView
:
using Android.Transitions;
public class MainActivity : Activity
{
LinearLayout linear;
Button button;
TextView text;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
linear = FindViewById<LinearLayout> (Resource.Id.linearLayout);
button = FindViewById<Button> (Resource.Id.button);
text = FindViewById<TextView> (Resource.Id.textView);
button.Click += (o, e) => {
TransitionManager.BeginDelayedTransition (linear);
if(text.Visibility != ViewStates.Visible)
{
text.Visibility = ViewStates.Visible;
}
else
{
text.Visibility = ViewStates.Invisible;
}
};
}
}
Dieses Beispiel verwendet das Übergangsframework, um einen automatischen Standardübergang zwischen den wechselnden Eigenschaftswerten zu erstellen. Da die Animation mit einer einzigen Codezeile verarbeitet wird, können Sie ganz einfach Kompatibilität mit älteren Android-Versionen herstellen, indem Sie den BeginDelayedTransition
-Aufruf mit einer Überprüfung der Systemversion umschließen. Weitere Informationen finden Sie im Abschnitt Migrieren Ihrer App zu KitKat.
Der folgende Screenshot zeigt die App vor der Animation:
Der folgende Screenshot zeigt die App nach der Animation:
Mit Szenen – diese werden im nächsten Abschnitt behandelt – erzielen Sie eine bessere Steuerung der Übergänge.
Szenen in Android
Szenen wurde als Teil des Übergangsframeworks eingeführt, um Entwicklern eine bessere Steuerung der Animationen zu ermöglichen. Szenen erstellen einen dynamischen Bereich auf der Benutzeroberfläche: Entwickler geben einen Container und verschiedene Versionen bzw. „Szenen“ für die XML-Inhalte im Container an, und Android führt alle notwendigen Vorgänge aus, um die Übergänge zwischen den Szenen zu animieren. Mit Android-Szenen können Sie mit sehr wenig Entwicklungsaufwand komplexe Animationen erstellen.
Das statische Benutzeroberflächenelement, das die dynamischen Inhalte enthält, wird als Container oder Szenenbasis bezeichnet. Das folgende Beispiel verwendet Android Designer, um ein RelativeLayout
namens container
zu erstellen:
Das Beispiellayout definiert auch eine Schaltfläche namens sceneButton
unterhalb von container
. Mit dieser Schaltfläche wird der Übergang ausgelöst.
Die dynamischen Inhalte im Container erfordern zwei neue Android-Layouts. Diese Layouts geben nur den Code innerhalb des Containers an. Der folgende Beispielcode definiert ein Layout namens Scene1, das zwei Textfelder mit dem Inhalt „Kit“ bzw. „Kat“ enthält, sowie ein zweites Layout namens Scene2, das dieselben Textfelder in umgekehrter Reihenfolge enthält. Der XML-Code lautet wie folgt:
Scene1.axml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/textA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kit"
android:textSize="35sp" />
<TextView
android:id="@+id/textB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/textA"
android:text="Kat"
android:textSize="35sp" />
</merge>
Scene2.axml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/textB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kat"
android:textSize="35sp" />
<TextView
android:id="@+id/textA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/textB"
android:text="Kit"
android:textSize="35sp" />
</merge>
Dieses Beispiel verwendet merge
, um den Ansichtscode zu verkürzen und die Ansichtshierarchie zu vereinfachen. Weitere Informationen zu merge
-Layouts finden Sie hier.
Zum Erstellen einer Szene wird Scene.GetSceneForLayout
aufgerufen, und dabei werden das Containerobjekt, die Ressourcen-ID der Layoutdatei der Szene sowie der aktuelle Context
übergeben, wie im folgenden Codebeispiel veranschaulicht:
RelativeLayout container = FindViewById<RelativeLayout> (Resource.Id.container);
Scene scene1 = Scene.GetSceneForLayout(container, Resource.Layout.Scene1, this);
Scene scene2 = Scene.GetSceneForLayout(container, Resource.Layout.Scene2, this);
scene1.Enter();
Durch Klicken auf die Schaltfläche erfolgt ein Wechsel zwischen den beiden Szenen, den Android mit den Werten für den Standardübergang animiert:
sceneButton.Click += (o, e) => {
Scene temp = scene2;
scene2 = scene1;
scene1 = temp;
TransitionManager.Go (scene1);
};
Der folgende Screenshot zeigt die Szene vor der Animation:
Der folgende Screenshot zeigt die Szene nach der Animation:
Hinweis
Es gibt einen bekannten Fehler in der Übergangsbibliothek von Android, der dazu führt, dass mithilfe von GetSceneForLayout
erstellte Szenen unterbrochen werden, wenn ein Benutzer ein zweites Mal durch eine Aktivität navigiert.
Benutzerdefinierte Übergänge in Szenen
Ein benutzerdefinierter Übergang kann in einer XML-Ressourcendatei im Verzeichnis transition
unter Resources
definiert werden, wie im folgenden Screenshot gezeigt:
Im folgenden Codebeispiel wird ein Übergang definiert, der 5 Sekunden lang animiert wird. Weitere Informationen zu Animationen finden Sie unter.
<changeBounds
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:interpolator="@android:anim/overshoot_interpolator" />
Der Übergang wird mit dem TransitionInflater in der Aktivität erstellt, wie im folgenden Code veranschaulicht:
Transition transition = TransitionInflater.From(this).InflateTransition(Resource.Transition.transition);
Der neue Übergang wird dann dem Go
-Aufruf hinzugefügt, der die Animation startet:
TransitionManager.Go (scene1, transition);
Durchsichtige Benutzeroberflächenelemente
KitKat ermöglicht Ihnen mit optionalen durchsichtigen Status- und Navigationsleisten eine bessere Steuerung der Designs in Ihrer App. Sie können die Durchsichtigkeit von Systemelementen auf der Benutzeroberfläche in derselben XML-Datei ändern, die Sie auch verwenden, um Ihr Android-Theme zu definieren. KitKat führt die folgenden Eigenschaften ein:
windowTranslucentStatus
– bei Festlegung auf „true“ wird die obere Statusleiste durchsichtig angezeigt.windowTranslucentNavigation
– bei Festlegung auf „true“ wird untere obere Statusleiste durchsichtig angezeigt.fitsSystemWindows
– wenn die obere oder untere Leiste als durchsichtig festgelegt wird, werden Inhalte unter den transparenten Benutzeroberflächenelementen standardmäßig verschoben. Durch Festlegen dieser Eigenschaft auftrue
lässt sich ganz einfach verhindern, dass Inhalte mit den durchsichtigen Systemelementen auf der Benutzeroberfläche überlappen.
Der folgende Code definiert ein Theme mit durchsichtigen Status- und Navigationsleisten:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<style name="KitKatTheme" parent="android:Theme.Holo.Light">
<item name="android:windowBackground">@color/xamgray</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:fitsSystemWindows">true</item>
<item name="android:actionBarStyle">@style/ActionBar.Solid.KitKat</item>
</style>
<style name="ActionBar.Solid.KitKat" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
<item name="android:background">@color/xampurple</item>
</style>
</resources>
Der folgende Screenshot zeigt das obige Theme mit durchsichtigen Status- und Navigationsleisten:
Benutzerinhalte
Storage Access Framework
Das Storage Access Framework (SAF) ist eine neue Möglichkeit für Benutzer zur Interaktion mit gespeicherten Inhalten wie Bildern, Videos und Dokumenten. Statt Benutzern ein Dialogfeld zur Auswahl einer Anwendung für die Verarbeitung von Inhalten anzuzeigen, öffnet KitKat eine neue Benutzeroberfläche, über die Benutzer an einem einzigen aggregierten Speicherort auf ihre Daten zugreifen können. Wenn der entsprechende Inhalt ausgewählt wurde, kehrt der Benutzer zu der Anwendung zurück, die den Inhalt angefordert hat, und die App-Ausführung wird normal fortgesetzt.
Diese Änderung erfordert zwei Aktionen seitens des Entwicklers: Erstens müssen Apps, die Inhalte von Anbietern benötigen, auf diese neue Art der Inhaltsanforderung aktualisiert werden. Zweitens müssen Anwendungen, die Daten in einen ContentProvider
schreiben, so geändert werden, dass sie das neue Framework verwenden. Beide Szenarien benötigen die neue -DocumentsProvider
API.
DocumentsProvider
In KitKat werden Interaktionen mit ContentProviders
über die DocumentsProvider
-Klasse abstrahiert. Das bedeutet, dass es für das SAF keine Rolle spielt, wo die Daten physisch gespeichert sind, solange über die DocumentsProvider
-API darauf zugegriffen werden kann. Lokale Anbieter, Clouddienste und externe Speichergeräte verwenden alle dieselbe Schnittstelle und werden auf dieselbe Weise behandelt – so profitieren sowohl Benutzer als auch Entwickler von einer zentralen Stelle für die Interaktion mit Benutzerinhalten.
In diesem Abschnitt wird erläutert, wie Sie Inhalte über das Storage Access Framework laden und speichern.
Anfordern von Inhalten von einem Anbieter
Sie können KitKat über die SAF-Benutzeroberfläche mit der Absicht ActionOpenDocument
mitteilen, dass Inhalte abgerufen werden sollen. Das bedeutet, dass eine Verbindung mit allen Inhaltsanbietern hergestellt werden soll, die für das Gerät verfügbar sind. Sie können dieser Absicht durch Angabe von CategoryOpenable
einen Filter hinzufügen, der dafür sorgt, dass nur Inhalte, die geöffnet werden können (also zugängliche und verwendbare Inhalte), zurückgegeben werden. KitKat ermöglicht auch die Filterung mit dem MimeType
. Der folgende Code beispielsweise filtert durch Angabe des MimeType
des Bilds nach Bildergebnissen:
Intent intent = new Intent (Intent.ActionOpenDocument);
intent.AddCategory (Intent.CategoryOpenable);
intent.SetType ("image/*");
StartActivityForResult (intent, save_request_code);
Durch Aufrufen von StartActivityForResult
wird die SAF-Benutzeroberfläche gestartet, die der Benutzer dann durchsuchen kann, um ein Bild auszuwählen:
Nachdem der Benutzer ein Bild ausgewählt hat, gibt OnActivityResult
den Android.Net.Uri
der ausgewählten Datei zurück. Das folgende Codebeispiel zeigt die Bildauswahl des Benutzers:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok && data != null && requestCode == save_request_code) {
imageView = FindViewById<ImageView> (Resource.Id.imageView);
imageView.SetImageURI (data.Data);
}
}
Schreiben von Inhalten in einem Anbieter
Zusätzlich zum Laden von Inhalten aus der SAF-Benutzeroberfläche ermöglicht KitKat auch das Speichern von Inhalten in jeden ContentProvider
, der die DocumentProvider
-API implementiert. Zum Speichern von Inhalten wird ein Intent
-Element mit ActionCreateDocument
verwendet:
Intent intentCreate = new Intent (Intent.ActionCreateDocument);
intentCreate.AddCategory (Intent.CategoryOpenable);
intentCreate.SetType ("text/plain");
intentCreate.PutExtra (Intent.ExtraTitle, "NewDoc");
StartActivityForResult (intentCreate, write_request_code);
Das oben stehende Codebeispiel lädt die SAF-Benutzeroberfläche, ermöglicht dem Benutzer die Änderung des Dateinamens und die Auswahl eines Verzeichnisses zum Speichern der neuen Datei:
Wenn der Benutzer auf Speichern tippt, wird der Android.Net.Uri
der neu erstellten Datei an OnActivityResult
übergeben. Der Zugriff erfolgt mit data.Data
. Der URI kann zum Streamen von Daten in die neue Datei verwendet werden:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok && data != null && requestCode == write_request_code) {
using (Stream stream = ContentResolver.OpenOutputStream(data.Data)) {
Encoding u8 = Encoding.UTF8;
string content = "Hello, world!";
stream.Write (u8.GetBytes(content), 0, content.Length);
}
}
}
Beachten Sie, dass ContentResolver.OpenOutputStream(Android.Net.Uri)
gibt einen System.IO.Stream
, sodass der gesamte Streamingprozess in .NET geschrieben werden kann.
Weitere Informationen zum Laden, Erstellen und Bearbeiten von Inhalten mit dem Storage Access Framework finden Sie in der Android-Dokumentation zum Storage Access Framework.
Es wird gedruckt
KitKat vereinfacht das Drucken mit der Einführung von Druckdiensten und PrintManager
. KitKat ist auch die erste API-Version, um die Google Cloud Print-Dienst-APIs mit den Google Cloud Print-Anwendungen vollständig zu nutzen.
Die meisten Geräte, die mit KitKat ausgeliefert werden, laden die Google Cloud Print-App und das HP Druckdienst-Plug-In automatisch herunter, wenn sie zum ersten Mal eine Verbindung mit einem WLAN herstellen. Ein Benutzer kann die Druckeinstellungen seines Geräts überprüfen, indem er zu Einstellungen Systemdruck > navigiert>:
Hinweis
Die Druck-APIs sind zwar standardmäßig für die Verwendung mit Google Cloud Print eingerichtet, aber Android ermöglicht es Entwicklern weiterhin, Druckinhalte über die neuen APIs vorzubereiten und sie dann an andere Anwendungen zu senden, die den Druck verarbeiten.
Drucken von HTML-Inhalten
KitKat erstellt automatisch einen PrintDocumentAdapter
für eine Webansicht mit WebView.CreatePrintDocumentAdapter
. Das Drucken von Webinhalten ist ein koordinierter Vorgang mit zwei Elementen: Zum einen ein WebViewClient
, der darauf wartet, dass HTML-Inhalte geladen werden, und die Aktivität darüber informiert, dass die Druckoption im Optionsmenü zur Verfügung gestellt werden soll; zum anderen die Aktivität, die darauf wartet, dass der Benutzer die Druckoption auswählt, und Print
im PrintManager
aufruft. Im folgenden Abschnitt wird das grundlegende Setup erläutert, das zum Drucken von HTML-Inhalten auf dem Bildschirm erforderlich ist.
Beachten Sie, dass zum Laden und Drucken von Webinhalten die Berechtigung „Internet“ benötigt wird:
Menüelement „Drucken“
Die Druckoption wird in der Regel im Optionsmenü der Aktivität angezeigt. Über das Optionsmenü können Benutzer Aktionen in einer Aktivität ausführen. Es befindet sich in der oberen rechten Ecke und sieht so aus:
Zusätzliche Menüelemente können im Verzeichnis menu unter Resources definiert werden. Der folgende Code definiert ein Beispielmenüelement namens Print:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_print"
android:title="Print"
android:showAsAction="never" />
</menu>
Die Interaktion mit dem Optionsmenü in der Aktivität erfolgt über die Methoden OnCreateOptionsMenu
und OnOptionsItemSelected
.
In OnCreateOptionsMenu
werden neue Menüelemente, wie z. B. die Druckoption, aus dem Ressourcenverzeichnis menu hinzugefügt.
OnOptionsItemSelected
lauscht auf die Benutzerauswahl der Druckoption aus dem Menü und startet den Druckvorgang:
bool dataLoaded;
public override bool OnCreateOptionsMenu (IMenu menu)
{
base.OnCreateOptionsMenu (menu);
if (dataLoaded) {
MenuInflater.Inflate (Resource.Menu.print, menu);
}
return true;
}
public override bool OnOptionsItemSelected (IMenuItem item)
{
if (item.ItemId == Resource.Id.menu_print) {
PrintPage ();
return true;
}
return base.OnOptionsItemSelected (item);
}
Der oben stehende Code definiert auch eine Variable namens dataLoaded
, um den Status der HTML-Inhalte nachzuverfolgen. Der WebViewClient
legt diese Variable auf „true“ fest, wenn sämtliche Inhalte geladen wurden, sodass die Aktivität weiß, dass das Menüelement „Drucken“ zum Optionsmenü hinzugefügt werden muss.
WebViewClient
Der WebViewClient
soll sicherstellen, dass die Daten im WebView
vollständig geladen sind, bevor die Druckoption im Menü angezeigt wird, und verwendet dafür die OnPageFinished
-Methode. OnPageFinished
lauscht auf den Abschluss des Ladevorgangs für die Webinhalte und informiert die Aktivität darüber, dass das Optionsmenü mit InvalidateOptionsMenu
neu erstellt werden muss:
class MyWebViewClient : WebViewClient
{
PrintHtmlActivity caller;
public MyWebViewClient (PrintHtmlActivity caller)
{
this.caller = caller;
}
public override void OnPageFinished (WebView view, string url)
{
caller.dataLoaded = true;
caller.InvalidateOptionsMenu ();
}
}
OnPageFinished
legt auch den dataLoaded
-Wert auf true
fest, sodass OnCreateOptionsMenu
das Menü mit der Druckoption neu erstellen kann.
PrintManager
Das folgende Codebeispiel druckt die Inhalte eines WebView
:
void PrintPage ()
{
PrintManager printManager = (PrintManager)GetSystemService (Context.PrintService);
PrintDocumentAdapter printDocumentAdapter = myWebView.CreatePrintDocumentAdapter ();
printManager.Print ("MyWebPage", printDocumentAdapter, null);
}
Print
verwendet als Argumente: einen Namen für den Druckauftrag ("MyWebPage" in diesem Beispiel), ein PrintDocumentAdapter
das Druckdokument aus dem Inhalt generiert und PrintAttributes
(null
im obigen Beispiel). Zwar können die Standardattribute die meisten Szenarien verarbeiten, aber Sie können PrintAttributes
angeben, um das Layout der Inhalte auf der gedruckten Seite einzurichten.
Durch Aufrufen von Print
wird die Benutzeroberfläche für den Druckvorgang aufgerufen, die Optionen für den Druckauftrag enthält. Auf der Benutzeroberfläche können Benutzer die HTML-Inhalte drucken oder in eine PDF-Datei speichern, wie in den folgenden Screenshots gezeigt:
Hardware
KitKat fügt verschiedene APIs für neue Gerätefunktionen hinzu. Die wichtigsten dieser Funktionen sind die hostbasierte Kartenemulation und der neue SensorManager
.
Hostbasierte Kartenemulation für NFC
Mit der hostbasierten Kartenemulation (Host-Based Card Emulation, HCE) können Anwendungen sich wie NFC-Karten oder NFC-Kartenleser verhalten, ohne den proprietären Secure Element-Chip des Anbieters zu benötigen. Bevor Sie HCE einrichten, stellen Sie mit PackageManager.HasSystemFeature
sicher, dass das Feature auf dem Gerät verfügbar ist:
bool hceSupport = PackageManager.HasSystemFeature(PackageManager.FeatureNfcHostCardEmulation);
Für HCE müssen sowohl das HCE-Feature als auch die Berechtigung Nfc
beim AndroidManifest.xml
der Anwendung registriert sein:
<uses-feature android:name="android.hardware.nfc.hce" />
Damit das Feature funktioniert, muss HCE im Hintergrund ausgeführt werden können und muss starten, wenn ein Benutzer eine NFC-Transaktion durchführt, auch wenn die Anwendung, die HCE verwendet, nicht ausgeführt wird. Dies lässt sich erreichen, indem der HCE-Code als Service
geschrieben wird. Ein HCE-Dienst implementiert die HostApduService
-Schnittstelle, die wiederum die folgenden Methoden implementiert:
ProcessCommandApdu: Zwischen dem NFC-Leser und dem HCE-Dienst wird eine Anwendungsprotokoll-Dateneinheit (Application Protocol Data Unit, APDU) gesendet. Diese Methode verwendet eine APDU des Lesers und gibt als Antwort eine Dateneinheit zurück.
OnDeactivated: Der
HostAdpuService
wird deaktiviert, wenn der HCE-Dienst nicht mehr mit dem NFC-Leser kommuniziert.
Ein HCE-Dienst muss auch beim Manifest der Anwendung registriert und mit den richtigen Berechtigungen, Absichtsfiltern und Metadaten versehen werden. Der folgende Code ist ein Beispiel für einen HostApduService
, der über das Service
-Attribut beim Android-Manifest registriert ist (weitere Informationen zu Attributen finden Sie im Xamarin-Leitfaden Arbeiten mit dem Android-Manifest):
[Service(Exported=true, Permission="android.permissions.BIND_NFC_SERVICE"),
IntentFilter(new[] {"android.nfc.cardemulation.HOST_APDU_SERVICE"}),
MetaData("android.nfc.cardemulation.host.apdu_service",
Resource="@xml/hceservice")]
class HceService : HostApduService
{
public override byte[] ProcessCommandApdu(byte[] apdu, Bundle extras)
{
...
}
public override void OnDeactivated (DeactivationReason reason)
{
...
}
}
Der oben genannte Dienst ermöglicht dem NFC-Leser die Interaktion mit der Anwendung, aber der NFC-Leser erhält weiterhin keine Informationen dazu, ob dieser Dienst die NFC-Karte emuliert, die gescannt werden soll. Damit der NFC-Leser den Dienst identifizieren kann, weisen Sie dem Dienst eine eindeutige Anwendungs-ID (AID) zu. Die AID wird zusammen mit weiteren Metadaten zum HCE-Dienst in einer XML-Ressourcendatei angegeben, die mit dem MetaData
-Attribut registriert wird (siehe Codebeispiel oben). Diese Ressourcendatei gibt mindestens einen AID-Filter an – eindeutige Bezeichnerzeichenfolgen im Hexadezimalformat, die den AIDs mindestens eines NFC-Lesegeräts entsprechen:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/hce_service_description"
android:requireDeviceUnlock="false"
android:apduServiceBanner="@drawable/service_banner">
<aid-group android:description="@string/aid_group_description"
android:category="payment">
<aid-filter android:name="1111111111111111"/>
<aid-filter android:name="0123456789012345"/>
</aid-group>
</host-apdu-service>
Zusätzlich zu AID-Filtern stellt die XML-Ressourcendatei auch eine Beschreibung des HCE-Dienst für den Benutzer bereit, gibt eine AID-Gruppe an (Zahlungsanwendung oder „sonstige Anwendung“) und stellt im Fall einer Zahlungsanwendung ein 260x96 px großes Banner bereit, das dem Benutzer angezeigt wird.
Das oben beschriebene Setup stellt auch die grundlegenden Bausteine für eine Anwendung bereit, die eine NFC-Karte emuliert. Zur Konfiguration von NFC selbst sind zahlreiche weitere Schritte sowie weitere Tests erforderlich. Weitere Informationen zur hostbasierten Kartenemulation finden Sie im Android-Dokumentationsportal. Weitere Informationen zur Verwendung von NFC mit Xamarin finden Sie in den Xamarin-Beispielen für NFC.
Sensoren
KitKat bietet über einen SensorManager
Zugriff auf die Sensoren eines Geräts.
Der SensorManager
ermöglicht es dem Betriebssystem, Anwendungen Sensorinformationen in Batches bereitzustellen und so Akkuleistung zu sparen.
KitKat wird auch mit zwei neuen Sensortypen zum Zählen von Schritten des Benutzers ausgeliefert. Diese basieren auf einem Beschleunigungsmesser und umfassen Folgendes:
StepDetector: Die App wird benachrichtigt bzw. aktiviert, wenn der Benutzer einen Schritt geht, und der Detektor stellt einen Uhrzeitwert für diesen Schritt bereit.
StepCounter: Verfolgt die Anzahl von Schritten nach, die der Benutzer seit der Registrierung gegangen ist. Dies gilt bis zum nächsten Neustart des Geräts.
Der folgende Screenshot zeigt den Schrittzähler in Aktion:
Sie können einen SensorManager
erstellen, indem Sie GetSystemService(SensorService)
aufrufen und das Ergebnis in einen SensorManager
umwandeln. Um den Schrittzähler zu verwenden, rufen Sie GetDefaultSensor
im SensorManager
auf. Verwenden Sie zum Registrieren des Sensors und Lauschen auf Änderungen an der Schrittzahl die Schnittstelle ,ISensorEventListener
Schnittstelle, wie im folgenden Codebeispiel dargestellt:
public class MainActivity : Activity, ISensorEventListener
{
float count = 0;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
SensorManager senMgr = (SensorManager) GetSystemService (SensorService);
Sensor counter = senMgr.GetDefaultSensor (SensorType.StepCounter);
if (counter != null) {
senMgr.RegisterListener(this, counter, SensorDelay.Normal);
}
}
public void OnAccuracyChanged (Sensor sensor, SensorStatus accuracy)
{
Log.Info ("SensorManager", "Sensor accuracy changed");
}
public void OnSensorChanged (SensorEvent e)
{
count = e.Values [0];
}
}
OnSensorChanged
wird aufgerufen, wenn die Schrittzahl aktualisiert wird, während die App sich im Vordergrund befindet. Wenn die App in den Hintergrund verlagert wird oder das Gerät in den Standbymodus wechselt, wird OnSensorChanged
nicht aufgerufen. Die Schritte werden jedoch weiterhin gezählt, bis UnregisterListener
aufgerufen wird.
Denken Sie daran, dass der Schrittzahlwert über alle Anwendungen hinweg kumulativ ist, die den Sensor registrieren. Das bedeutet Folgendes: Selbst wenn ein Benutzer Ihre App deinstalliert und neu installiert und die count
-Variable beim App-Start mit dem Wert 0 initialisiert, ist der vom Sensor gemeldete Wert weiterhin die Gesamtzahl der Schritte, die der Benutzer gegangen ist, während der Sensor registriert war (bei Ihrer App oder einer anderen). Sie können verhindern, dass Ihre App Schritte zum Schrittzähler hinzufügt, indem Sie UnregisterListener
im SensorManager
aufrufen, wie im folgenden Code veranschaulicht:
protected override void OnPause()
{
base.OnPause ();
senMgr.UnregisterListener(this);
}
Durch Neustarten des Geräts wird die Schrittzahl auf 0 zurückgesetzt. Für Ihre App ist zusätzlicher Code erforderlich, um sicherzustellen, dass die richtige Zählung für die App gemeldet wird, unabhängig davon, ob andere Anwendungen den Sensor oder Status des Geräts verwenden.
Hinweis
Die API für die Erfassung und Zählung von Schritten wird zwar mit KitKat ausgeliefert, aber nicht alle Smartphones sind mit einem entsprechenden Sensor ausgestattet. Mit PackageManager.HasSystemFeature(PackageManager.FeatureSensorStepCounter);
können Sie überprüfen, ob ein Sensor verfügbar ist, oder sich vergewissern, dass der Rückgabewert von GetDefaultSensor
nicht null
lautet.
Entwicklertools
Bildschirmaufzeichnung
KitKat enthält neue Funktionen für Bildschirmaufzeichnungen, sodass Entwickler Anwendung in Aktion aufzeichnen können. Bildschirmaufzeichnungen sind über den Android Debug Bridge-Client (ADB) verfügbar, der als Teil des Android SDK heruntergeladen werden kann.
Um Vorgänge auf Ihrem Bildschirm aufzuzeichnen, stellen Sie eine Verbindung mit Ihrem Gerät her. Dann suchen Sie Ihre Android SDK-Installation, navigieren zum Verzeichnis platform-tools und führen den adb-Client aus:
adb shell screenrecord /sdcard/screencast.mp4
Der Befehl oben zeichnet ein 3-minütiges Standardvideo mit der Standardauflösung von 4 Mbit/s auf. Um die Länge zu bearbeiten, fügen Sie das Flag --time-limit hinzu. Um die Auflösung zu ändern, fügen Sie das Flag --bit-rate hinzu. Der folgende Befehl zeichnet ein Video mit 8 Mbit/s und einer Länge von einer Minute auf:
adb shell screenrecord --bit-rate 8000000 --time-limit 60 /sdcard/screencast.mp4
Das Video wird auf dem Gerät in der Galerie angezeigt, wenn die Aufzeichnung beendet ist.
Weitere Ergänzungen in KitKat
Zusätzlich zu den oben beschriebenen Änderungen ermöglicht KitKat Folgendes:
Verwenden des gesamten Bildschirms: KitKat führt einen neuen plastischen Modus zum Durchsuchen von Inhalten, zum Spielen und zum Ausführen anderer Anwendungen ein, bei denen ein Vollbildmodus nützlich ist.
Anpassen von Benachrichtigungen – Abrufen zusätzlicher Details zu Systembenachrichtigungen mit dem
NotificationListenerService
. Damit können Sie die Informationen in Ihrer App auf andere Weise darstellen.Verspiegelte drawable Resources – Drawable resources have a new
autoMirrored
attribut that tells the system create a Spiegel ed version for images that require flipping for left-to-right layouts.Animationen anhalten – Animationen anhalten und fortsetzen, die mit dem
Animator
-Klasse.Dynamisches Ändern von Text lesen – Geben Sie Teile der Benutzeroberfläche an, die dynamisch mit neuem Text als "Livebereiche" mit dem neuen
accessibilityLiveRegion
Attribut, damit der neue Text automatisch im Barrierefreiheitsmodus gelesen wird.Verbessern des Audioerlebnisses – Sorgen Sie für lautere Titel mit der
LoudnessEnhancer
, suchen Sie den Peak und RMS eines Audiodatenstroms mit demVisualizer
Klasse und Abrufen von Informationen aus einem Audiozeitstempel zur Unterstützung der Audiovideosynchronisierung.Synchronisieren des ContentResolver in benutzerdefinierten Intervallen: KitKat erhöht die Variabilität in Bezug auf den Zeitpunkt, zu dem eine Synchronisierungsanforderung ausgeführt wird. Synchronisieren Sie einen
ContentResolver
zu einem benutzerdefinierten Zeitpunkt oder in einem benutzerdefinierten Intervall, indem SieContentResolver.RequestSync
aufrufen und eineSyncRequest
übergeben.Unterscheiden zwischen Controllern: In KitKat werden Controllern eindeutige ganzzahlige Bezeichner zugewiesen, auf die über die
ControllerNumber
-Eigenschaft eines Geräts zugegriffen werden kann. So lassen sich beispielsweise Spieler in einem Spiel leichter auseinanderhalten.Fernbedienung – Mit einigen Änderungen sowohl auf der Hardware- als auch auf der Softwareseite ermöglicht KitKat, ein Gerät, das mit einem IR-Sender ausgestattet ist, in eine Fernbedienung zu
ConsumerIrService
verwandeln und mit Peripheriegeräten mit dem neuenRemoteController
Apis.
Weitere Informationen zu den oben genannten API-Änderungen finden Sie in der Übersicht zu Android 4.4-APIs.
Zusammenfassung
In diesem Artikel wurden einige der neuen APIs vorgestellt, die in Android 4.4 (API-Ebene 19) verfügbar sind, und einige bewährte Methoden beim Migrieren einer Anwendung zu KitKat erläutert. Es wurden Änderungen an den APIs beschrieben, die die Benutzerfreundlichkeit betreffen, wie beispielsweise das Übergangsframework und neue Optionen für Themes. Danach wurden das Storage Access Framework und die DocumentsProvider
-Klasse sowie die neuen Druck-APIs vorgestellt. Die hostbasierte Kartenemulation für NFC wurde ebenso erläutert wie die Arbeit mit Sensoren mit geringem Stromverbrauch, einschließlich zweier neuer Sensoren für die Schrittzählung. Zum Schluss wurde das Erfassen von Echtzeitdemonstrationen von Anwendungen per Bildschirmaufzeichnung beschrieben, und es wurde eine detaillierte Liste weiterer Änderungen und Ergänzungen der KitKat-API bereitgestellt.