Poziom API: 18
Android 4.3 (JELLY_BEAN_MR2
)
to aktualizacja wersji Jelly Bean, która oferuje nowe funkcje dla użytkowników i aplikacji
dla programistów. Ten dokument zawiera wprowadzenie do najważniejszych
nowych interfejsów API.
Jako deweloper aplikacji możesz pobrać obraz systemu Androida 4.3 i platformy SDK z Menedżera SDK jako jak najszybciej. Jeśli nie masz urządzenia z Androidem 4.3, na którym Przetestować aplikację, użyć systemu Android 4.3 aby przetestować aplikację przy użyciu emulatora Androida. Następnie twórz aplikacje na platformie Android 4.3, aby zacząć korzystać do obsługi 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 poziomach interfejsu API znajdziesz w artykule Co to jest interfejs API? Poziom?
Ważne zmiany w działaniu
Jeśli masz już opublikowaną aplikację na Androida, pamiętaj, że może ona na zmiany w Androidzie 4.3.
Jeśli aplikacja używa intencji niejawnych...
Aplikacja może działać nieprawidłowo w ograniczonym środowisku profilu.
Użytkownicy w środowisku profili z ograniczonym dostępem mogą nie
mają wszystkie standardowe aplikacje na Androida. Na przykład profil z ograniczonym dostępem może mieć:
wyłączono przeglądarkę i aparat. Aplikacja nie powinna więc przyjmować żadnych założeń na temat tego, które aplikacje
dostępny, bo jeśli zadzwonisz pod numer startActivity()
bez
sprawdzanie, czy aplikacja może obsługiwać
Intent
,
może spowodować awarię aplikacji w profilu z ograniczonym dostępem.
Gdy używasz intencji niejawnej, zawsze sprawdzaj, czy aplikacja jest dostępna do obsługi intencji, wywołując metodę 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 aplikacja jest zależna od kont...
Aplikacja może działać nieprawidłowo w ograniczonym środowisku profilu.
Użytkownicy w ograniczonym środowisku profili nie mają domyślnie dostępu do kont użytkowników.
Jeśli aplikacja zależy od tego zasobu (Account
), może ulec awarii lub działać
w przypadku użycia jej w profilu ograniczonym.
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 informacje można znaleźć w sekcji poniżej znajdziesz informacje na temat obsługi kont w profilu ograniczonym.
Jeśli Twoja aplikacja używa VideoView...
Na Androidzie 4.3 film może być mniejszy.
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"
we współpracy z: "match_parent"
i potwierdź, że film wyświetla się prawidłowo w
Androida 4.3 oraz starszych wersji.
Profile z ograniczeniami
Na tabletach z Androidem użytkownicy mogą teraz tworzyć profile z ograniczonym dostępem na podstawie głównego użytkownika. Gdy użytkownicy utworzą profil z ograniczonym dostępem, mogą włączyć ograniczenia dotyczące na przykład aplikacji, które mogą dostępnych dla profilu. Nowy zestaw interfejsów API w Androidzie 4.3 umożliwia również ustawień ograniczeń dla tworzonych przez siebie aplikacji. Dzięki nowym interfejsom API możesz na przykład pozwalają użytkownikom kontrolować rodzaj treści dostępnych w aplikacji, gdy działają ograniczone środowisko profilu.
Interfejsem, w którym użytkownicy mogą kontrolować utworzone ograniczenia, zarządza
Ustawienia. 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 tę intencję, aby wysłać zapytanie
wszystkich aplikacji pod kątem dostępnych ograniczeń, a następnie tworzy interfejs tak, aby główny użytkownik
zarządzać ograniczeniami każdego profilu ograniczonego,
W metodzie onReceive()
funkcji
BroadcastReceiver
, musisz utworzyć RestrictionEntry
dla każdego ograniczenia dotyczącego Twojej aplikacji. Każdy element RestrictionEntry
definiuje tytuł, opis i jeden ze
następujące typy danych:
TYPE_BOOLEAN
za ograniczenie, które jest: do wartości prawda lub fałsz.TYPE_CHOICE
za ograniczenie, które: opcje, które wzajemnie się wykluczają (opcje wyboru).TYPE_MULTI_SELECT
za ograniczenie, które: zawiera opcje, które nie wzajemnie się wykluczają (pola wyboru).
Następnie należy umieścić wszystkie obiekty RestrictionEntry
w obiekcie ArrayList
i umieścić go w wyniku odbiornika jako wartość parametru
Dodatkowo 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 pole Bundle
zawierające pary klucz-wartość dla każdego ograniczenia
zdefiniowanych za pomocą obiektów RestrictionEntry
.
Jeśli chcesz podać bardziej szczegółowe ograniczenia, których nie można obsługiwać za pomocą wartości logicznej,
i wartości wielokrotnego wyboru, możesz utworzyć działanie, w którym użytkownik może określić
ograniczeń i zezwolić użytkownikom na otwieranie tej aktywności w ustawieniach ograniczeń. W
odbiornik, dołącz dodatek EXTRA_RESTRICTIONS_INTENT
w wyniku Bundle
. Ten dodatek musi określać atrybut Intent
wskazujący klasę Activity
do uruchomienia (użyj
putParcelable()
, aby przekazać funkcję EXTRA_RESTRICTIONS_INTENT
z intencją).
Gdy główny użytkownik wejdzie w interakcję, aby ustawić ograniczenia niestandardowe,
aktywność musi następnie zwrócić wynik zawierający wartości ograniczeń w dodatkowym miejscu przy użyciu
EXTRA_RESTRICTIONS_LIST
lub EXTRA_RESTRICTIONS_BUNDLE
(w zależności od tego, czy
RestrictionEntry
obiektów lub par 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 u operatora AccountManager
w sieci objętej ograniczeniami
profil, wyświetli się wynik. Ze względu na te ograniczenia masz:
3 opcje:
Aby uzyskać dostęp do konta z profilu ograniczonego, 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. Należy więc zezwolić na tylko pod warunkiem, że informacje wyświetlane przez aplikację nie zawierają informacji umożliwiających identyfikację osoby. informacji poufnych, które są uznawane za poufne. Ustawienia systemowe będą informować że aplikacja udostępnia ich kontom profile z ograniczonym dostępem, więc powinno to być dla niego jasne. ż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 chcesz używać kont, ale nie są one wymagane na potrzeby
, możesz sprawdzić dostępność konta i wyłączyć funkcje, gdy są one niedostępne.
Najpierw sprawdź, czy masz już dostępne konto. Jeśli nie, sprawdź, czy
możesz utworzyć nowe konto, dzwoniąc pod numer getUserRestrictions()
i sprawdzając w wyniku działania dodatkowe DISALLOW_MODIFY_ACCOUNTS
. 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 wszystkie nowe atrybuty w pliku manifestu.
Jeśli zamiast tego ważne jest, aby aplikacja nie była dostępna dla profili z ograniczonym dostępem,
aplikacja korzysta z poufnych danych osobowych na koncie (oraz dlatego, że profile ograniczone
obecnie nie może dodawać nowych kont), dodaj
atrybut android:requiredAccountType
do tagu <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 Bluetooth Low Energy
urządzenia peryferyjne, takie jak pulsometr i krokomierze.
Bluetooth LE to funkcja sprzętowa, która nie jest dostępna na wszystkich
Urządzenia z Androidem – w pliku manifestu należy zadeklarować <uses-feature>
element dla zakresu "android.hardware.bluetooth_le"
:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
Jeśli znasz już klasyczne interfejsy API Bluetootha na Androidzie, zwróć uwagę, że przy użyciu
Interfejsy API Bluetooth LE różnią się pewnymi różnicami. 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 startLeScan()
w BluetoothAdapter
, przekazując je implementację
w interfejsie BluetoothAdapter.LeScanCallback
. Gdy Bluetooth
adapter wykryje urządzenie peryferyjne Bluetooth LE, Twoja implementacja BluetoothAdapter.LeScanCallback
otrzymuje wywołanie do
Metoda onLeScan()
. Ten
zapewnia obiekt BluetoothDevice
reprezentujący
wykryte urządzenie, wartość RSSI urządzenia oraz tablicę bajtów zawierającą
rekord reklamowej w Google.
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: możesz skanować w poszukiwaniu tylko urządzeń Bluetooth LE albo w poszukiwaniu klasycznych urządzeń Bluetooth przy użyciu poprzednich interfejsów API. Nie możesz skanować zarówno dla wersji LE, jak i Classic urządzenia Bluetooth jednocześnie.
Aby połączyć się z urządzeniem peryferyjnym Bluetooth LE, zadzwoń pod connectGatt()
pod
BluetoothDevice
, przesyłając do niego implementację
BluetoothGattCallback
Implementacja usługi BluetoothGattCallback
otrzymuje wywołania zwrotne dotyczące połączenia
stanu urządzenia 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ż włączenia przez aplikację określonych Uprawnienia użytkownika Bluetooth. Więcej informacji znajdziesz w przewodniku po interfejsie API Bluetooth Low Energy.
Tryb Tylko skanowanie Wi-Fi
Android może użyć sieci Wi-Fi, aby określić lokalizację użytkownika, przez skanowanie pobliskich punktów dostępu. Jednak użytkownicy często mają wyłączone Wi-Fi, oszczędzać baterię, przez co dane o lokalizacji będą 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ć o
aby włączyć tryb skanowania Wi-Fi, wywołając startActivity()
z działaniem ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE
.
Konfiguracja Wi-Fi
Nowe interfejsy API WifiEnterpriseConfig
umożliwiają usługom przeznaczonym dla firm
automatyzować konfigurowanie Wi-Fi na urządzeniach zarządzanych.
Szybka odpowiedź na połączenia przychodzące
Od Androida 4.0 funkcja „Szybka odpowiedź” umożliwia użytkownikom reagowanie na przychodzące
natychmiast gdy zadzwonisz, korzystając z natychmiastowego SMS-a, bez konieczności odbierania połączenia ani odblokowywania urządzenia.
Do tej pory te szybkie wiadomości były obsługiwane przez domyślną aplikację do obsługi wiadomości. Teraz dowolna aplikacja
może zadeklarować, że potrafi obsłużyć te wiadomości, tworząc Service
z filtrem intencji dla: ACTION_RESPOND_VIA_MESSAGE
.
Gdy użytkownik odpowie na połączenie przy użyciu szybkiej odpowiedzi, aplikacja Telefon wyśle
intencja ACTION_RESPOND_VIA_MESSAGE
z identyfikatorem URI
opis odbiorcy (rozmówcy) i dodatkowy 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ć tę intencję, musisz zadeklarować uprawnienie SEND_RESPOND_VIA_MESSAGE
.
Multimedia
Ulepszenia MediaExtractor i MediaCodec
Android ułatwia teraz tworzenie własnych kreacji dynamicznych
Odtwarzacze strumieniowe przez HTTP (DASH) zgodne ze standardem ISO/IEC 23009-1
przy użyciu istniejących interfejsów API w MediaCodec
i MediaExtractor
. 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 przekazywanie pojedynczych strumieni 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. Ponadto metodę getPsshInfo()
dodaliśmy do metody
MediaExtractor
, aby uzyskać dostęp do metadanych PSSH treści multimedialnych DASH.
Ta metoda zwraca mapę UUID
obiektów do bajtów, przy czym metoda
UUID
określający schemat kryptograficzny i wskazujące bajty, które są danymi
do tego schematu.
DRM multimediów
Nowa klasa MediaDrm
zapewnia modułowe rozwiązanie z zakresu praw cyfrowych
zarządzania treściami multimedialnymi (DRM) dzięki oddzieleniu problemów DRM od odtwarzania multimediów. Dla:
instancji, to rozdzielenie interfejsów API umożliwia odtwarzanie treści zaszyfrowanych przez Widevine bez konieczności
formatu multimediów Widevine. Rozwiązanie DRM obsługuje również standard DASH Common Encryption,
mogą stosować różne schematy DRM w przypadku treści przesyłanych strumieniowo.
Za pomocą MediaDrm
możesz uzyskiwać nieprzejrzyste wiadomości dotyczące żądania klucza i przetwarzać je
wiadomości z serwera w odpowiedzi na kluczowe wiadomości dotyczące pozyskiwania i udostępniania licencji. Twoja aplikacja jest
odpowiada za obsługę komunikacji sieciowej z serwerami; Klasa MediaDrm
umożliwia jedynie generowanie i przetwarzanie wiadomości.
Interfejsy API MediaDrm
są przeznaczone do używania w połączeniu z protokołami
Interfejsy API MediaCodec
wprowadzone w Androidzie 4.1 (poziom 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. Pozwala to na przykład zakodować dane wejściowe
z istniejącego pliku wideo lub z użyciem klatek wygenerowanych przez OpenGL ES.
Aby użyć wejścia Surface
jako danych wejściowych kodera, najpierw wywołaj configure()
dla swojego MediaCodec
.
Następnie wywołaj createInputSurface()
, aby otrzymać Surface
, na którym możesz przesyłać multimedia.
Na przykład można użyć podanego elementu Surface
jako okna dla trybu OpenGL
kontekst, przekazując go do narzędzia eglCreateWindowSurface()
. Następnie podczas renderowania powierzchni wywołaj funkcję eglSwapBuffers()
, aby przekazać ramkę do 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
Muxing multimediów
Nowa klasa MediaMuxer
umożliwia multipleksowanie między 1 strumieniem audio
i 1 strumień 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 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
. Aby zwiększyć skuteczność, możesz też użyć parametru MediaMuxer
w połączeniu z atrybutem MediaExtractor
edycji multimediów bez konieczności kodowania i dekodowania.
Postęp odtwarzania i przewijanie dla RemoteControlClient
W Androidzie 4.0 (poziom interfejsu API 14) dodano RemoteControlClient
do
włącz elementy sterujące odtwarzaniem multimediów dostępne w klientach pilota, takie jak elementy sterujące dostępne na
ekranu 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 o nową pozycję wywołaj
setPlaybackState()
, aby wskazać nowy stan, pozycję i prędkość 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. Najważniejsze nowe funkcje dostępne w OpenGL ES 3.0 obejmuje:
- Zaawansowane efekty wizualne
- Wysoka jakość kompresji tekstur ETC2/EAC jako funkcja standardowa
- 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ą parametru
<uses-feature>
i atrybut 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 korzystaniu z platformy OpenGL ES, w tym o sprawdzaniu obsługiwanych urządzeń Wersja OpenGL ES w czasie działania zawiera przewodnik po interfejsie OpenGL ES API.
Mipmapping dla elementów rysowanych
Użycie mimmapy jako źródła bitmapy lub elementu rysowania to prosty sposób na zapewnienie wysokiej jakości i różnych skalach obrazu, co może być przydatne, jeśli spodziewasz się, który ma być skalowany podczas animacji.
W Androidzie 4.2 (poziom interfejsu API 17) dodaliśmy obsługę map mipmaps w: Bitmap
klasa – Android zamienia obrazy mip na urządzeniu Bitmap
, gdy
podano źródło mipmap i włączono 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ę co widok hosta (widok, z którego został utworzony),
Dzięki temu można dodawać treści widoczne na ekranie hosta, ale nie rozszerzające
granic tego widoku hosta.
Używanie interfejsu ViewOverlay
jest szczególnie przydatne, gdy chcesz tworzyć
animacje, takie jak przesuwanie widoku poza kontener lub przenoszenie elementów na ekranie.
bez wpływu na hierarchię widoków. 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 funkcję getOverlay()
w przypadku widoku układu, np. RelativeLayout
,
zwrócony obiekt to ViewGroupOverlay
.
Klasa ViewGroupOverlay
jest podklasą
z ViewOverlay
, która również umożliwia dodanie View
obiektów po wywołaniu funkcji add(View)
.
Uwaga: wszystkie elementy rysowane i widoki dodane do nakładki. mają charakter czysto wizualny. Nie mogą odbierać zdarzeń skupienia ani danych wejściowych.
Na przykład ten kod animuje widok przesuwający się w prawo przez umieszczenie w nakładce widoku nadrzędnego, a następnie uruchomić w nim 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();
Optyczny układ granic
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 na ilustracjach 1 i 2 widać ten sam układ, ale wersje na ilustracji 1 z użyciem granic przycięcia (działanie domyślne), a rysunek 2 używa granic optycznych. Ponieważ Obrazy w dziewięciu łatkach użytych na przycisku i w ramce na zdjęcia mają dopełnienie na krawędziach. nie są wyrównane względem siebie lub tekstu przy korzystaniu z granic 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.
Aby wyrównać widoki na podstawie ich granic optycznych, ustaw atrybut android:layoutMode
na "opticalBounds"
w jednym z układów nadrzędnych. Na przykład:
<LinearLayout android:layoutMode="opticalBounds" ... >
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.
Po włączeniu granic optycznych dla elementu ViewGroup
w układzie
widoki podrzędne dziedziczą tryb układu granic optycznych, chyba że zastąpisz go dla grupy
Ustawianie wartości android:layoutMode
na "clipBounds"
. Wszystkie elementy układu uwzględniają też atrybut
ich granic optycznych, dostosowując własne granice w oparciu o
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 za pomocą podklasy View
, ViewGroup
lub dowolnej z jej podklas, Twój widok odziedziczy te powiązane zachowania optyczne.
Uwaga: wszystkie widżety obsługiwane przez motyw Holo zostały zaktualizowane
z granicami optycznymi, w tym Button
, Spinner
,
EditText
i inni. 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 jest implementacją klasy TypeEvaluator
, którą można przekazać do klasy ValueAnimator.setEvaluator()
.
Detektor podłączania i zaznaczania okna
Wcześniej, aby nasłuchiwać, kiedy widok został dołączony/odłączony od okna lub
po zmianie fokusu trzeba zastąpić klasę View
wartością
zaimplementuj odpowiednio onAttachedToWindow()
i onDetachedFromWindow()
lub onWindowFocusChanged()
.
Aby otrzymywać zdarzenia podłączania i odłączania, możesz zaimplementować ViewTreeObserver.OnWindowAttachListener
i ustawić go w widoku za pomocą parametru
addOnWindowAttachListener()
Aby otrzymywać zdarzenia skupienia, możesz zaimplementować ViewTreeObserver.OnWindowFocusChangeListener
i ustawić je dla widoku za pomocą
addOnWindowFocusChangeListener()
Obsługa nadmiarowego skanowania obrazu
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
<activity>
tag screenOrientation
Atrybut obsługuje teraz dodatkowe wartości, aby uwzględniać preferencje użytkownika dotyczące autorotacji:
"userLandscape"
- Działa tak samo jak
"sensorLandscape"
, chyba że użytkownik wyłączy autoobracanie zablokuje się on w normalnej orientacji poziomej i nie odwróci. "userPortrait"
- Działa tak samo jak
"sensorPortrait"
, ale jeśli użytkownik wyłączy autoobracanie, wtedy blokuje się w normalnej orientacji pionowej i nie odwróci. "fullUser"
- Działa tak samo jak
"fullSensor"
i umożliwia obracanie we wszystkich 4 kierunkach, z wyjątkiem jeśli użytkownik wyłączy autoobracanie, zostanie ono zablokowane w orientacji preferowanej przez użytkownika.
Dodatkowo możesz teraz zadeklarować "locked"
, aby zablokować orientację aplikacji
w bieżącej orientacji ekranu.
Animacje obrotu
Nowe pole rotationAnimation
w:
WindowManager
umożliwia wybranie jednej z trzech animacji,
ma być używane przy zmianie orientacji 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łączyć za pomocą motywów takich jak Theme.Holo.NoActionBar.Fullscreen
.
Oto jak można na przykład włączyć przenikanie animacja:
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
wartość TYPE_GAME_ROTATION_VECTOR
nie jest określana na podstawie kierunku północnego magnetycznego.
Nowe czujniki TYPE_GYROSCOPE_UNCALIBRATED
i TYPE_MAGNETIC_FIELD_UNCALIBRATED
dostarczają nieprzetworzone dane z czujników bez
do szacowania tendencyjności. Oznacza to, że obecne właściwości TYPE_GYROSCOPE
i TYPE_MAGNETIC_FIELD
czujniki dostarczają dane z czujników, które uwzględniają szacunkowe odchylenie wynikające z żyroskopu i żelaza
na urządzeniu. Natomiast nowa wersja „nieskalibrowana” dla różnych wersji tych czujników
nieprzetworzone dane z czujnika i oddzielnie oferują szacowane wartości odchylenia. Czujniki te umożliwiają:
przeprowadzić własną kalibrację danych czujnika, ulepszając szacowane odchylenie o
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
) stanowi skuteczny sposób uzyskania jednego typu Cursor
zawierającego wszystkie adresy e-mail i numery telefonów należące do wszystkich kontaktów pasujących do określonego zapytania.
Zapytanie o delta 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 Twoja aplikacja mogła otrzymywać powiadomienia, gdy coś się zmieni w danych kontaktów, ale nie wiadomo było, co dokładnie się zmieniło, i trzeba było pobrać wszystkie kontakty, a następnie je przejrzeć, aby wykryć zmianę.
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ć usunięte kontakty, nowa tabela ContactsContract.DeletedContacts
zawiera dziennik usuniętych kontaktów (ale każdy usunięty kontakt jest w niej przechowywany przez ograniczony czas). Podobnie jak w przypadku funkcji 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 dotyczącego 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 korzystający z tych interfejsów API do sprawdzania zmian w kontaktach znajdziesz w ApiDemos przykładową aplikację można pobrać przykładowe pakiety 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. Z tego powodu Android 4.3 dodaje interfejsy API BidiFormatter
, które pomagają poprawnie sformatować tekst w przeciwnym kierunku
treści bez usuwania ich zniekształcenia.
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 językiem jest hebrajski, sformatowany ciąg znaków będzie wyglądać w następujący sposób:
Tętniąca życiem Ameryka Łacińska, Warszawa, Polska?
To nie jest poprawna odpowiedź, bo „15” powinien znajdować się po lewej stronie
„Bay Street”. Rozwiązaniem jest użycie metody BidiFormatter
i jej unicodeWrap()
. Powyższy kod wygląda na przykład tak:
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
heurystycznego szacowania kierunków o pierwszej silnej wartości, gdzie błąd może wystąpić, jeśli pierwszy
Kierunek tekstu nie odzwierciedla właściwego kierunku całej treści.
W razie potrzeby możesz określić inną heurystykę, przekazując jedną ze stałych TextDirectionHeuristic
z TextDirectionHeuristics
do: unicodeWrap()
.
Uwaga: nowe interfejsy API są również dostępne we wcześniejszych wersjach.
z Androidem dzięki działowi pomocy
Library z klasą BidiFormatter
i powiązanymi interfejsami API.
Usługi ułatwień dostępu
Obsługa kluczowych zdarzeń
AccessibilityService
może teraz odebrać połączenie zwrotne za numer
za pomocą metody wywołania zwrotnego onKeyEvent()
. Dzięki temu usługa ułatwień dostępu będzie mogła obsługiwać dane wejściowe
urządzeń wejściowych, np. klawiatury, i przekształcania tych zdarzeń na specjalne akcje,
wcześniej było to możliwe tylko przy użyciu wprowadzania dotykowego lub pada kierunkowego urządzenia.
Zaznacz tekst, a następnie skopiuj/wklej
AccessibilityNodeInfo
udostępnia teraz interfejsy API, które umożliwiają
AccessibilityService
, aby zaznaczyć, wyciąć, skopiować i wkleić
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, modyfikując pozycję kursora za pomocą
działanie, ACTION_NEXT_AT_MOVEMENT_GRANULARITY
(wcześniej tylko do przesuwania pozycji kursora) i dodanie argumentu 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
Począwszy od Androida 4.3 usługa ułatwień dostępu musi zadeklarować funkcje ułatwień dostępu.
w pliku metadanych, aby korzystać z pewnych 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
Zautomatyzowane testowanie UI
Nowa klasa UiAutomation
udostępnia interfejsy API umożliwiające symulację działań użytkowników
na potrzeby automatyzacji testów. Przy użyciu interfejsów API platformy AccessibilityService
UiAutomation
Interfejsy API umożliwiają analizowanie zawartości ekranu oraz wstrzykiwanie dowolnych zdarzeń związanych z klawiaturą i dotykiem.
Aby pobrać instancję UiAutomation
, wywołaj Instrumentation.getUiAutomation()
. W zamówieniu
aby to zadziałało, musisz podać opcję -w
za pomocą polecenia instrument
przy uruchamianiu InstrumentationTestCase
z adb shell
.
Dzięki instancji UiAutomation
możesz uruchamiać dowolne zdarzenia do testowania
aplikację, wywołując metodę executeAndWaitForEvent()
, przekazując jej Runnable
do wykonania, limit czasu
okresu operacji oraz implementacja interfejsu UiAutomation.AccessibilityEventFilter
. To w ramach implementacji UiAutomation.AccessibilityEventFilter
otrzymasz połączenie
który pozwala filtrować interesujące Cię zdarzenia i określać skuteczność
danego przypadku testowego.
Aby obserwować wszystkie zdarzenia podczas testu, utwórz implementację UiAutomation.OnAccessibilityEventListener
i przekaż ją do setOnAccessibilityEventListener()
.
Interfejs odbiornika odbiera wywołanie onAccessibilityEvent()
po każdym wystąpieniu zdarzenia, odebranie obiektu AccessibilityEvent
opisujący wydarzenie.
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ż:
- Wstrzykiwanie zdarzeń wejściowych
- Zmienianie orientacji ekranu
- wykonać zrzut ekranu,
A przede wszystkim w przypadku narzędzi do testowania interfejsu API
interfejsy API UiAutomation
działają
między aplikacjami, w przeciwieństwie do tych w 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
Sklep z kluczami Androida do przechowywania 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 danymi logowania do aplikacji w Android Key Store, wygeneruj nowy klucz:
KeyPairGenerator
z: KeyPairGeneratorSpec
. 1.
uzyskać wystąpienie funkcji KeyPairGenerator
, wywołując metodę getInstance()
. Następnie zadzwoń
initialize()
, przekazując je do instancji
KeyPairGeneratorSpec
, którą możesz uzyskać za pomocą
KeyPairGeneratorSpec.Builder
Na koniec zdobądź KeyPair
, dzwoniąc pod numer generateKeyPair()
.
Magazyn danych logowania do sprzętu
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
Poniższe wartości są teraz obsługiwane w <uses-feature>
Dzięki temu masz pewność, że aplikacja jest zainstalowana tylko na urządzeniach, które obsługują funkcje
do aplikacji.
FEATURE_APP_WIDGETS
- Deklaruje, że Twoja aplikacja udostępnia widżet i powinna być instalowana tylko na urządzeniach, które
zawierać ekran główny lub podobne miejsce, w którym użytkownicy mogą umieszczać widżety aplikacji.
Przykład:
<uses-feature android:name="android.software.app_widgets" android:required="true" />
FEATURE_HOME_SCREEN
- Deklaruje, że Twoja aplikacja działa jak zamiennik ekranu głównego i powinna być zainstalowana tylko na
obsługujące aplikacje innych firm dostępne na ekranie głównym.
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ę zbudowaną przy użyciu
InputMethodService
) i powinna być instalowana tylko na urządzeniach, które i obsługują metody wprowadzania innych firm. Przykład:<uses-feature android:name="android.software.input_methods" android:required="true" />
FEATURE_BLUETOOTH_LE
- Deklaruje, że Twoja aplikacja używa interfejsów API Bluetooth Low Energy i powinna być instalowana tylko na urządzeniach
które mogą komunikować się z innymi urządzeniami przez Bluetooth Low Energy.
Przykład:
<uses-feature android:name="android.software.bluetooth_le" android:required="true" />
Uprawnienia użytkownika
Poniższe wartości są teraz obsługiwane w <uses-permission>
zadeklarować
uprawnień wymaganych przez aplikację do uzyskania dostępu do określonych interfejsów API.
BIND_NOTIFICATION_LISTENER_SERVICE
- Wymagane do korzystania z nowych interfejsów API
NotificationListenerService
. SEND_RESPOND_VIA_MESSAGE
- Wymagane, aby otrzymać
ACTION_RESPOND_VIA_MESSAGE
intencji.
Szczegółowy widok wszystkich zmian interfejsu API w Androidzie 4.3 znajdziesz Raport o różnicach w interfejsie API.