Oprócz nowych funkcji i możliwości Android 6.0 (poziom interfejsu API 23) wprowadza szereg zmian w systemie oraz w sposobie działania interfejsów API. W tym dokumencie opisujemy najważniejsze zmiany, które musisz zrozumieć i uwzględnić w swoich aplikacjach.
Jeśli masz już opublikowaną aplikację na Androida, pamiętaj, że te zmiany na platformie wpłyną na nią.
Uprawnienia czasu działania
W tej wersji wprowadziliśmy nowy model uprawnień, dzięki któremu użytkownicy mogą teraz bezpośrednio zarządzać uprawnieniami aplikacji w czasie działania. Ten model zapewnia użytkownikom lepszy wgląd w uprawnienia i kontrolę nad nimi, a deweloperzy aplikacji upraszczają proces instalacji i automatycznej aktualizacji. Użytkownicy mogą przyznawać i odbierać uprawnienia dla zainstalowanych aplikacji osobno.
W przypadku aplikacji kierowanych na Androida 6.0 (poziom interfejsu API 23) lub nowszego sprawdź, czy uprawnienia są odpowiednie, i poproś o ich uprawnienia w czasie działania. Aby sprawdzić, czy aplikacja otrzymała to uprawnienie, wywołaj nową metodę checkSelfPermission()
. Aby poprosić o uprawnienia, wywołaj nową metodę requestPermissions()
. Nawet jeśli Twoja aplikacja nie jest kierowana na Androida 6.0 (poziom interfejsu API 23), przetestuj ją z wykorzystaniem nowego modelu uprawnień.
Szczegółowe informacje o obsłudze nowego modelu uprawnień w aplikacji znajdziesz w sekcji Korzystanie z uprawnień systemowych. Wskazówki dotyczące oceny wpływu zmiany na aplikację znajdziesz w artykule Uwagi na temat korzystania z uprawnień.
Uśpienie i czuwanie aplikacji
Ta wersja wprowadza nowe optymalizacje pozwalające oszczędzać energię w przypadku nieaktywnych urządzeń i aplikacji. Te funkcje mają wpływ na wszystkie aplikacje, więc pamiętaj, aby je przetestować w nowych trybach.
- Uśpienie: jeśli użytkownik odłączy urządzenie i pozostawi je w tym samym stanie z wyłączonym ekranem, a urządzenie zostanie na jakiś czas wyłączone, przejdzie w tryb uśpienia, w którym spróbuje utrzymać system w stanie uśpienia. W tym trybie urządzenia okresowo wznawiają normalne działanie na krótki czas, aby umożliwić synchronizację aplikacji i wykonywanie oczekujących operacji.
- Czuwanie aplikacji: umożliwia systemowi ustalenie, czy aplikacja jest nieaktywna, gdy użytkownik jej nie używa. System określa to, gdy użytkownik nie korzysta z aplikacji przez określony czas. Jeśli urządzenie jest odłączone, system wyłącza dostęp do sieci oraz zawiesza synchronizacje i zadania w przypadku aplikacji, które uzna za nieaktywne.
Aby dowiedzieć się więcej o tych zmianach, które pozwalają oszczędzać energię, przeczytaj artykuł o optymalizacji funkcji Uśpienie i Czuwanie aplikacji.
Usunięcie klienta HTTP Apache
Android 6.0 wyłącza obsługę klienta HTTP Apache. Jeśli Twoja aplikacja używa tego klienta i jest kierowana na Androida 2.3 (poziom interfejsu API 9) lub nowszego, użyj zamiast niego klasy HttpURLConnection
. Ten interfejs API jest wydajniejszy, ponieważ zmniejsza wykorzystanie sieci dzięki przejrzystej kompresji i buforowaniu odpowiedzi, a także minimalizuje zużycie energii. Aby nadal korzystać z interfejsów Apache HTTP API, musisz najpierw zadeklarować w pliku build.gradle
tę zależność czasu kompilacji:
android { useLibrary 'org.apache.http.legacy' }
Nudny SSL
Android wycofuje OpenSSL z biblioteki BoringSSL. Jeśli w aplikacji używasz pakietu NDK na Androida, nie twórz linków do bibliotek kryptograficznych, które nie są częścią interfejsu NDK API, takich jak libcrypto.so
i libssl.so
. Biblioteki te nie są publicznymi interfejsami API i mogą się zmieniać lub działać bez powiadomienia w poszczególnych wersjach i urządzeniach.
Oprócz tego narażasz się na luki w zabezpieczeniach. Zamiast tego zmodyfikuj kod natywny tak, aby wywoływał interfejsy API kryptografii Java za pomocą JNI lub aby utworzyć statyczny link do wybranej biblioteki kryptograficznej.
Dostęp do identyfikatora sprzętowego
Aby zapewnić użytkownikom lepszą ochronę danych, od tej wersji Android usuwa programowy dostęp do lokalnego identyfikatora sprzętowego urządzenia w przypadku aplikacji, które korzystają z interfejsów API Wi-Fi i Bluetooth. Metody WifiInfo.getMacAddress()
i BluetoothAdapter.getAddress()
zwracają teraz stałą wartość 02:00:00:00:00:00
.
Aby przez Bluetooth i skanowanie Wi-Fi uzyskać dostęp do identyfikatorów sprzętowych urządzeń zewnętrznych w pobliżu, aplikacja musi mieć teraz uprawnienia ACCESS_FINE_LOCATION
lub ACCESS_COARSE_LOCATION
:
Uwaga: gdy urządzenie z Androidem 6.0 (poziom interfejsu API 23) inicjuje skanowanie Wi-Fi lub Bluetooth w tle, operacja jest widoczna dla urządzeń zewnętrznych jako pochodząca z randomizowanego adresu MAC.
Powiadomienia
W tej wersji usunięto metodę Notification.setLatestEventInfo()
. Do tworzenia powiadomień używaj zamiast tego klasy Notification.Builder
. Aby wielokrotnie aktualizować powiadomienie, użyj ponownie wystąpienia Notification.Builder
. Wywołaj metodę build()
, aby zaktualizować instancje Notification
.
Polecenie adb shell dumpsys notification
nie wyświetla już tekstu powiadomienia.
Zamiast tego użyj polecenia adb shell dumpsys notification --noredact
, aby wydrukować tekst w obiekcie powiadomienia.
Zmiany w usłudze AudioManager
Bezpośrednie ustawianie głośności lub wyciszanie konkretnych strumieni za pomocą klasy AudioManager
nie jest już obsługiwane. Metoda setStreamSolo()
została wycofana. Zamiast niej należy wywołać metodę requestAudioFocus()
. Podobnie jest wycofana metoda setStreamMute()
. Wywołaj metodę adjustStreamVolume()
i przekaż wartość kierunku ADJUST_MUTE
lub ADJUST_UNMUTE
.
Zaznaczanie tekstu
![Ekran z nowymi funkcjami zaznaczania tekstu na pływającym pasku narzędzi](https://developer.android.com/static/images/android-6.0/text-selection.gif?authuser=7&hl=pl)
Gdy użytkownicy zaznaczą tekst w aplikacji, na pływającym pasku narzędzi możesz teraz wyświetlać działania wyboru tekstu, takie jak Wytnij, Kopiuj i Wklej. Implementacja interakcji z użytkownikiem jest podobna do tej w przypadku paska działań kontekstowych, co opisano w sekcji Włączanie trybu działań kontekstowych w poszczególnych widokach danych.
Aby zaimplementować pływający pasek narzędzi do zaznaczania tekstu, wprowadź te zmiany w istniejących aplikacjach:
- W obiekcie
View
lubActivity
zmień wywołaniaActionMode
zstartActionMode(Callback)
nastartActionMode(Callback, ActionMode.TYPE_FLOATING)
. - Wykorzystaj dotychczasową implementację funkcji
ActionMode.Callback
i rozszerz ją naActionMode.Callback2
. - Zastąp metodę
onGetContentRect()
, aby podać współrzędne obiektuRect
treści (np. prostokąta wyboru tekstu) w widoku. - Jeśli położenie prostokąta jest nieprawidłowe i tylko ten element jest unieważniony, wywołaj metodę
invalidateContentRect()
.
Jeśli korzystasz z
Biblioteki pomocy Androida w wersji 22.2, pamiętaj, że pływające paski narzędzi nie są zgodne wstecznie i domyślnie przejmują kontrolę nad obiektami ActionMode
. Zapobiega to wyświetlaniu pływających pasków narzędzi. Aby włączyć obsługę ActionMode
w elemencie AppCompatActivity
, wywołaj metodę getDelegate()
, a następnie wywołaj metodę setHandleNativeActionModesEnabled()
w zwróconym obiekcie AppCompatDelegate
i ustaw parametr wejściowy na false
. To wywołanie zwraca do platformy kontrolę nad obiektami ActionMode
. Na urządzeniach z Androidem 6.0 (poziom interfejsu API 23), który umożliwia obsługę trybów ActionBar
lub pływającego paska narzędzi, a na urządzeniach z Androidem 5.1 (poziom interfejsu API 22) lub niższym obsługiwane są tylko tryby ActionBar
.
Zmiany zakładek w przeglądarce
W tej wersji wycofujemy obsługę zakładek globalnych. Metody android.provider.Browser.getAllBookmarks()
i android.provider.Browser.saveBookmark()
zostały usunięte. Analogicznie zostają usunięte uprawnienia READ_HISTORY_BOOKMARKS
i WRITE_HISTORY_BOOKMARKS
. Jeśli Twoja aplikacja jest kierowana na Androida 6.0 (poziom interfejsu API 23) lub nowszego, nie korzystaj z zakładek od dostawcy globalnego ani nie używaj uprawnień do zakładek. Zamiast tego aplikacja powinna
przechowywać dane zakładek.
Zmiany dotyczące magazynu kluczy Androida
W tej wersji dostawca magazynu kluczy Android nie obsługuje już DSA. ECDSA jest nadal obsługiwane.
Klucze, które nie wymagają szyfrowania w spoczynku, nie będą już usuwane po wyłączeniu lub zresetowaniu bezpiecznego ekranu blokady (na przykład przez użytkownika lub administratora urządzenia). Klucze, które wymagają szyfrowania w spoczynku, zostaną usunięte podczas tych zdarzeń.
Zmiany dotyczące Wi-Fi i sieci
W tej wersji wprowadziliśmy opisane poniżej zmiany w działaniu interfejsów API Wi-Fi i sieciowych.
- Twoje aplikacje mogą teraz zmieniać stan obiektów
WifiConfiguration
tylko wtedy, gdy te obiekty zostały utworzone przez Ciebie. Nie możesz modyfikować ani usuwaćWifiConfiguration
obiektów utworzonych przez użytkownika lub inne aplikacje. -
Wcześniej, gdy aplikacja wymuszała na urządzeniu połączenie z konkretną siecią Wi-Fi przy użyciu
enableNetwork()
w ustawieniudisableAllOthers=true
, urządzenie rozłączało się z innymi sieciami, np. komórkową transmisją danych. W tej wersji urządzenie nie rozłącza się już z innymi sieciami. JeślitargetSdkVersion
w Twojej aplikacji to“20”
lub mniej, jest ona przypięta do wybranej sieci Wi-Fi. JeślitargetSdkVersion
Twojej aplikacji to“21”
lub więcej, użyj wielosieciowych interfejsów API (takich jakopenConnection()
,bindSocket()
oraz nowej metodybindProcessToNetwork()
), aby mieć pewność, że ruch sieciowy jest wysyłany do wybranej sieci.
Zmiany w usłudze aparatów fotograficznych
W tej wersji model uzyskiwania dostępu do udostępnionych zasobów w usłudze aparatu został zmieniony z poprzedniego modelu dostępu „pierwszy, lepszy” na model, w którym faworyzowane są procesy o wysokim priorytecie. Zmiany w działaniu usługi obejmują:
- Dostęp do zasobów podsystemu kamery, w tym do jego otwierania i konfigurowania, jest przyznawany na podstawie „priorytetu” procesu aplikacji klienckiej. Procesy aplikacji, w których występują działania widoczne dla użytkownika lub działania na pierwszym planie, mają zwykle wyższy priorytet, co sprawia, że pozyskiwanie zasobów kamery jest bardziej niezawodne.
- Aktywne klienty aparatu dla aplikacji o niższym priorytecie mogą zostać „opróżnione”, gdy aplikacja o wyższym priorytecie spróbuje użyć kamery. W wycofanym interfejsie API
Camera
powoduje to wywołanie metodyonError()
w przypadku wykluczonego klienta. W interfejsie APICamera2
wywołuje to wywołanieonDisconnected()
dla wykluczonego klienta. - Na urządzeniach z odpowiednim aparatem osobne procesy aplikacji mogą się niezależnie otwierać i korzystać z osobnych kamer jednocześnie. Jednak przypadki użycia obejmujące wiele procesów, w przypadku których jednoczesne korzystanie z nich powoduje znaczne pogorszenie wydajności lub możliwości dowolnych otwartych aparatów, są teraz wykrywane i niedozwolone przez usługę aparatu. Ta zmiana może spowodować „usunięcia” klientów o niższym priorytecie, nawet jeśli żadna inna aplikacja nie próbuje bezpośrednio uzyskać dostępu do tego samego urządzenia z kamerą.
- Zmiana bieżącego użytkownika spowoduje trwałe usunięcie aktywnych klientów aparatu w aplikacjach należących do poprzedniego użytkownika. Dostęp do kamery jest ograniczony do profili użytkowników, których właścicielem jest obecny użytkownik urządzenia. W praktyce oznacza to, że na przykład konto gościa nie może zatrzymać uruchomionych procesów korzystających z podsystemu kamer, gdy użytkownik przełączy się na inne konto.
Środowisko wykonawcze
Teraz środowisko wykonawcze ART poprawnie implementuje reguły dostępu dla metody newInstance()
. Ta zmiana rozwiązuje problem związany z nieprawidłowym sprawdzaniem reguł dostępu w poprzednich wersjach.
Jeśli Twoja aplikacja używa metody newInstance()
i chcesz zastąpić sprawdzanie dostępu, wywołaj metodę setAccessible()
z parametrem wejściowym ustawionym na true
. Jeśli Twoja aplikacja korzysta z biblioteki appcompat w wersji 7 lub biblioteki Recyclerview w wersji 7, musisz ją zaktualizować, aby używała najnowszych wersji tych bibliotek. W przeciwnym razie sprawdź, czy wszystkie niestandardowe klasy, do których odwołuje się plik XML, zostały zaktualizowane, tak aby ich konstruktory klas były dostępne.
Ta wersja aktualizuje działanie dynamicznego tagu łączącego. Tag łączący dynamiczne rozumie teraz różnicę między elementem soname
biblioteki a jej ścieżką (
błąd publiczny 6670), a wyszukiwanie za pomocą soname
zostało wdrożone. Aplikacje, które wcześniej działały, z błędnymi wpisami DT_NEEDED
(zwykle są to ścieżki bezwzględne w systemie plików komputera kompilacji), mogą przestać działać.
Flaga dlopen(3) RTLD_LOCAL
jest teraz prawidłowo zaimplementowana. Pamiętaj, że wartością domyślną jest RTLD_LOCAL
, więc wpłynie to na wywołania dlopen(3)
, które nie używają bezpośrednio funkcji RTLD_LOCAL
(chyba że aplikacja wyraźnie używała funkcji RTLD_GLOBAL
). W przypadku RTLD_LOCAL
symbole nie są udostępniane biblioteczkom załadowanym przez późniejsze wywołania dlopen(3)
(zamiast się odwoływać do wpisów DT_NEEDED
).
Jeśli we wcześniejszych wersjach Androida aplikacja zażądała wczytania biblioteki udostępnionej z przeniesieniem tekstu, system wyświetlił ostrzeżenie, ale wciąż umożliwił wczytanie biblioteki.
Począwszy od tej wersji system będzie odrzucać tę bibliotekę, jeśli docelowa wersja pakietu SDK aplikacji to 23 lub nowsza. Aby ułatwić wykrywanie, czy nie udało się wczytać biblioteki, aplikacja powinna zarejestrować błąd dlopen(3)
i podać tekst opisu problemu zwracany przez wywołanie dlerror(3)
. Więcej informacji o obsłudze relokacji tekstu znajdziesz w tym przewodniku.
Weryfikacja pakietu APK
Platforma przeprowadza teraz bardziej rygorystyczną weryfikację plików APK. Uszkodzony plik APK jest uznawany za uszkodzony, jeśli zadeklarowano w pliku manifestu plik, ale nie ma go w samym pakiecie APK. Jeśli jakakolwiek treść zostanie usunięta, musisz ponownie podpisać plik APK.
Połączenie USB
Połączenia urządzenia przez port USB są teraz domyślnie ustawione w trybie tylko do ładowania. Aby uzyskać dostęp do urządzenia i jego zawartości przez połączenie USB, użytkownicy muszą jawnie przyznać uprawnienia do takich interakcji. Jeśli aplikacja obsługuje interakcje użytkowników z urządzeniem przez port USB, pamiętaj, że interakcja ta musi być wyraźnie włączona.
Zmiany w Android for Work
W tej wersji wprowadziliśmy te zmiany w działaniu Android for Work:
- Kontakty służbowe w kontekście osobistym. Rejestr połączeń Google wyświetla teraz kontakty służbowe, gdy użytkownik przegląda wcześniejsze połączenia.
Ustawienie
setCrossProfileCallerIdDisabled()
natrue
ukrywa kontakty z profilu służbowego w rejestrze połączeń Telefonu Google. Kontakty służbowe mogą być wyświetlane na urządzeniach przez Bluetooth wraz z kontaktami osobistymi tylko wtedy, gdy ustawiszsetBluetoothContactSharingDisabled()
nafalse
. Domyślnie ustawiona jest wartośćtrue
. - Usunięcie konfiguracji Wi-Fi: konfiguracje Wi-Fi dodane przez właściciela profilu (np. przez wywołania metody
addNetwork()
) są teraz usuwane, jeśli profil służbowy zostanie usunięty. - Blokada konfiguracji Wi-Fi: użytkownik nie może zmienić ani usunąć konfiguracji Wi-Fi utworzonej przez aktywnego właściciela urządzenia, jeśli wartość
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
ma wartość inną niż 0. Użytkownik nadal będzie mógł tworzyć i modyfikować własne konfiguracje Wi-Fi. Aktywne właściciele urządzeń mogą edytować i usuwać dowolne konfiguracje Wi-Fi, również te, które nie zostały przez nich utworzone. - Pobieranie kontrolera zasad dotyczących urządzeń przy użyciu dodawania konta Google: gdy konto Google, które wymaga zarządzania za pomocą aplikacji kontrolera zasad dotyczących urządzeń (DPC), zostanie dodane do urządzenia poza kontekstem zarządzanym, podczas dodawania konta użytkownik będzie musiał zainstalować odpowiednią platformę WPC. Dotyczy to też kont dodanych w kreatorze początkowej konfiguracji urządzenia w sekcji Ustawienia > Konta.
- Zmiany dotyczące określonych zachowań interfejsu API
DevicePolicyManager
:- Wywołanie metody
setCameraDisabled()
wpływa tylko na kamerę u użytkownika, który ją wywoła. Wywołanie jej z profilu zarządzanego nie ma wpływu na aplikacje aparatu uruchomione przez głównego użytkownika. - Metoda
setKeyguardDisabledFeatures()
jest teraz dostępna zarówno dla właścicieli profili, jak i właścicieli urządzeń. - Właściciel profilu może ustawić następujące ograniczenia blokady klawiszy:
KEYGUARD_DISABLE_TRUST_AGENTS
iKEYGUARD_DISABLE_FINGERPRINT
, które mają wpływ na ustawienia blokady klucza dla rodzica użytkownika profilu.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
, który ma wpływ tylko na powiadomienia generowane przez aplikacje w profilu zarządzanym.
- Metody
DevicePolicyManager.createAndInitializeUser()
iDevicePolicyManager.createUser()
zostały wycofane. - Metoda
setScreenCaptureDisabled()
blokuje teraz także strukturę wspomagającą, gdy aplikacja danego użytkownika działa na pierwszym planie. EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
teraz domyślnie przyjmuje SHA-256. Szyfrowanie SHA-1 jest nadal obsługiwane na potrzeby zgodności wstecznej, ale w przyszłości zostanie usunięte.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
akceptuje teraz tylko SHA-256.- Interfejsy API inicjatora urządzeń, które istniały w Androidzie 6.0 (poziom API 23), zostały usunięte.
- System
EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
został usunięty, więc obsługa administracyjna NFC nie będzie można automatycznie odblokować urządzenia chronionego przywróconymi ustawieniami fabrycznymi. - Za pomocą dodatku
EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
możesz teraz przekazywać dane do aplikacji właściciela urządzenia podczas obsługi administracyjnej urządzenia zarządzanego przez NFC. - Interfejsy Android for Work API są zoptymalizowane pod kątem uprawnień M w czasie działania, w tym profili Work, warstwy wspomagającej i innych. Nowe interfejsy API uprawnień
DevicePolicyManager
nie mają wpływu na aplikacje w wersjach starszych niż M. - Gdy użytkownicy wycofują się z synchronicznej części procesu konfiguracji zainicjowanego przez intencję
ACTION_PROVISION_MANAGED_PROFILE
lubACTION_PROVISION_MANAGED_DEVICE
, system zwraca teraz kod wynikuRESULT_CANCELED
.
- Wywołanie metody
- Zmiany w innych interfejsach API:
- Użycie danych: nazwa klasy
android.app.usage.NetworkUsageStats
została zmieniona naNetworkStats
.
- Użycie danych: nazwa klasy
- Zmiany w ustawieniach globalnych:
- Tych ustawień nie można już konfigurować w
setGlobalSettings()
:BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
- Te ustawienia globalne można teraz konfigurować w
setGlobalSettings()
:
- Tych ustawień nie można już konfigurować w