Interfejsy API Androida 4.3

Poziom interfejsu API: 18

Android 4.3 (JELLY_BEAN_MR2) to aktualizacja wersji Jelly Bean, która zawiera nowe funkcje dla użytkowników i programistów. Ten dokument zawiera wprowadzenie do najważniejszych nowych interfejsów API.

Jako deweloper aplikacji jak najszybciej pobierz obraz systemu Android 4.3 i platformę SDK z Menedżera pakietu SDK. Jeśli nie masz urządzenia z Androidem 4.3, na którym możesz przetestować aplikację, użyj obrazu systemu Android 4.3, aby przetestować aplikację na emulatorze Androida. Następnie utwórz aplikacje na platformę Android 4.3, aby zacząć korzystać z najnowszych interfejsów API.

Zaktualizuj docelowy poziom interfejsu API

Aby lepiej zoptymalizować aplikację na urządzeniach z Androidem 4.3: ustaw targetSdkVersion na "18", zainstaluj ją w obrazie systemu Android 4.3 przetestować ją, a następnie opublikować aktualizację z tą zmianą.

Z interfejsów API w Androidzie 4.3 możesz korzystać, jednocześnie obsługując starsze wersje, dodając w kodzie, które sprawdzają poziom interfejsu API systemu przed jego wykonaniem minSdkVersion nie obsługuje interfejsów API. Więcej informacji na temat zachowania zgodności wstecznej można znaleźć w artykule Obsługa różnych Wersje platformy.

W Bibliotece pomocy Androida są również dostępne różne interfejsy API, które umożliwiają implementację nowych funkcji w starszych wersjach platformy.

Więcej informacji o tym, jak działają poziomy interfejsu API, znajdziesz w artykule Co to jest poziom interfejsu API?

Ważne zmiany w działaniu

Jeśli aplikacja na Androida została już przez Ciebie opublikowana, pamiętaj, że zmiany w Androidzie 4.3 mogą na nią wpłynąć.

Jeśli aplikacja używa intencji niejawnych...

Aplikacja może działać nieprawidłowo w środowisku profilu z ograniczonym dostępem.

Użytkownicy korzystający z profilu z ograniczonym dostępem mogą nie mieć dostępu do wszystkich standardowych aplikacji na Androida. Na przykład w profilu z ograniczonym dostępem może być wyłączona przeglądarka internetowa i aplikacja do obsługi aparatu. Twoja aplikacja nie powinna zakładać, że są dostępne inne aplikacje, ponieważ jeśli wywołasz funkcję startActivity() bez weryfikowania, czy aplikacja jest dostępna do obsługi funkcji Intent, może się ona zawiesić w profilu z ograniczonym dostępem.

Podczas korzystania z domyślnego zamiaru zawsze należy sprawdzić, czy aplikacja jest dostępna do obsługi zamiaru, wywołując resolveActivity() lub queryIntentActivities(). Na przykład:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

Jeśli Twoja aplikacja korzysta z kont...

Aplikacja może działać nieprawidłowo w środowisku profilu z ograniczonym dostępem.

Użytkownicy w ograniczonym środowisku profili nie mają domyślnie dostępu do kont użytkowników. Jeśli Twoja aplikacja zależy od Account, może się zawieszać lub zachowywać nieoczekiwanie, gdy jest używana na profilu z ograniczonymi uprawnieniami.

Jeśli chcesz całkowicie uniemożliwić profilom z ograniczonym dostępem korzystanie z Twojej aplikacji aplikacja korzysta z poufnych informacji o koncie, określ atrybut android:requiredAccountType w pliku manifestu <application> .

Jeśli chcesz zezwolić profilom z ograniczeniami na dalsze korzystanie z aplikacji, mimo że nie mogą tego zrobić własnych kont, możesz wyłączyć funkcje aplikacji, które wymagają konta lub zezwól profilom z ograniczonym dostępem na dostęp do kont utworzonych przez użytkownika głównego. Więcej informacji znajdziesz w sekcji Obsługa kont na profilu ograniczonym.

Jeśli Twoja aplikacja używa VideoView…

Film może być wyświetlany w mniejszym rozmiarze w Androidzie 4.3.

W poprzednich wersjach Androida widżet VideoView był nieprawidłowo wyświetlany. obliczył, że wartość "wrap_content" dla layout_height i layout_width jest taka sama jak "match_parent". Jeśli więc użyjesz opcji "wrap_content" na wysokość lub szerokość, być może uzyskasz wcześniej wybrany układ filmu, W Androidzie 4.3 i nowszych film może być znacznie rzadziej wyświetlany. Aby rozwiązać ten problem, zastąp "wrap_content" wartością "match_parent" i sprawdź, czy film wyświetla się zgodnie z oczekiwaniami w Androidzie 4.3 i starszych wersjach.

Profile z ograniczeniami

Na tabletach z Androidem użytkownicy mogą teraz tworzyć profile z ograniczonymi uprawnieniami na podstawie konta głównego. Gdy użytkownicy tworzą profil z ograniczonym dostępem, mogą włączyć ograniczenia, takie jak aplikacje dostępne na tym profilu. Nowy zestaw interfejsów API w Androidzie 4.3 umożliwia również ustawień ograniczeń dla tworzonych przez siebie aplikacji. Za pomocą nowych interfejsów API możesz na przykład zezwolić użytkownikom na kontrolowanie, jakiego typu treści są dostępne w aplikacji, gdy działa ona w środowisku profilu z ograniczonymi uprawnieniami.

Interfejs użytkownika do zarządzania wprowadzonymi przez Ciebie ograniczeniami jest zarządzany przez aplikację Ustawienia systemu. Aby wyświetlić użytkownikowi ustawienia ograniczeń aplikacji: musisz zadeklarować ograniczenia stosowane przez Twoją aplikację, tworząc obiekt BroadcastReceiver, który odbiera intencję ACTION_GET_RESTRICTION_ENTRIES. System wywołuje ten zamiar, aby zapytać wszystkie aplikacje o dostępne ograniczenia, a następnie tworzy interfejs użytkownika, który pozwala głównemu użytkownikowi zarządzać ograniczeniami dla każdego profilu z ograniczeniami.

W metodzie onReceive() w Twojej BroadcastReceiver musisz utworzyć RestrictionEntry dla każdej restrykcji oferowanej przez aplikację. Każdy element RestrictionEntry definiuje tytuł i opis ograniczenia oraz jeden z tych typów danych:

  • TYPE_BOOLEAN dla ograniczenia, które ma wartość prawda lub fałsz.
  • TYPE_CHOICE w przypadku ograniczenia, które ma wiele opcji wzajemnie się wykluczających (opcje z opcji z jednego wyboru).
  • TYPE_MULTI_SELECT w przypadku ograniczenia, które ma więcej niż 1 opcję (opcje w polu wyboru).

Następnie umieszczasz wszystkie obiekty RestrictionEntry w obiekcie ArrayList i przekazujesz go do wyniku odbiornika transmisji jako wartość dodatkowego obiektu EXTRA_RESTRICTIONS_LIST.

System tworzy interfejs pod kątem ograniczeń aplikacji w aplikacji Ustawienia i zapisuje każdy z nich używając unikalnego klucza podanego przez Ciebie dla każdej jednostki RestrictionEntry obiektu. Gdy użytkownik otworzy aplikację, możesz zapytać o aktualne ograniczenia przez Dzwonię pod getApplicationRestrictions(). Zwraca to obiekt Bundle zawierający pary klucz-wartość dla każdej z ograniczeń zdefiniowanych za pomocą obiektów RestrictionEntry.

Jeśli chcesz wprowadzić bardziej szczegółowe ograniczenia, których nie można obsługiwać za pomocą wartości logicznych, jednowyborowych i wielowyborowych, możesz utworzyć aktywność, w której użytkownik może określić ograniczenia i otworzyć tę aktywność z ustawień ograniczeń. W odbiorniku transmisji uwzględnij dodatkowy parametr EXTRA_RESTRICTIONS_INTENT w wyniku Bundle. Ten dodatek musi zawierać parametr Intent wskazujący klasę Activity, która ma zostać uruchomiona (użyj metody putParcelable(), aby przekazać EXTRA_RESTRICTIONS_INTENT z zamierzeniem). Gdy główny użytkownik wejdzie do Twojej aktywności, aby ustawić niestandardowe ograniczenia, Twoja aktywność musi zwrócić wynik zawierający wartości ograniczeń w dodatku za pomocą klucza EXTRA_RESTRICTIONS_LIST lub EXTRA_RESTRICTIONS_BUNDLE, w zależności od tego, czy określisz obiekty RestrictionEntry czy pary klucz-wartość.

Obsługa kont w profilu z ograniczonym dostępem

Wszystkie konta dodane do użytkownika głównego są dostępne w profilu z ograniczonym dostępem, konta nie są domyślnie dostępne z interfejsów API AccountManager. Jeśli spróbujesz dodać konto z AccountManager w profilu z ograniczonymi uprawnieniami, nie uda Ci się tego zrobić. Ze względu na te ograniczenia masz: 3 opcje:

  • Zezwalaj na dostęp do kont właściciela z profilu ograniczonego.

    Aby uzyskać dostęp do konta z profilu z ograniczonym dostępem, musisz dodać atrybut android:restrictedAccountType do tagu <application>:

    <application ...
        android:restrictedAccountType="com.example.account.type" >

    Uwaga: włączenie tego atrybutu spowoduje, że Twoje dane dostępu aplikacji do kont głównego użytkownika z profili ograniczonych. Zezwalaj na to tylko wtedy, gdy wyświetlane przez aplikację informacje nie zawierają informacji umożliwiających identyfikację, które są uważane za poufne. Ustawienia systemowe informują głównego użytkownika, że aplikacja przyznaje ograniczone profile do kont, więc użytkownik powinien mieć jasność, że dostęp do konta jest ważny dla działania aplikacji. W miarę możliwości zapewnić głównemu użytkownikowi dostęp do odpowiednich ograniczeń, aby określić poziom dostępu do konta; jest dozwolona w Twojej aplikacji.

  • Jeśli nie możesz modyfikować kont, wyłącz określone funkcje.

    Jeśli chcesz używać kont, ale nie są one wymagane do korzystania z podstawowych funkcji aplikacji, możesz sprawdzić dostępność kont i wyłączyć funkcje, gdy nie są dostępne. Najpierw sprawdź, czy masz już dostępne konto. Jeśli nie, sprawdź, czy można utworzyć nowe konto, wykonując wywołanie getUserRestrictions() i sprawdzając dodatkowy parametr DISALLOW_MODIFY_ACCOUNTS w wyniku. Jeśli jest to true, musisz wyłączyć te funkcje, które wymagają dostępu do konta. Na przykład:

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }

    Uwaga: w tym scenariuszu nie deklaruj żadnych nowych atrybutów w pliku manifestu.

  • Wyłącz aplikację, gdy nie masz dostępu do kont prywatnych.

    Jeśli zależy Ci na tym, aby aplikacja nie była dostępna dla profili z ograniczonymi uprawnieniami, ponieważ zależy ona od poufnych danych osobowych na koncie (a profily z ograniczonymi uprawnieniami obecnie nie mogą dodawać nowych kont), dodaj atrybut android:requiredAccountType do elementu <application>:

    <application ...
        android:requiredAccountType="com.example.account.type" >

    Na przykład aplikacja Gmail używa tego atrybutu do wyłączenia się dla profili ograniczonych, bo osobisty adres e-mail właściciela nie powinien być dostępny w przypadku profili z ograniczonym dostępem.

  • Komunikacja bezprzewodowa i łączność

    Bluetooth Low Energy (Smart ready)

    Android obsługuje teraz Bluetooth Low Energy (LE) z nowymi interfejsami API w android.bluetooth. Dzięki nowym interfejsom API możesz tworzyć aplikacje na Androida, które komunikują się z urządzeniami peryferyjnymi Bluetooth Low Energy, takimi jak pulsoksymetry czy krokomierze.

    Bluetooth LE to funkcja sprzętowa, która nie jest dostępna na wszystkich urządzeniach z Androidem, dlatego w pliku manifestu musisz zadeklarować element <uses-feature> dla "android.hardware.bluetooth_le":

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

    Jeśli znasz już interfejsy API klasycznego Bluetootha na Androida, pamiętaj, że korzystanie z interfejsów API Bluetooth LE różni się nieco od tego. Najważniejsze jest to, że istnieje teraz klasa BluetoothManager, której należy użyć w przypadku niektórych operacji wysokiego poziomu. takie jak zdobycie BluetoothAdapter, uzyskanie listy połączonych urządzeń i sprawdzanie ich stanu. Oto w jaki sposób możesz teraz pobrać BluetoothAdapter:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();

    Aby wykryć urządzenia peryferyjne Bluetooth LE, wywołaj funkcję startLeScan() w obiekcie BluetoothAdapter, przekazując mu implementację interfejsu BluetoothAdapter.LeScanCallback. Gdy Bluetooth adapter wykryje urządzenie peryferyjne Bluetooth LE, Twoja implementacja BluetoothAdapter.LeScanCallback otrzymuje wywołanie do Metoda onLeScan(). Ta metoda zwraca obiekt BluetoothDevice reprezentujący wykryte urządzenie, wartość RSSI urządzenia oraz tablicę bajtów zawierającą rekord reklamy urządzenia.

    Jeśli chcesz skanować w poszukiwaniu tylko określonych typów urządzeń peryferyjnych, możesz zamiast tego wywołać funkcję startLeScan() i dodać tablicę obiektów UUID określających usługi GATT obsługiwane przez Twoją aplikację.

    Uwaga: za pomocą starszych interfejsów API możesz skanować tylko urządzenia Bluetooth LE lubskanować urządzenia Bluetooth Classic. Nie można skanować jednocześnie urządzeń Bluetooth LE i klasycznych.

    Aby połączyć się z urządzeniem peryferyjnym Bluetooth LE, wywołaj metodę connectGatt() obiektu BluetoothDevice, przekazując mu implementację interfejsu BluetoothGattCallback. Twoja implementacja BluetoothGattCallback otrzymuje wywołania zwrotne dotyczące stanu połączeń z urządzeniem i innych zdarzeń. Jest w okresie: onConnectionStateChange() wywołanie zwrotne, które można rozpocząć komunikację z urządzeniem, jeśli metoda przekazuje STATE_CONNECTED jako nowy stan.

    Dostęp do funkcji Bluetooth na urządzeniu wymaga też, aby aplikacja poprosiła o pewne uprawnienia użytkownika Bluetooth. Więcej informacji znajdziesz w przewodniku po interfejsie Bluetooth Low Energy API.

    Tryb Wi-Fi tylko do skanowania

    Android może użyć sieci Wi-Fi, aby określić lokalizację użytkownika, przez skanowanie pobliskich punktów dostępu. Użytkownicy często wyłączają jednak Wi-Fi, aby oszczędzać baterię, co powoduje, że dane o lokalizacji są mniej dokładne. Android obejmuje teraz tryb „tylko skanowanie”, który umożliwia Wi-Fi urządzenia skanowanie punktów dostępu, aby pomóc w ustaleniu lokalizacji bez łączenia się z punktem dostępu, co znacznie zmniejsza zużycie baterii.

    Jeśli chcesz poznać lokalizację użytkownika, ale Wi-Fi jest obecnie wyłączone, możesz poprosić użytkownika o włączenie trybu skanowania Wi-Fi, wywołując funkcję startActivity() z działaniem ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.

    Konfiguracja Wi-Fi

    Nowe interfejsy API WifiEnterpriseConfig umożliwiają usługom przeznaczonym dla firm automatyzację konfiguracji Wi-Fi na urządzeniach zarządzanych.

    Szybka odpowiedź na połączenia przychodzące

    Od wersji Androida 4.0 funkcja „Szybka odpowiedź” umożliwia użytkownikom odpowiadanie na przychodzące połączenia natychmiastową wiadomością tekstową bez konieczności odbierania połączenia ani odblokowywania urządzenia. Do tej pory te szybkie wiadomości były zawsze obsługiwane przez domyślną aplikację do obsługi SMS-ów. Teraz każda aplikacja może zadeklarować obsługę tych wiadomości, tworząc Servicez filtrem intencji ACTION_RESPOND_VIA_MESSAGE.

    Gdy użytkownik odpowie na przychodzące połączenie, aplikacja Telefon wysyła intent ACTION_RESPOND_VIA_MESSAGE z URI opisującym odbiorcę (rozmówcę) oraz dodatkowy parametr EXTRA_TEXT z wiadomością, którą użytkownik chce wysłać. Gdy usługa otrzymuje intencję, powinna dostarczyć komunikat i natychmiast się zatrzymuje (aplikacja nie powinna wykazywać aktywności).

    Aby otrzymywać te intencje, musisz zadeklarować uprawnienie SEND_RESPOND_VIA_MESSAGE.

    Multimedia

    Ulepszenia MediaExtractor i MediaCodec

    Android ułatwia teraz tworzenie własnych odtwarzaczy strumieniowego przesyłania danych w standardzie DASH (dynamiczne adaptacyjne strumieniowe przesyłanie danych przez HTTP) zgodnie ze standardem ISO/IEC 23009-1 za pomocą istniejących interfejsów API w MediaCodecMediaExtractor. Platforma, na której są oparte te interfejsy API, została zaktualizowana, analizowanie fragmentarycznych plików MP4, ale Twoja aplikacja nadal odpowiada za analizę metadanych MPD i przekazywać poszczególne strumienie do usługi MediaExtractor.

    Jeśli chcesz używać DASH z zaszyfrowanymi treściami, zwróć uwagę, że metoda getSampleCryptoInfo() zwraca metadane MediaCodec.CryptoInfo opisujące strukturę każdego zaszyfrowanego multimediów przykład. Do metody getPsshInfo() dodano też metodę MediaExtractor, dzięki której możesz uzyskać dostęp do metadanych PSSH dla multimediów DASH. Ta metoda zwraca mapę obiektów UUID na bajty, w której UUID określa schemat szyfrowania, a bajty to dane specyficzne dla tego schematu.

    DRM multimediów

    Nowa klasa MediaDrm zapewnia modułowe rozwiązanie do zarządzania prawami cyfrowymi (DRM) w przypadku treści multimedialnych, oddzielając kwestie DRM od odtwarzania multimediów. Na przykład rozdzielenie interfejsu API umożliwia odtwarzanie treści zaszyfrowanych za pomocą Widevine bez konieczności korzystania z formatu multimediów Widevine. Rozwiązanie DRM obsługuje też standard DASH Common Encryption, mogą stosować różne schematy DRM w przypadku treści przesyłanych strumieniowo.

    Możesz użyć MediaDrm, aby uzyskać nieprzezroczyste wiadomości z żądaniem klucza i przetworzyć wiadomości z odpowiedzią na żądanie klucza z serwera na potrzeby pozyskiwania i zarządzania licencjami. Twoja aplikacja jest odpowiedzialna za obsługę komunikacji sieciowej z serwerami. Klasa MediaDrm zapewnia tylko możliwość generowania i przetwarzania wiadomości.

    Interfejsy MediaDrm API są przeznaczone do używania w połączeniu z interfejsami MediaCodec API wprowadzonymi w Androidzie 4.1 (poziom interfejsu API 16), w tym MediaCodec do kodowania i dekodowania treści, MediaCrypto do obsługi zaszyfrowanych treści oraz MediaExtractor do wyodrębniania i demultipleksowania treści.

    Najpierw musisz utworzyć MediaExtractor i MediaCodec obiektów. Otrzymasz wtedy dostęp do schematu DRM UUID, zwykle z metadanych zawartych w treści, i używaj ich do tworzenia wystąpienia obiektu MediaDrm za pomocą jego konstruktora.

    Kodowanie wideo z urządzenia Surface

    Android 4.1 (poziom interfejsu API 16) dodał klasę MediaCodec dla niskiego poziomu kodowania i dekodowania treści multimedialnych. Do kodowania filmu Android 4.1 wymaga podania przez Ciebie multimediów z tablicy ByteBuffer, ale Android 4.3 umożliwia teraz korzystanie z Surface jako wejścia kodera. Umożliwia to na przykład kodowanie danych wejściowych z istniejącego pliku wideo lub za pomocą klatek wygenerowanych z OpenGL ES.

    Aby użyć Surface jako wejścia do kodera, najpierw wywołaj configure() dla MediaCodec. Następnie zadzwoń pod numer createInputSurface(), aby uzyskać Surface, na którym możesz przesyłać strumieniowo swoje multimedia.

    Możesz na przykład użyć danego obiektu Surface jako okna dla kontekstu OpenGL, przekazując go do funkcji eglCreateWindowSurface(). Następnie podczas renderowania powierzchni wywołaj funkcję eglSwapBuffers(), aby przekazać ramkę do funkcji MediaCodec.

    Aby rozpocząć kodowanie, wywołaj start() na urządzeniu MediaCodec. Gdy skończysz, zadzwoń pod numer signalEndOfInputStream() aby zakończyć kodowanie i wywołać release() na Surface

    Muxowanie mediów

    Nowa klasa MediaMuxer umożliwia multipleksowanie między jednym strumieniem audio i jednym strumieniem wideo. Te interfejsy API stanowią odpowiednik MediaExtractor dodano w Androidzie 4.2 klasę do demultipleksowania (demultipleksowania) multimediów.

    Obsługiwane formaty wyjściowe są zdefiniowane w sekcji MediaMuxer.OutputFormat. Obecnie Jedynym obsługiwanym formatem wyjściowym jest MP4, a MediaMuxer obsługuje obecnie tylko jeden strumień audio lub wideo w danym momencie.

    Aplikacja MediaMuxer jest przeznaczona głównie do działania z usługą MediaCodec aby przetworzyć wideo w MediaCodec, a następnie zapisać plik dane wyjściowe do pliku MP4 za pomocą MediaMuxer. Możesz też używać MediaMuxer w połączeniu z MediaExtractor do edycji multimediów bez konieczności kodowania ani dekodowania.

    Postęp odtwarzania i przewijanie dla RemoteControlClient

    W Androidzie 4.0 (poziom interfejsu API 14) dodano RemoteControlClient, aby umożliwić sterowanie odtwarzaniem multimediów z urządzeń zdalnego sterowania, takich jak elementy sterujące dostępne na ekranie blokady. Android 4.3 umożliwia teraz takim kontrolerom wyświetlanie odtwarzania oraz przyciski i elementy sterujące do przewijania odtwarzania. Jeśli na urządzeniu jest włączony pilot za pomocą interfejsów API RemoteControlClient, możesz zezwolić na odtwarzanie wymaga optymalizacji przez wdrożenie 2 nowych interfejsów.

    Najpierw musisz włączyć flagę FLAG_KEY_MEDIA_POSITION_UPDATE, przekazując ją do setTransportControlsFlags()

    Następnie zaimplementuj te 2 nowe interfejsy:

    RemoteControlClient.OnGetPlaybackPositionListener
    Obejmuje to wywołanie zwrotne onGetPlaybackPosition(), które dotyczy bieżącej pozycji Twoich multimediów, gdy pilot musi aktualizować postęp w interfejsie użytkownika.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    Obejmuje to wywołanie zwrotne onPlaybackPositionUpdate(), które informuje aplikację o nowym kodzie czasu multimediów, gdy użytkownik przewija odtwarzanie za pomocą interfejsu pilota.

    Po zaktualizowaniu odtwarzania z nową pozycją wywołaj setPlaybackState(), aby wskazać nowy stan, pozycję i szybkość odtwarzania.

    Po zdefiniowaniu tych interfejsów możesz skonfigurować je dla swojego urządzenia RemoteControlClient, wywołując metodę setOnGetPlaybackPositionListener() i setPlaybackPositionUpdateListener().

    Grafika

    Obsługa OpenGL ES 3.0

    W Androidzie 4.3 dodaliśmy interfejsy Java i wbudowaną obsługę OpenGL ES 3.0. Główne nowe funkcje OpenGL ES 3.0:

    • Zaawansowane efekty wizualne
    • Wysokiej jakości kompresja tekstur ETC2/EAC jako standardowa funkcja
    • Nowa wersja języka cieniowania GLSL ES z obsługą liczb całkowitych i 32-bitowej liczby zmiennoprzecinkowej.
    • Zaawansowane renderowanie tekstur
    • Szersza standaryzacja rozmiaru tekstury i formatów bufora renderowania

    Interfejs Java dla OpenGL ES 3.0 na Androidzie zawiera dodatek GLES30. Jeśli używasz OpenGL ES 3.0, pamiętaj, aby zadeklarować go w pliku manifestu za pomocą elementu <uses-feature> i atrybutu android:glEsVersion. Na przykład:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>

    Pamiętaj, aby określić kontekst OpenGL ES, wywołując funkcję setEGLContextClientVersion(), przesyłając wersję 3.

    Więcej informacji o używaniu OpenGL ES, w tym o sprawdzaniu obsługiwanej wersji OpenGL ES na urządzeniu w czasie wykonywania, znajdziesz w przewodniku po interfejsie API OpenGL ES.

    Mipmapowanie dla rysunków

    Użycie mapy MIP jako źródła bitmapy lub obiektu rysowanego to prosty sposób na uzyskanie obrazu wysokiej jakości i różnych skal obrazu, co może być szczególnie przydatne, jeśli oczekujesz, że obraz będzie skalowany podczas animacji.

    Android 4.2 (poziom interfejsu API 17) obsługuje mipmapy w klasie Bitmap. Android zamienia obrazy mip w Twoim pliku Bitmap, gdy podasz źródło mipmapy i włączysz opcję setHasMipMap(). Teraz w Androidzie 4.3 możesz włączyć również mipmapy dla obiektu BitmapDrawable, przesyłając zasób mipmap ustawiając atrybut android:mipMap w pliku zasobów bitmapy lub wywołując hasMipMap().

    Interfejs

    Wyświetlanie nakładek

    Nowa klasa ViewOverlay zapewnia przezroczystą warstwę View, do którego można dodawać treści wizualne, który nie ma wpływu w hierarchii układu. Możesz otrzymać ViewOverlay na dowolną kwotę View, dzwoniąc pod numer getOverlay(). Nakładka ma zawsze taki sam rozmiar i pozycję jak widok hosta (widok, z którego została utworzona). Pozwala to dodawać treści, które pojawiają się przed widokiem hosta, ale nie mogą wykraczać poza jego granice.

    Użycie ViewOverlay jest szczególnie przydatne, gdy chcesz utworzyć animacje, np. przesuwanie widoku poza jego kontener lub przemieszczanie elementów po ekranie bez wpływu na hierarchię widoku. Ponieważ jednak obszarem użytkowym nakładki jest ograniczony do tego samego obszaru co widok hosta, jeśli chcesz animować widok na zewnątrz jego położenie w układzie, należy użyć nakładki z widoku nadrzędnego, która zawiera wymagane granic układu.

    Utworzenie nakładki dla widoku widżetu, takiego jak Button, może dodać Drawable obiektów do nakładki, wywołując add(Drawable) Jeśli wywołasz getOverlay() w celu wyświetlenia widoku układu, np. RelativeLayout, zwracanym obiektem jest ViewGroupOverlay. Klasa ViewGroupOverlay jest podklasą klasy ViewOverlay, która umożliwia też dodawanie obiektów View przez wywołanie metody add(View).

    Uwaga: wszystkie elementy rysowalne i widoki, które dodajesz do nakładki, są tylko wizualne. Nie mogą odbierać zdarzeń skupienia ani danych wejściowych.

    Na przykład ten kod animuje przesuwanie widoku w prawo, umieszczając go w nakładce widoku nadrzędnego, a następnie wykonując animację przesunięcia:

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();

    Układ granic optycznych

    W widokach zawierających 9 poprawek obrazów tła możesz określić, być wyrównane z sąsiadującymi widokami na podstawie „optycznego” granic obrazu tła, a nie niż „klip” od granic widoku.

    Na przykład rysunki 1 i 2 przedstawiają ten sam układ, ale wersja na rysunku 1 używa ograniczeń przycinania (zachowanie domyślne), a wersja na rysunku 2 – ograniczeń optycznych. Obrazy z 9 kawałków użyte na przycisku i w ramce zdjęcia zawierają wypełnienie wokół krawędzi, więc nie są wyrównane względem siebie ani tekstu, gdy używasz ograniczeń klipu.

    Uwaga: na zrzucie ekranu na ilustracjach 1 i 2 widoczne jest pole „Pokaż granice układu" Włączono ustawienie programisty. Przy każdym widoku czerwone linie wskazują, granice, niebieskie wskazują granice przycięcia, a różowy – marginesy.

    Rysunek 1. Układ z użyciem granic przycięcia (domyślnie).

    Rysunek 2. Układ z użyciem granic optycznych.

    Aby wyrównać widoki na podstawie ich granic optycznych, w jednym z layoutów nadrzędnych ustaw atrybut android:layoutMode na "opticalBounds". Na przykład:

    <LinearLayout android:layoutMode="opticalBounds" ... >

    Rysunek 3. Powiększony widok na 9 części przycisku Holo granic optycznych.

    Aby wszystko działało, obrazy złożone z dziewięciu poprawek zastosowane do tła widoków muszą określać wyznaczamy granice optyczne za pomocą czerwonych linii wzdłuż dolnej i prawej strony pliku z 9 poprawkami ( widoczne na rysunku 3). Linie czerwone wskazują obszary, które należy odjąć od granice przycięcia, pozostawiając optyczne granice obrazu.

    Gdy włączysz granice optyczne dla ViewGroup w swoim układzie, wszystkie widoki potomne odziedziczą tryb układu granic optycznych, chyba że zastąpisz go dla grupy, ustawiając wartość android:layoutMode na "clipBounds". Wszystkie elementy układu uwzględniają też granice optyczne widoków podrzędnych, dostosowując własne granice na podstawie granic optycznych widoków w nich zawartych. Jednak elementy układu (podklasy klasy ViewGroup) obecnie nie obsługuje granic optycznych w przypadku obrazów z dziewięcioma poprawkami zastosowanymi do własnego tła.

    Jeśli utworzysz widok niestandardowy, tworząc podklasę View, ViewGroup lub dowolnej podklasy, widok odziedziczy te właściwości związane z ograniczeniami optycznymi.

    Uwaga: wszystkie widżety obsługiwane przez motyw Holo zostały zaktualizowane o ograniczenia optyczne, w tym Button, Spinner, EditText i inne. Dzięki temu od razu masz czas, ustawiając Atrybut android:layoutMode do "opticalBounds", jeśli aplikacja stosuje motyw holograficzny. (Theme.Holo, Theme.Holo.Light itp.).

    Aby określić granice optyczne dla własnych obrazów 9-punktowych za pomocą narzędzia Draw 9-patch, przytrzymaj Control, gdy klikając piksele obramowania.

    Animacja wartości prostokątów

    W nowym formacie RectEvaluator możesz teraz animować 2 wartości elementu Rect. Ta nowa klasa to implementacja TypeEvaluator, którą możesz przekazać do ValueAnimator.setEvaluator().

    Detektor podłączania i zaznaczania okna

    Jeśli wcześniej chciałeś/chciałaś sprawdzać, czy widok został dołączony/odłączony od okna lub czy zmienił się jego punkt skupienia, musiałeś/musiałaś zastąpić klasę View, aby zaimplementować odpowiednio onAttachedToWindow()onDetachedFromWindow() lub onWindowFocusChanged().

    Aby teraz otrzymywać zdarzenia attach i detach, możesz zamiast tego zaimplementować ViewTreeObserver.OnWindowAttachListener i ustawić je w widoku za pomocą addOnWindowAttachListener(). Aby otrzymywać zdarzenia skupienia, możesz zaimplementować ViewTreeObserver.OnWindowFocusChangeListener i ustawić je dla widoku za pomocą addOnWindowFocusChangeListener()

    Obsługa overscanu telewizora

    Aby mieć pewność, że aplikacja wypełni cały ekran każdego telewizora, możesz włączyć nadmiarowe skanowanie układ aplikacji. Tryb nadmiarowego skanowania zależy od flagi FLAG_LAYOUT_IN_OVERSCAN, którą możesz włączyć, używając motywów platformy takich jak Theme_DeviceDefault_NoActionBar_Overscan lub włączając Styl windowOverscan w motywie niestandardowym.

    Orientacja ekranu

    Atrybut screenOrientationtagu <activity> obsługuje teraz dodatkowe wartości, aby uwzględnić preferencje użytkownika dotyczące automatycznego obracania:

    "userLandscape"
    Działanie takie samo jak w przypadku "sensorLandscape", z tą różnicą, że jeśli użytkownik wyłączy automatyczne obracanie, obraz zostanie zablokowany w normalnej orientacji poziomej i nie będzie się obracać.
    "userPortrait"
    Działanie takie samo jak w przypadku "sensorPortrait", z tą różnicą, że jeśli użytkownik wyłączy automatyczne obracanie, obraz zostanie zablokowany w normalnej orientacji pionowej i nie będzie się obracać.
    "fullUser"
    Działanie takie samo jak w przypadku "fullSensor". Umożliwia obracanie w 4 kierunkach, z tym że jeśli użytkownik wyłączy automatyczne obracanie, obraz zostanie zablokowany w preferowanym położeniu.

    Dodatkowo możesz teraz zadeklarować "locked", aby zablokować orientację aplikacji w bieżącej orientacji ekranu.

    Animacje obrotu

    Nowe pole rotationAnimation w elementach WindowManager umożliwia wybranie jednej z 3 animacji, której chcesz użyć, gdy system zmieni orientację ekranu. Są to:

    Uwaga: te animacje są dostępne tylko wtedy, gdy ustawisz aktywność na „pełnoekranowy”. w tym trybie, który możesz włączać za pomocą motywów takich jak Theme.Holo.NoActionBar.Fullscreen.

    Oto, jak włączyć animację „przejście”:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }

    Dane wejściowe użytkownika

    Nowe typy czujników

    Nowy czujnik TYPE_GAME_ROTATION_VECTOR umożliwia wykrywanie obrotów urządzenia bez obaw o zakłócenia magnetyczne. W przeciwieństwie do czujnika TYPE_ROTATION_VECTOR czujnik TYPE_GAME_ROTATION_VECTOR nie jest oparty na kierunku północnym magnetycznym.

    Nowe czujniki TYPE_GYROSCOPE_UNCALIBRATED i TYPE_MAGNETIC_FIELD_UNCALIBRATED dostarczają nieprzetworzone dane z czujników bez do szacowania tendencyjności. Oznacza to, że istniejące czujniki TYPE_GYROSCOPETYPE_MAGNETIC_FIELD dostarczają dane, które uwzględniają szacowane odchylenie spowodowane dryfowaniem żyroskopu i twardym rdzeniem magnetycznym w urządzeniu. Natomiast nowa wersja „nieskalibrowana” dla różnych wersji tych czujników nieprzetworzone dane z czujnika i oddzielnie oferują szacowane wartości odchylenia. Te czujniki umożliwiają zastosowanie własnej kalibracji niestandardowej dla danych czujnika poprzez wzbogacenie oszacowanego odchylenia za pomocą danych zewnętrznych.

    Odbiornik powiadomień

    Do Androida 4.3 dodano nową klasę usługi (NotificationListenerService), która umożliwia aplikacji otrzymywanie informacji o nowych powiadomieniach publikowanych przez system.

    Jeśli Twoja aplikacja uzyskuje obecnie dostęp do powiadomień systemowych za pomocą interfejsów API usługi ułatwień dostępu, zaktualizuj ją, aby używała tych interfejsów API.

    dostawca kontaktów

    Zapytanie o „kontakty”

    Nowe zapytanie dotyczące dostawcy kontaktów, Contactables.CONTENT_URI, to skuteczny sposób na uzyskanie jednego Cursor, który zawiera wszystkie adresy e-mail i numery telefonów należące do wszystkich kontaktów pasujących do określonego zapytania.

    Zapytanie o różnice kontaktów

    Do dostawcy kontaktów dodaliśmy nowe interfejsy API, które pozwalają na efektywne wysyłanie zapytań dotyczących ostatnich zmian w danych kontaktów. Wcześniej aplikacja mogła otrzymywać powiadomienia, gdy coś zmieniło się w danych kontaktów, ale nie wiedziała dokładnie, co się zmieniło. Aby to sprawdzić, musiała pobrać wszystkie kontakty i przeanalizować je.

    Aby śledzić zmiany wstawek i aktualizacji, możesz teraz uwzględnić w zaznaczonym elemencie parametr CONTACT_LAST_UPDATED_TIMESTAMP, aby wysyłać zapytania tylko do tych kontaktów, które uległy zmianie od ostatniego zapytania dotyczącego dostawcy.

    Aby śledzić, które kontakty zostały usunięte, nowa tabela ContactsContract.DeletedContacts zawiera dziennik usuniętych kontaktów (każdy usunięty kontakt jest przechowywany w tej tabeli przez ograniczony czas). Podobnie jak w przypadku parametru CONTACT_LAST_UPDATED_TIMESTAMP, możesz użyć nowego parametru wyboru CONTACT_DELETED_TIMESTAMP, aby sprawdzić, które kontakty zostały usunięte od ostatniego zapytania do dostawcy. Tabela zawiera też stałą DAYS_KEPT_MILLISECONDS, która określa liczbę dni (w milisekundach), przez które dziennik ma być przechowywany.

    Dodatkowo dostawca kontaktów transmituje teraz działanie CONTACTS_DATABASE_CREATED, gdy użytkownik czyści pamięć kontaktów w menu ustawień systemowych, odtwarzając w ten sposób Baza danych dostawcy kontaktów. Jego zadaniem jest sygnalizowanie aplikacjom, że muszą usunąć cały kontakt zapisane informacje i wczytać je ponownie za pomocą nowego zapytania.

    Przykładowy kod, który korzysta z tych interfejsów API do sprawdzania zmian w kontaktach, znajdziesz w pliku ApiDemos, który jest dostępny w pakiecie Przykłady kodu SDK.

    Lokalizacja

    Ulepszona obsługa tekstu dwukierunkowego

    Poprzednie wersje Androida obsługują języki i układ od prawej do lewej (RTL). ale czasami nie obsługują tekstu z różnymi kierunkami. Android 4.3 dodaje interfejsy API BidiFormatter, które pomagają prawidłowo formatować tekst z zawartością w przeciwnym kierunku bez zniekształcania jego części.

    Gdy chcesz na przykład utworzyć zdanie ze zmienną ciągu znaków, np. „Czy chodziło Ci o: 15 Bay Street, Laurel, CA?”, zazwyczaj przekazujesz zlokalizowany zasób ciągu znaków i zmienną do String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);

    Jeśli jednak ustawisz język hebrajski, sformatowany ciąg będzie wyglądał tak:

    Tętniąca życiem Ameryka Łacińska, Warszawa, Polska?

    To jest błędne, ponieważ liczba „15” powinna znajdować się po lewej stronie „Bay Street”. Rozwiązaniem jest użycie metody BidiFormatter i jej unicodeWrap(). Na przykład kod powyżej zmieni się w taki:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));

    Domyślnie unicodeWrap() używa heurystyki szacowania kierunkowości opartej na pierwszym silnym sygnale, która może się mylić, jeśli pierwszy sygnał kierunkowy dla tekstu nie odpowiada kierunkowi całego tekstu. W razie potrzeby możesz określić inną heurystykę, przekazując jedną z konstant TextDirectionHeuristicTextDirectionHeuristics do unicodeWrap().

    Uwaga: te nowe interfejsy API są też dostępne w poprzednich wersjach Androida za pomocą biblioteki obsługi Androida, w tym klasy BidiFormatter i powiązanych interfejsów API.

    Usługi ułatwień dostępu

    Obsługa kluczowych zdarzeń

    AccessibilityService może teraz otrzymywać wywołania zwrotne zdarzeń kluczowego wejścia za pomocą metody wywołania zwrotnego onKeyEvent(). Dzięki temu usługa ułatwień dostępu może obsługiwać dane wejściowe urządzeń takich jak klawiatura i przekształcać je w działania specjalne, które wcześniej były możliwe tylko za pomocą sterowania dotykowego lub przycisków kierunkowych urządzenia.

    Zaznacz tekst, a następnie skopiuj/wklej

    Interfejs AccessibilityNodeInfo udostępnia teraz interfejsy API, które umożliwiają AccessibilityService zaznaczanie, wycinanie, kopiowanie i wklejanie tekstu w węźle.

    Aby określić fragment tekstu do wycięcia lub skopiowania, usługa ułatwień dostępu może użyć nowej działanie, ACTION_SET_SELECTION, wynik pozytywny pozycję początkową i końcową zaznaczenia za pomocą funkcji ACTION_ARGUMENT_SELECTION_START_INT i ACTION_ARGUMENT_SELECTION_END_INT. Możesz też zaznaczyć tekst, manipulując kursorem za pomocą istniejącej akcji ACTION_NEXT_AT_MOVEMENT_GRANULARITY (wcześniej służyła ona tylko do przemieszczania kursora) i dodając argument ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN.

    Potem możesz wyciąć lub skopiować treści za pomocą ACTION_CUT, ACTION_COPY, a później wklej w niej przy użyciu ACTION_PASTE

    Uwaga: nowe interfejsy API są również dostępne we wcześniejszych wersjach. z Androidem dzięki działowi pomocy Library, w której znajduje się AccessibilityNodeInfoCompat zajęcia.

    Deklarowanie funkcji ułatwień dostępu

    Od wersji 4.3 Androida usługa ułatwień dostępu musi deklarować możliwości ułatwień dostępu w pliku metadanych, aby móc korzystać z pewnych funkcji ułatwień dostępu. Jeśli nie można w pliku metadanych, funkcja nie będzie operacyjna. Aby zadeklarować funkcji ułatwień dostępu, należy używać atrybutów XML odpowiadających różnym „capability” stałe w zakresie AccessibilityServiceInfo zajęcia.

    Jeśli na przykład usługa nie żąda możliwości flagRequestFilterKeyEvents, nie będzie więc otrzymywać kluczowych zdarzeń.

    Testowanie i debugowanie

    Automatyczne testowanie interfejsu użytkownika

    Nowa klasa UiAutomation udostępnia interfejsy API, które umożliwiają symulowanie działań użytkownika na potrzeby automatyzacji testów. Korzystając z interfejsów API AccessibilityService platformy, możesz sprawdzać zawartość ekranu i wstawiać dowolne zdarzenia związane z klawiaturą oraz dotykiem.

    Aby uzyskać instancję UiAutomation, wywołaj funkcję Instrumentation.getUiAutomation(). Aby to działało, musisz podać opcję -w w ramach polecenia instrument podczas uruchamiania InstrumentationTestCaseadb shell.

    Za pomocą instancji UiAutomation możesz wykonywać dowolne zdarzenia, aby testować aplikację. Wystarczy, że wywołasz funkcję executeAndWaitForEvent(), przekazując jej Runnable do wykonania, okres oczekiwania na wykonanie operacji oraz implementację interfejsu UiAutomation.AccessibilityEventFilter. W ramach implementacji UiAutomation.AccessibilityEventFilter otrzymasz wywołanie, które umożliwia filtrowanie interesujących Cię zdarzeń i określanie, czy dany przypadek testowy zakończył się powodzeniem, czy nie.

    Aby obserwować wszystkie zdarzenia podczas testu, utwórz implementację funkcji UiAutomation.OnAccessibilityEventListener i przekaż ją do funkcji setOnAccessibilityEventListener(). Za każdym razem, gdy wystąpi zdarzenie, wywoływana jest metoda onAccessibilityEvent() interfejsu listenera, która otrzymuje obiekt AccessibilityEvent opisujący to zdarzenie.

    Interfejsy API UiAutomation ujawniają też wiele innych operacji bardzo niskim, aby zachęcić do rozwoju narzędzi do testowania interfejsu, takich jak uiautomator. Przykład: UiAutomation może też:

    • Wstrzyknij zdarzenia wejściowe
    • Zmienianie orientacji ekranu
    • wykonać zrzut ekranu,

    Co najważniejsze dla narzędzi do testowania interfejsu użytkownika, interfejsy API UiAutomation działają w różnych aplikacjach, w przeciwieństwie do interfejsów API Instrumentation.

    Zdarzenia Systrace dla aplikacji

    Android 4.3 dodaje klasę Trace z 2 metodami statycznymi: beginSection() i endSection(), który umożliwia zdefiniowanie bloków kodu, które mają być uwzględniane w raporcie systrace. Tworząc fragmentów kodu możliwego do śledzenia w aplikacji, logi systrace dostarczają dużo bardziej szczegółowych informacji analiza miejsca w aplikacji, gdzie występuje spowolnienie.

    Informacje o korzystaniu z narzędzia Systrace znajdziesz w artykule Analiza wyświetlania i skuteczności reklam w systemie Systrace.

    Bezpieczeństwo

    Kluczowe repozytorium Androida dla kluczy prywatnych aplikacji

    W regionie KeyStore Android oferuje teraz niestandardowego dostawcę zabezpieczeń Java o nazwie Android Key Store, która pozwala generować i zapisywać klucze prywatne, może być widoczna i używana tylko przez Twoją aplikację. Aby wczytać magazyn kluczy Android, przekaż "AndroidKeyStore" do KeyStore.getInstance().

    Aby zarządzać prywatnymi poświadczeniami aplikacji w Android Key Store, wygeneruj nowy klucz za pomocą KeyPairGenerator z użyciem KeyPairGeneratorSpec. 1. uzyskać wystąpienie funkcji KeyPairGenerator, wywołując metodę getInstance(). Następnie wywołaj funkcję initialize(), przekazując jej instancję KeyPairGeneratorSpec, którą możesz uzyskać za pomocą funkcji KeyPairGeneratorSpec.Builder. Na koniec zdobądź KeyPair, dzwoniąc pod numer generateKeyPair().

    Magazyn danych logowania na sprzęcie

    Android obsługuje teraz także pamięć sprzętową urządzenia KeyChain danych logowania, zwiększając bezpieczeństwo, uniemożliwiając wyodrębnianie kluczy. Oznacza to, że raz Klucze znajdują się w obsługiwanym sprzętowo magazynie kluczy (Secure Element, TPM lub TrustZone). Mogą być używane operacji kryptograficznych, ale nie można wyeksportować materiału klucza prywatnego. Nawet jądro systemu operacyjnego nie może uzyskać dostępu do tego materiału klucza. Nie wszystkie urządzenia z systemem Android obsługują sprzęt, można sprawdzić w czasie działania, czy dostępna pamięć sprzętowa jest dostępna, wywołując KeyChain.IsBoundKeyAlgorithm()

    Deklaracje w pliku manifestu

    Deklarowane wymagane funkcje

    W elemencie <uses-feature> są teraz obsługiwane te wartości, dzięki czemu możesz mieć pewność, że Twoja aplikacja jest instalowana tylko na urządzeniach, które zapewniają funkcje wymagane przez aplikację.

    FEATURE_APP_WIDGETS
    Oświadczenie, że Twoja aplikacja udostępnia widżet aplikacji i powinna być instalowana tylko na urządzeniach, które mają ekran główny lub podobną lokalizację, gdzie użytkownicy mogą umieszczać widżety aplikacji. Przykład:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    FEATURE_HOME_SCREEN
    Oświadczenie, że aplikacja działa jak ekran główny i powinna być instalowana tylko na urządzeniach, które obsługują aplikacje ekranu głównego innych firm. Przykład:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    FEATURE_INPUT_METHODS
    Deklaruje, że Twoja aplikacja udostępnia niestandardową metodę wprowadzania (klawiaturę utworzoną za pomocą InputMethodService) i powinna być instalowana tylko na urządzeniach obsługujących metody wprowadzania innych firm. Przykład:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    FEATURE_BLUETOOTH_LE
    Oświadcza, że aplikacja korzysta z interfejsów Bluetooth Low Energy i powinna być instalowana tylko na urządzeniach, które mogą komunikować się z innymi urządzeniami za pomocą Bluetooth Low Energy. Przykład:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />

    Uprawnienia użytkowników

    W elementach <uses-permission> są teraz obsługiwane te wartości, które umożliwiają deklarowanie uprawnień wymaganych przez aplikację do uzyskiwania dostępu do określonych interfejsów API.

    BIND_NOTIFICATION_LISTENER_SERVICE
    Wymagany do korzystania z nowych interfejsów API NotificationListenerService.
    SEND_RESPOND_VIA_MESSAGE
    Wymagane do odbierania informacji o ACTION_RESPOND_VIA_MESSAGEzamierzeniach.

    Szczegółowy widok wszystkich zmian interfejsu API w Androidzie 4.3 znajdziesz w Raport o różnicach w interfejsie API.