Udostępnij za pośrednictwem


KitKat, funkcje

System Android 4.4 (KitKat) jest ładowany z cornucopia funkcji dla użytkowników i deweloperów. Ten przewodnik wyróżnia kilka z tych funkcji i zawiera przykłady kodu i szczegóły implementacji, aby ułatwić ci jak największe korzyści z zestawu KitKat.

Omówienie

Android 4.4 (API Level 19), znany również jako "KitKat", został wydany pod koniec 2013 roku. KitKat oferuje różne nowe funkcje i ulepszenia, w tym:

  • Środowisko użytkownika — łatwe animacje ze strukturą przejścia, przejściowym stanem i paskami nawigacji oraz trybem immersyjnym pełnoekranowym ułatwiają tworzenie lepszego środowiska dla użytkownika.

  • Zawartość użytkownika — zarządzanie plikami użytkowników uproszczone dzięki strukturze dostępu do magazynu; drukowanie obrazów, witryn internetowych i inną zawartość jest łatwiejsze dzięki ulepszonym interfejsom API drukowania.

  • Sprzęt — przekształcanie dowolnej aplikacji w kartę NFC z emulacją kart opartych na hoście NFC; uruchamiaj czujniki o niskiej mocy za pomocą elementu SensorManager .

  • Developer Tools — aplikacje screencast w działaniu z klientem mostka debugowania systemu Android dostępne jako część zestawu Android SDK.

Ten przewodnik zawiera wskazówki dotyczące migrowania istniejącej aplikacji platformy Xamarin.Android do zestawu KitKat, a także ogólne omówienie zestawu KitKat dla deweloperów platformy Xamarin.Android.

Wymagania

Aby opracowywać aplikacje platformy Xamarin.Android przy użyciu zestawu KitKat, potrzebujesz platformy Xamarin.Android 4.11.0 lub nowszej i systemu Android 4.4 (poziom 19 interfejsu API) zainstalowanego za pośrednictwem Menedżera zestawu SDK systemu Android, jak pokazano na poniższym zrzucie ekranu:

Wybieranie systemu Android 4.4 w Menedżerze zestawu Android SDK

Migrowanie aplikacji do aplikacji KitKat

Ta sekcja zawiera niektóre elementy pierwszej odpowiedzi ułatwiające przejście istniejących aplikacji do systemu Android 4.4.

Sprawdzanie wersji systemu

Jeśli aplikacja musi być zgodna ze starszymi wersjami systemu Android, pamiętaj, aby opakowować dowolny kod specyficzny dla zestawuKat w kontroli wersji systemu, jak pokazano w poniższym przykładzie kodu:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) {
    //KitKat only code here
}

Przetwarzanie wsadowe alarmów

System Android używa usług alarmowych do wznawiania aplikacji w tle w określonym czasie. KitKat robi to krok dalej, wsadując alarmy, aby zachować moc. Oznacza to, że zamiast obudzić każdą aplikację w dokładnym czasie, KitKat woli grupować kilka aplikacji zarejestrowanych w celu wznowienia w tym samym przedziale czasu i wybudzać je w tym samym czasie. Aby poinformować system Android o wznawianiu aplikacji w określonym przedziale czasu, wywołaj metodę SetWindow , AlarmManagerprzechodząc przez minimalny i maksymalny czas (w milisekundach), który może upłynąć przed wybudzeniem aplikacji i operacją do wykonania w trakcie wznawiania. Poniższy kod zawiera przykład aplikacji, która musi zostać wybudzona z przedziału od pół godziny do godziny od momentu ustawienia okna:

AlarmManager alarmManager = (AlarmManager)GetSystemService(AlarmService);
alarmManager.SetWindow (AlarmType.Rtc, AlarmManager.IntervalHalfHour, AlarmManager.IntervalHour, pendingIntent);

Aby kontynuować przebudzenie aplikacji w dokładnym czasie, użyj polecenia SetExact, przekazując dokładny czas, w jaki aplikacja powinna zostać zdjęta, oraz operację do wykonania:

alarmManager.SetExact (AlarmType.Rtc, AlarmManager.IntervalDay, pendingIntent);

KitKat nie pozwala już ustawić dokładnego powtarzającego się alarmu. Aplikacje korzystające z SetRepeating i wymagają dokładnych alarmów do pracy będzie teraz konieczne ręczne wyzwolenie każdego alarmu.

Magazyn zewnętrzny

Magazyn zewnętrzny jest teraz podzielony na dwa typy — magazyn unikatowy dla aplikacji i dane współużytkowane przez wiele aplikacji. Odczytywanie i zapisywanie w określonej lokalizacji aplikacji w magazynie zewnętrznym nie wymaga specjalnych uprawnień. Interakcja z danymi w magazynie udostępnionym wymaga READ_EXTERNAL_STORAGE teraz uprawnień lub WRITE_EXTERNAL_STORAGE . Te dwa typy można sklasyfikować jako takie:

Uwaga

WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE oznacza uprawnienie, więc należy ustawić tylko jedno uprawnienie.

Konsolidacja wiadomości SMS

KitKat upraszcza obsługę komunikatów dla użytkownika, agregując całą zawartość sms w jednej domyślnej aplikacji wybranej przez użytkownika. Deweloper jest odpowiedzialny za wybranie aplikacji jako domyślnej aplikacji do obsługi komunikatów i zachowanie odpowiedniego działania w kodzie i w życiu, jeśli aplikacja nie jest wybrana. Aby uzyskać więcej informacji na temat przenoszenia aplikacji SMS do aplikacji KitKat, zapoznaj się z przewodnikiem Getting Your SMS Apps Ready for KitKat from Google (Przygotowywanie aplikacji SMS dla zestawu KitKat ).

Aplikacje WebView

Element WebView dostał metamorfozę w KitKat. Największą zmianą jest dodanie zabezpieczeń ładowania zawartości do elementu WebView. Chociaż większość aplikacji przeznaczonych dla starszych wersji interfejsu API powinna działać zgodnie z oczekiwaniami, zdecydowanie zaleca się testowanie aplikacji korzystających z WebView klasy. Aby uzyskać więcej informacji na temat interfejsów API webview, których dotyczy problem, zapoznaj się z dokumentacją rozwiązania Android Migrating to WebView w systemie Android 4.4 .

Środowisko użytkownika

KitKat zawiera kilka nowych interfejsów API, które usprawnią środowisko użytkownika, w tym nową strukturę przejścia do obsługi animacji właściwości i przezroczystą opcję interfejsu użytkownika do obsługi motywów. Te zmiany zostały omówione poniżej.

Struktura przejścia

Struktura przejścia ułatwia implementowanie animacji. KitKat umożliwia wykonywanie prostej animacji właściwości z tylko jednym wierszem kodu lub dostosowywanie przejść przy użyciu scen.

Animacja właściwości prostych

Nowa biblioteka przejścia systemu Android upraszcza kod związany z animacjami właściwości. Platforma umożliwia wykonywanie prostych animacji z minimalnym kodem. Na przykład w poniższym przykładzie kodu użyto następującego kodu TransitionManager.BeginDelayedTransition animowanie wyświetlania i ukrywania elementu 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;
            }
        };
    }
}

W powyższym przykładzie użyto struktury przejściowej do utworzenia automatycznego, domyślnego przejścia między zmieniającymi się wartościami właściwości. Ponieważ animacja jest obsługiwana przez pojedynczy wiersz kodu, można łatwo uczynić to zgodne ze starszymi wersjami systemu Android, opakowując BeginDelayedTransition wywołanie w kontroli wersji systemu. Aby uzyskać więcej informacji, zobacz sekcję Migrowanie aplikacji do zestawuKat .

Poniższy zrzut ekranu przedstawia aplikację przed animacją:

Zrzut ekranu aplikacji przed rozpoczęciem animacji

Poniższy zrzut ekranu przedstawia aplikację po animacji:

Zrzut ekranu aplikacji po zakończeniu animacji

Możesz uzyskać większą kontrolę nad przejściem za pomocą funkcji Sceny, które zostały omówione w następnej sekcji.

Sceny systemu Android

Sceny zostały wprowadzone w ramach struktury przejściowej, aby zapewnić deweloperowi większą kontrolę nad animacjami. Sceny tworzą obszar dynamiczny w interfejsie użytkownika: określasz kontener i kilka wersji lub "scen", dla zawartości XML wewnątrz kontenera, a system Android wykonuje resztę pracy, aby animować przejścia między scenami. Sceny systemu Android umożliwiają tworzenie złożonych animacji z minimalną pracą po stronie programowania.

Statyczny element interfejsu użytkownika, który mieści zawartość dynamiczną, jest nazywany kontenerem lub bazą scen. W poniższym przykładzie użyto Projektant systemu Android do utworzenia RelativeLayout o nazwie container:

Tworzenie kontenera RelativeLayout przy użyciu Projektant systemu Android

Przykładowy układ definiuje również przycisk o nazwie sceneButton poniżej .container Ten przycisk spowoduje wyzwolenie przejścia.

Zawartość dynamiczna wewnątrz kontenera wymaga dwóch nowych układów systemu Android. Te układy określają tylko kod wewnątrz kontenera. Poniższy przykładowy kod definiuje układ o nazwie Scene1, który zawiera dwa pola tekstowe odczytujące odpowiednio "Kit" i "Kat" oraz drugi układ o nazwie Scene2 zawierający te same pola tekstowe odwrócone. Kod XML jest następujący:

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>

W powyższym przykładzie użyto merge metody , aby kod widoku był krótszy i upraszczał hierarchię widoku. Więcej informacji o merge układach można znaleźć tutaj.

Scena jest tworzona przez wywołanie Scene.GetSceneForLayoutmetody , przekazując obiekt kontenera, identyfikator zasobu pliku układu sceny i bieżący Contextelement , jak pokazano w poniższym przykładzie kodu:

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();

Kliknięcie przycisku powoduje przejście między dwiema scenami, które system Android animuje z domyślnymi wartościami przejścia:

sceneButton.Click += (o, e) => {
    Scene temp = scene2;
    scene2 = scene1;
    scene1 = temp;

    TransitionManager.Go (scene1);
};

Poniższy zrzut ekranu przedstawia scenę przed animacją:

Zrzut ekranu przedstawiający aplikację przed rozpoczęciem animacji

Poniższy zrzut ekranu ilustruje scenę po animacji:

Zrzut ekranu aplikacji po zakończeniu animacji

Uwaga

Istnieje znana usterka w bibliotece Przejścia systemu Android, która powoduje, że sceny utworzone przy użyciu funkcji GetSceneForLayout przerywania, gdy użytkownik przechodzi przez działanie po raz drugi.

Niestandardowe przejścia w scenach

Przejście niestandardowe można zdefiniować w pliku zasobów XML w katalogu w transition obszarze Resources, jak pokazano na poniższym zrzucie ekranu:

Lokalizacja pliku transition.xml w obszarze Zasoby/katalog przejścia

Poniższy przykładowy kod definiuje przejście, które animuje się przez 5 sekund. Zobacz więcej informacji o animacji pod adresem.

<changeBounds
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:duration="5000"
  android:interpolator="@android:anim/overshoot_interpolator" />

Przejście jest tworzone w działaniu przy użyciu elementu TransitionInflater, jak pokazano w poniższym kodzie:

Transition transition = TransitionInflater.From(this).InflateTransition(Resource.Transition.transition);

Nowe przejście zostanie następnie dodane do wywołania rozpoczynającego Go animację:

TransitionManager.Go (scene1, transition);

Przezroczysty interfejs użytkownika

KitKat zapewnia większą kontrolę nad motywami aplikacji z opcjonalnym przezroczystym stanem i paskami nawigacji. Translucency elementów interfejsu użytkownika systemu można zmienić w tym samym pliku XML, którego używasz do zdefiniowania motywu systemu Android. KitKat wprowadza następujące właściwości:

  • windowTranslucentStatus — W przypadku ustawienia wartości true powoduje, że górny pasek stanu jest przezroczysty.

  • windowTranslucentNavigation — W przypadku ustawienia wartości true powoduje, że dolny pasek nawigacyjny jest przezroczysty.

  • fitsSystemWindows - Ustawienie górnego lub dolnego paska na transcluent przesuwa zawartość pod przezroczystymi elementami interfejsu użytkownika domyślnie. Ustawienie tej właściwości true na wartość jest prostym sposobem zapobiegania nakładaniu się zawartości na przezroczyste elementy interfejsu użytkownika systemu.

Poniższy kod definiuje motyw ze stanem przezroczystym i paskami nawigacji:

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

Poniższy zrzut ekranu przedstawia motyw powyżej ze stanem przezroczystym i paskami nawigacji:

Przykładowy zrzut ekranu aplikacji ze stanem przezroczystym i paskami nawigacji

Treści Użytkownika

Struktura dostępu do magazynu

Struktura dostępu do magazynu (SAF) to nowy sposób interakcji użytkowników z przechowywaną zawartością, taką jak obrazy, filmy wideo i dokumenty. Zamiast prezentować użytkownikom okno dialogowe w celu wybrania aplikacji do obsługi zawartości, KitKat otwiera nowy interfejs użytkownika, który umożliwia użytkownikom dostęp do danych w jednej zagregowanej lokalizacji. Po wybraniu zawartości użytkownik wróci do aplikacji, która zażądała zawartości, a środowisko aplikacji będzie kontynuowane normalnie.

Ta zmiana wymaga dwóch akcji po stronie dewelopera: najpierw aplikacje wymagające zawartości od dostawców muszą zostać zaktualizowane do nowego sposobu żądania zawartości. Po drugie, aplikacje, które zapisują dane do ContentProvider elementu, muszą być modyfikowane w celu korzystania z nowej platformy. Oba scenariusze zależą od nowego DocumentsProvider API.

DocumentsProvider

W pliku KitKat interakcje z ContentProviders klasą DocumentsProvider są abstrakcyjne. Oznacza to, że zapora SAF nie dba o to, gdzie dane są fizycznie, o ile są dostępne za pośrednictwem interfejsu DocumentsProvider API. Dostawcy lokalni, usługi w chmurze i zewnętrzne urządzenia magazynujące używają tego samego interfejsu i są traktowani w ten sam sposób, zapewniając użytkownikowi i deweloperowi jedno miejsce do interakcji z zawartością użytkownika.

W tej sekcji opisano sposób ładowania i zapisywania zawartości za pomocą struktury dostępu do magazynu.

Żądanie zawartości od dostawcy

Możemy poinformować KitKat, że chcemy wybrać zawartość przy użyciu interfejsu ActionOpenDocument użytkownika zapory SAF z intencją, co oznacza, że chcemy połączyć się ze wszystkimi dostawcami zawartości dostępnymi dla urządzenia. Możesz dodać filtrowanie do tej intencji, określając CategoryOpenablewartość , co oznacza, że zostanie zwrócona tylko zawartość, która może zostać otwarta (tj. dostępna, do użytku). KitKat umożliwia również filtrowanie zawartości za pomocą elementu MimeType. Na przykład poniższy kod filtruje wyniki obrazu, określając obraz MimeType:

Intent intent = new Intent (Intent.ActionOpenDocument);
intent.AddCategory (Intent.CategoryOpenable);
intent.SetType ("image/*");
StartActivityForResult (intent, save_request_code);

Wywołanie StartActivityForResult uruchamia interfejs użytkownika zapory aplikacji SAF, który użytkownik może następnie przeglądać, aby wybrać obraz:

Przykładowy zrzut ekranu przedstawiający aplikację korzystającą z struktury dostępu do magazynu na potrzeby przeglądania obrazu

Gdy użytkownik wybierze obraz, OnActivityResult zwraca Android.Net.Uri wartość wybranego pliku. Poniższy przykładowy kod wyświetla wybór obrazu użytkownika:

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);
    }
}

Zapisywanie zawartości u dostawcy

Oprócz ładowania zawartości z interfejsu użytkownika zapory aplikacji SAF, KitKat umożliwia również zapisywanie zawartości na dowolnym ContentProvider , który implementuje DocumentProvider interfejs API. Zapisywanie zawartości używa elementu Intent za pomocą polecenia ActionCreateDocument:

Intent intentCreate = new Intent (Intent.ActionCreateDocument);
intentCreate.AddCategory (Intent.CategoryOpenable);
intentCreate.SetType ("text/plain");
intentCreate.PutExtra (Intent.ExtraTitle, "NewDoc");
StartActivityForResult (intentCreate, write_request_code);

Powyższy przykładowy kod ładuje interfejs użytkownika zapory aplikacji SAF, pozwalając użytkownikowi zmienić nazwę pliku i wybrać katalog, aby pomieścić nowy plik:

Zrzut ekranu przedstawiający użytkownika zmieniającego nazwę pliku na NewDoc w katalogu Pobrane

Gdy użytkownik naciśnie przycisk Zapisz, OnActivityResult zostanie przekazany Android.Net.Uri nowo utworzony plik, do którego można uzyskać dostęp za pomocą polecenia data.Data. Identyfikator URI może służyć do przesyłania strumieniowego danych do nowego pliku:

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);
        }
    }
}

Należy pamiętać, że ContentResolver.OpenOutputStream(Android.Net.Uri) zwraca wartość System.IO.Stream, więc cały proces przesyłania strumieniowego można zapisać na platformie .NET.

Aby uzyskać więcej informacji na temat ładowania, tworzenia i edytowania zawartości za pomocą programu Storage Access Framework, zapoznaj się z dokumentacją systemu Android dotyczącą struktury dostępu do magazynu.

Drukowanie

Drukowanie zawartości jest uproszczone w kitKat wraz z wprowadzeniem usług drukowania i PrintManager. KitKat jest również pierwszą wersją interfejsu API, która w pełni korzysta z interfejsów API usługi Cloud Print firmy Google przy użyciu aplikacji Google Cloud Print. Większość urządzeń, które są dostarczane z zestawemKat, automatycznie pobiera aplikację Google Cloud Print i wtyczkęusługi HP Print, gdy po raz pierwszy nawiążą połączenie z siecią Wi-Fi. Użytkownik może sprawdzić ustawienia drukowania urządzenia, przechodząc do pozycji drukowanie systemu >Ustawienia>:

Przykładowy zrzut ekranu przedstawiający ekran Ustawienia drukowania

Uwaga

Mimo że interfejsy API drukowania są skonfigurowane do pracy z usługą Google Cloud Print domyślnie, system Android nadal umożliwia deweloperom przygotowywanie zawartości wydruku przy użyciu nowych interfejsów API i wysyłanie ich do innych aplikacji w celu obsługi drukowania.

Drukowanie zawartości HTML

KitKat automatycznie tworzy obiekt PrintDocumentAdapter dla widoku internetowego za pomocą polecenia WebView.CreatePrintDocumentAdapter. Drukowanie zawartości internetowej to skoordynowany wysiłek między elementemWebViewClient, który czeka na załadowanie zawartości HTML i informuje działanie o udostępnieniu opcji drukowania w menu opcji, a działaniem, które oczekuje na wybranie opcji Drukuj i wywołania elementu PrintPrintManager. W tej sekcji opisano podstawową konfigurację wymaganą do drukowania zawartości HTML na ekranie.

Należy pamiętać, że ładowanie i drukowanie zawartości internetowej wymaga uprawnienia Do Internetu:

Ustawianie uprawnień do Internetu w opcjach aplikacji

Opcja drukowania będzie zwykle wyświetlana w menu Opcje działania. Menu opcji umożliwia użytkownikom wykonywanie akcji w działaniu. Znajduje się on w prawym górnym rogu ekranu i wygląda następująco:

Przykładowy zrzut ekranu przedstawiający element menu Drukuj wyświetlany w prawym górnym rogu ekranu

Dodatkowe elementy menu można zdefiniować w katalogu menuw obszarze Zasoby. Poniższy kod definiuje przykładowy element menu o nazwie Drukuj:

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

Interakcja z menu opcji w działaniu odbywa się za pomocą OnCreateOptionsMenu metod i OnOptionsItemSelected . OnCreateOptionsMenu to miejsce dodawania nowych elementów menu, takich jak opcja Drukuj, z katalogu zasobów menu . OnOptionsItemSelected nasłuchuje użytkownika wybierającego opcję Drukuj z menu i rozpoczyna drukowanie:

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);
}

Powyższy kod definiuje również zmienną o nazwie dataLoaded , aby śledzić stan zawartości HTML. Dla WebViewClient tej zmiennej zostanie ustawiona wartość true po załadowaniu całej zawartości, więc działanie wie, aby dodać element menu Drukuj do menu opcji.

Element WebViewClient

Zadaniem WebViewClient elementu jest upewnienie się, że dane w obiekcie WebView są w pełni załadowane przed wyświetleniem opcji drukowania w menu, co robi z OnPageFinished metodą . OnPageFinished Nasłuchuje zawartości internetowej w celu zakończenia ładowania i informuje działanie o ponownym utworzeniu menu opcji za pomocą polecenia InvalidateOptionsMenu:

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 Ustawia dataLoaded również wartość na true, aby OnCreateOptionsMenu można było ponownie utworzyć menu z opcją Drukuj.

PrintManager

Poniższy przykład kodu wyświetla zawartość elementu WebView:

void PrintPage ()
{
    PrintManager printManager = (PrintManager)GetSystemService (Context.PrintService);
    PrintDocumentAdapter printDocumentAdapter = myWebView.CreatePrintDocumentAdapter ();
    printManager.Print ("MyWebPage", printDocumentAdapter, null);
}

Print przyjmuje jako argumenty: nazwę zadania drukowania ("MyWebPage" w tym przykładzie), a PrintDocumentAdapter wygeneruje dokument wydruku z zawartości i PrintAttributes (null w powyższym przykładzie). Można określić PrintAttributes , aby ułatwić określanie zawartości na drukowanej stronie, chociaż atrybuty domyślne powinny obsługiwać większość scenariuszy.

Wywołanie Print ładuje interfejs użytkownika drukowania, który zawiera listę opcji zadania drukowania. Interfejs użytkownika umożliwia użytkownikom drukowanie lub zapisywanie zawartości HTML w pliku PDF, jak pokazano na poniższych zrzutach ekranu:

Zrzut ekranu przedstawiający menu PrintHtmlActivity

Zrzut ekranu przedstawiający polecenie PrintHtmlActivity z menu Zapisz jako plik PDF

Sprzęt

KitKat dodaje kilka interfejsów API do obsługi nowych funkcji urządzeń. Najbardziej godne uwagi są emulacja kart opartych na hoście i nowe SensorManager.

Emulacja kart opartych na hoście w nfc

Emulacja kart opartych na hoście (HCE) umożliwia aplikacjom zachowanie się jak karty NFC lub czytniki kart NFC bez polegania na zastrzeżonym elemektorze Secure. Przed skonfigurowaniem HCE upewnij się, że funkcja HCE jest dostępna na urządzeniu za pomocą polecenia PackageManager.HasSystemFeature:

bool hceSupport = PackageManager.HasSystemFeature(PackageManager.FeatureNfcHostCardEmulation);

HCE wymaga, aby zarówno funkcja HCE, jak i Nfc uprawnienie zostały zarejestrowane w aplikacji AndroidManifest.xml:

<uses-feature android:name="android.hardware.nfc.hce" />

Ustawianie uprawnień NFC w opcjach aplikacji

Aby działać, HCE musi być w stanie uruchomić w tle i musi zacząć, gdy użytkownik wykonuje transakcję NFC, nawet jeśli aplikacja korzystająca z HCE nie jest uruchomiona. Możemy to zrobić, pisząc kod HCE jako Service. Usługa HCE implementuje HostApduService interfejs, który implementuje następujące metody:

  • ProcessCommandApdu — jednostka danych protokołu aplikacji (APDU) jest wysyłana między czytnikiem NFC a usługą HCE. Ta metoda używa modułu ADPU z czytnika i zwraca jednostkę danych w odpowiedzi.

  • OnDeactivated — element HostAdpuService jest dezaktywowany, gdy usługa HCE nie komunikuje się już z czytnikiem NFC.

Usługa HCE musi być również zarejestrowana w manifeście aplikacji i ozdobiona odpowiednimi uprawnieniami, filtrem intencji i metadanymi. Poniższy kod jest przykładem zarejestrowanego HostApduService w manifeście systemu Android przy użyciu atrybutu (aby uzyskać więcej informacji na temat atrybutów, zapoznaj się z przewodnikiem manifestu Service platformy Xamarin pracującym z systemem Android):

[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)
    {
        ...
    }
}

Powyższa usługa umożliwia czytnikowi NFC interakcję z aplikacją, ale czytnik NFC nadal nie ma możliwości poznania, czy ta usługa emuluje kartę NFC, której potrzebuje do skanowania. Aby ułatwić czytnikowi NFC identyfikację usługi, możemy przypisać usłudze unikatowy identyfikator aplikacji (AID). Określamy pomoc wraz z innymi metadanymi dotyczącymi usługi HCE w pliku zasobów XML zarejestrowanym za pomocą atrybutu MetaData (zobacz przykładowy kod powyżej). Ten plik zasobu określa jeden lub więcej filtrów AID — unikatowe ciągi identyfikatorów w formacie szesnastkowym odpowiadającym identyfikatorom AID jednego lub większej liczby urządzeń czytnika NFC:

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

Oprócz filtrów AID plik zasobu XML zawiera również opis usługi HCE, określa grupę POMOCY (wniosek o płatności a "inne") i, w przypadku aplikacji płatniczej, baner 260x96 dp do wyświetlenia użytkownikowi.

Konfiguracja opisana powyżej zawiera podstawowe bloki konstrukcyjne aplikacji emulujące kartę NFC. Sama komunikacja NFC wymaga wykonania kilku kolejnych kroków i dalszych testów w celu skonfigurowania. Aby uzyskać więcej informacji na temat emulacji kart opartych na hoście, zapoznaj się z portalem dokumentacji systemu Android. Aby uzyskać więcej informacji na temat korzystania z komunikacji NFC z platformą Xamarin, zapoznaj się z przykładami Xamarin NFC.

Czujniki

KitKat zapewnia dostęp do czujników urządzenia za pośrednictwem elementu SensorManager. Dzięki SensorManager systemowi operacyjnemu można zaplanować dostarczanie informacji z czujnika do aplikacji w partiach, zachowując żywotność baterii.

KitKat jest również dostarczany z dwoma nowymi typami czujników do śledzenia kroków użytkownika. Są one oparte na akcelerometrze i obejmują:

  • StepDetector — aplikacja jest powiadamiana/wybudowana, gdy użytkownik wykonuje krok, a narzędzie wykrywacza zapewnia wartość czasu dla momentu wystąpienia kroku.

  • StepCounter — śledzi liczbę kroków, które użytkownik podjął od momentu zarejestrowania czujnika do momentu następnego ponownego uruchomienia urządzenia.

Poniższy zrzut ekranu przedstawia licznik kroków w działaniu:

Zrzut ekranu przedstawiający aplikację SensorsActivity z licznikiem kroków

Element można utworzyć SensorManager przez wywołanie i rzutowanie GetSystemService(SensorService) wyniku jako SensorManager. Aby użyć licznika kroków, wywołaj metodę GetDefaultSensorSensorManagerna . Możesz zarejestrować czujnik i nasłuchiwać zmian w liczbie kroków za pomocą ISensorEventListener interfejs, jak pokazano w poniższym przykładzie kodu:

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 jest wywoływana, jeśli liczba kroków jest aktualizowana, gdy aplikacja znajduje się na pierwszym planie. Jeśli aplikacja przejdzie w tle lub urządzenie jest w stanie uśpienia, OnSensorChanged nie zostanie wywołana. Jednak kroki będą nadal liczone do momentu UnregisterListener wywołania.

Należy pamiętać, że wartość licznika kroków jest skumulowana we wszystkich aplikacjach rejestrujących czujnik. Oznacza to, że nawet jeśli odinstalujesz i ponownie zainstalujesz aplikację i zainicjujesz count zmienną o wartości 0 podczas uruchamiania aplikacji, wartość zgłoszona przez czujnik pozostanie całkowitą liczbą kroków podjętych podczas rejestracji czujnika, niezależnie od tego, czy aplikacja, czy inna. Możesz zapobiec dodawaniu aplikacji do licznika kroków, wywołując metodę UnregisterListenerSensorManager, jak pokazano w poniższym kodzie:

protected override void OnPause()
{
    base.OnPause ();
    senMgr.UnregisterListener(this);
}

Ponowne uruchomienie urządzenia powoduje zresetowanie liczby kroków do 0. Aplikacja będzie wymagać dodatkowego kodu, aby upewnić się, że raportuje dokładną liczbę aplikacji, niezależnie od innych aplikacji korzystających z czujnika lub stanu urządzenia.

Uwaga

Chociaż interfejs API wykrywania kroków i zliczania jest dostarczany z zestawem KitKat, nie wszystkie telefony są wyposażone w czujnik. Możesz sprawdzić, czy czujnik jest dostępny, uruchamiając PackageManager.HasSystemFeature(PackageManager.FeatureSensorStepCounter);polecenie , lub sprawdź, czy zwrócona wartość GetDefaultSensor nie nullma wartości .

Narzędzia programistyczne

Nagrywanie ekranu

KitKat zawiera nowe funkcje nagrywania ekranu, dzięki czemu deweloperzy mogą rejestrować aplikacje w działaniu. Nagrywanie ekranu jest dostępne za pośrednictwem klienta mostka debugowania systemu Android (ADB ), który można pobrać jako część zestawu Android SDK.

Aby zarejestrować ekran, połącz urządzenie; następnie znajdź instalację zestawu Android SDK, przejdź do katalogu narzędzi platformy i uruchom klienta adb :

adb shell screenrecord /sdcard/screencast.mp4

Powyższe polecenie spowoduje zarejestrowanie domyślnego 3-minutowego wideo w domyślnej rozdzielczości 4 Mb/s. Aby edytować długość, dodaj flagę --time-limit . Aby zmienić rozdzielczość, dodaj flagę --bit-rate . Następujące polecenie spowoduje zarejestrowanie minutowego wideo o długości 8 Mb/s:

adb shell screenrecord --bit-rate 8000000 --time-limit 60 /sdcard/screencast.mp4

Film wideo można znaleźć na urządzeniu — zostanie on wyświetlony w galerii po zakończeniu nagrywania.

Inne dodatki KitKat

Oprócz opisanych powyżej zmian kitKat umożliwia:

  • Korzystanie z pełnego ekranu — KitKat wprowadza nowy tryb immersyjny do przeglądania zawartości, gry i uruchamiania innych aplikacji, które mogą korzystać z pełnego ekranu.

  • Dostosowywanie powiadomień — uzyskiwanie dodatkowych szczegółów dotyczących powiadomień systemowych za pomocą polecenia NotificationListenerService . Dzięki temu można prezentować informacje w inny sposób w aplikacji.

  • Dublowalne zasoby z możliwością rysowania — zasoby możliwe do rysowania mają nowe autoMirrored atrybut, który informuje system o utworzeniu dublowanej wersji obrazów, które wymagają przerzucania układów od lewej do prawej.

  • Wstrzymywanie animacji — wstrzymywanie i wznawianie animacji utworzonych za pomocą polecenia Animator Klasa.

  • Odczytywanie dynamicznego zmieniania tekstu — oznacza części interfejsu użytkownika, które aktualizują się dynamicznie przy użyciu nowego tekstu jako "regiony na żywo" przy użyciu nowego accessibilityLiveRegion atrybut, aby nowy tekst był odczytywany automatycznie w trybie ułatwień dostępu.

  • Ulepszanie środowiska audio — głośniejsze utwory za pomocą LoudnessEnhancer , znajdź szczytowe i rms strumienia audio za pomocą Visualizerklasa i uzyskaj informacje z sygnatury czasowej audio, aby ułatwić synchronizację audio-wideo.

  • Synchronizacja elementu ContentResolver w interwale niestandardowym — kitKat dodaje pewną zmienność do czasu wykonania żądania synchronizacji. Zsynchronizuj element w niestandardowym ContentResolver czasie lub interwale, wywołując ContentResolver.RequestSync i przekazując element SyncRequest.

  • Rozróżnianie kontrolerów — w zestawieKat kontrolery mają przypisane unikatowe identyfikatory całkowite, do których można uzyskać dostęp za pośrednictwem właściwości urządzenia ControllerNumber . Ułatwia to odróżnić graczy w grze.

  • Zdalne sterowanie — dzięki kilku zmianom po stronie sprzętu i oprogramowania KitKat umożliwia przekształcenie urządzenia wyposażonego w nadajnik IR w zdalne sterowanie przy użyciu ConsumerIrServiceprogramu i interakcję z urządzeniami peryferyjnymi z nowym RemoteController Interfejsów api.

Aby uzyskać więcej informacji na temat powyższych zmian interfejsu API, zapoznaj się z omówieniem interfejsów API systemu Google Android 4.4.

Podsumowanie

W tym artykule przedstawiono niektóre nowe interfejsy API dostępne w systemie Android 4.4 (poziom 19 interfejsu API) i opisano najlepsze rozwiązania dotyczące przechodzenia aplikacji do zestawu KitKat. Przedstawiono w nim zmiany interfejsów API wpływające na środowisko użytkownika, w tym strukturę przejścia i nowe opcje ich obsługi. Następnie wprowadzono platformę Storage-Access Framework i klasę, a także nowe interfejsy API DocumentsProvider drukowania. Zbadano emulację kart opartych na hoście NFC i sposób pracy z czujnikami o niskiej mocy, w tym dwoma nowymi czujnikami do śledzenia kroków użytkownika. Na koniec zademonstrowano przechwytywanie pokazów aplikacji w czasie rzeczywistym za pomocą nagrywania ekranu oraz podano szczegółową listę zmian i dodatków interfejsu API KitKat.