Android 8.1 (poziom interfejsu API 27) oferuje użytkownikom i deweloperom szereg nowych funkcji i możliwości. W tym dokumencie znajdziesz informacje o nowościach dla deweloperów.
Android Oreo (wersja Go)
Android Go to nasza inicjatywa mająca na celu optymalizację sposobu korzystania z Androida przez miliardy ludzi korzystających z internetu na całym świecie. Począwszy od Androida 8.1, stajemy się doskonałą platformą na urządzenia podstawowe. Funkcje konfiguracji Androida Oreo (w wersji Go) to m.in.:
- Optymalizacja pamięci. Zwiększyliśmy wykorzystanie pamięci na całej platformie, aby aplikacje mogły działać wydajnie na urządzeniach z maksymalnie 1 GB pamięci RAM.
- Elastyczne opcje kierowania. Nowe stałe funkcje sprzętowe, które pozwalają kierować aplikacje w Google Play na zwykłe urządzenia lub urządzenia z małą ilością pamięci RAM.
- Google Play.Choć wszystkie aplikacje będą dostępne na urządzeniach z Androidem Oreo (wersja Go), w Google Play będą widoczne aplikacje zoptymalizowane przez deweloperów, aby zapewnić komfort miliardom ludzi korzystających z budynku pod kątem przestrzegania wytycznych.
Zaktualizowaliśmy budynek pod kątem miliardów wskazówek o dodatkowe wskazówki dotyczące optymalizacji aplikacji pod kątem urządzeń z Androidem Oreo (wersja Go). W przypadku większości deweloperów najlepszym sposobem na przygotowanie się na urządzenia z Androidem Oreo (wersja Go) jest zoptymalizowanie istniejącego pliku APK lub skorzystanie z dostępnej w Google Play funkcji wielu plików APK w celu kierowania wersji pliku APK na urządzenia z małą ilością pamięci RAM. Pamiętaj, że lżejsza i wydajniejsza aplikacja przynosi korzyści wszystkim odbiorcom, niezależnie od urządzenia.
Interfejs API sieci neuronowych
Neural Networks API zapewnia przyspieszone obliczenia i wnioskowanie w przypadku platform systemów uczących się na urządzeniu, takich jak TensorFlow Lite – wieloplatformowa biblioteka ML Google dla urządzeń mobilnych – a także Caffe2 i inne. Odwiedź repozytorium open source TensorFlow Lite, gdzie znajdziesz dokumenty i pliki do pobrania. TensorFlow Lite współpracuje z interfejsem Neural Networks API, aby sprawnie uruchamiać modele takie jak MobileNets, Inception v3 i Smart Reply na urządzeniu mobilnym.
Aktualizacje platformy autouzupełniania
Android 8.1 (poziom interfejsu API 27) udostępnia kilka ulepszeń autouzupełniania, które możesz wykorzystać w swoich aplikacjach.
Klasa BaseAdapter
zawiera teraz metodę setAutofillOptions()
, która umożliwia przekazywanie wartości w postaci ciągu znaków w adapterze. Jest to przydatne w przypadku elementów sterujących wskaźnikiem, które dynamicznie generują wartości w adapterach. Korzystając na przykład z metody setAutofillOptions()
, możesz podać ciąg reprezentujący listę lat, które użytkownicy mogą wybrać w ramach daty ważności karty kredytowej. Usługi autouzupełniania mogą korzystać z reprezentacji ciągu znaków, aby odpowiednio wypełniać widoki, które wymagają danych.
Dodatkowo klasa AutofillManager
zawiera metodę notifyViewVisibilityChanged(View, int, boolean)
, którą możesz wywoływać, aby powiadamiać platformę o zmianach widoczności widoku w strukturze wirtualnej. Metoda jest też przeciążona w przypadku struktur niewirtualnych. Jednak w przypadku struktur innych niż wirtualne zwykle nie musisz wyraźnie informować platformy, ponieważ metoda jest już wywoływana przez klasę View
.
Android 8.1 daje też usługom autouzupełniania większe możliwości dostosowania interfejsu zapisu przez dodanie obsługi CustomDescription
and
Validator
w ramach SaveInfo
.
Opisy niestandardowe ułatwiają usłudze autouzupełniania określanie, co jest zapisywane. Jeśli na przykład na ekranie widać kartę kredytową, na ekranie może pojawić się logo banku karty kredytowej, ostatnie 4 cyfry numeru karty kredytowej i jej numer ważności. Więcej informacji znajdziesz na zajęciach
CustomDescription
.
Validator
pozwalają uniknąć wyświetlania interfejsu zapisu autouzupełniania, jeśli warunek walidatora nie jest spełniony. Aby dowiedzieć się więcej, zapoznaj się z klasą
Validator i jej podklasami:
LuhnChecksumValidator i RegexValidator.
Powiadomienia
W Androidzie 8.1 wprowadzono te zmiany w powiadomieniach:
- Aplikacje mogą teraz odtwarzać dźwięk alertu tylko raz na sekundę. Dźwięki alertu, które przekraczają tę częstotliwość, nie są dodawane do kolejki i są usuwane. Ta zmiana nie ma wpływu na inne aspekty działania powiadomień i wiadomości z powiadomieniami są nadal publikowane zgodnie z oczekiwaniami.
-
Urządzenia
NotificationListenerService
iConditionProviderService
nie są obsługiwane na urządzeniach z Androidem z małą ilością pamięci RAM, które zwracajątrue
po wywołaniu metodyActivityManager.isLowRamDevice()
.
Aktualizacja EditText
Od poziomu interfejsu API 27 metoda EditText.getText()
zwraca wartość Editable
, a wcześniej CharSequence
. Ta zmiana jest zgodna wstecznie, ponieważ Editable
wdraża CharSequence
.
Interfejs Editable
udostępnia cenne dodatkowe funkcje. Przykład: ponieważ Editable
również implementuje interfejs Spannable
, możesz stosować znaczniki do treści w wystąpieniu EditText
.
Działania związane z automatycznym Bezpiecznym przeglądaniem
Dzięki
wdrożeniu WebView
interfejsu API Bezpiecznego przeglądania Twoja aplikacja może wykrywać przypadki próby otwarcia adresu URL, który Google sklasyfikował jako znane zagrożenie, gdy WebView
próbuje otworzyć stronę. Domyślnie WebView
wyświetla reklamę pełnoekranową ostrzegającą użytkowników o znanym zagrożeniu.
Użytkownicy mogą na nim wczytać adres URL mimo to lub wrócić do bezpiecznej poprzedniej strony.
W Androidzie 8.1 możesz programowo określić, jak aplikacja reaguje na znane zagrożenie:
- Możesz określić, czy Twoja aplikacja zgłasza znane zagrożenia do Bezpiecznego przeglądania.
- Aplikacja może automatycznie wykonywać określone działanie – na przykład przywracać zabezpieczenia – za każdym razem, gdy natrafi na adres URL, który Bezpieczne przeglądanie sklasyfikuje jako znane zagrożenie.
Uwaga: aby uzyskać optymalną ochronę przed znanymi zagrożeniami, przed wywołaniem metody loadUrl()
obiektu WebView
poczekaj, aż zainicjujesz Bezpieczne przeglądanie.
Z poniższych fragmentów kodu dowiesz się, jak nakazać wystąpieniem WebView
w aplikacji zawsze powrotu do stanu zabezpieczeń po napotkaniu znanego zagrożenia:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="true" /> </application> </manifest>
Kotlin
private var superSafeWebView: WebView? = null private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this).apply { webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false startSafeBrowsing(this@SafeBrowsingActivity, { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); }
Kotlin
class MyWebViewClient : WebViewClient() { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponse ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } }
Java
public class MyWebViewClient extends WebViewClient { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponse callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } }
Wyodrębnianie miniatur filmu
Klasa MediaMetadataRetriever
ma nową metodę getScaledFrameAtTime()
, która znajduje klatkę w pobliżu określonej pozycji w czasie i zwraca mapę bitową o tym samym współczynniku proporcji co ramka źródłowa, ale przeskalowana tak, aby pasowała do prostokąta o danej szerokości i wysokości. Przydaje się to do generowania miniatur z filmów.
Zalecamy korzystanie z tej metody zamiast metody getFrameAtTime()
, ponieważ może to zwiększyć ilość pamięci, ponieważ zwraca mapę bitową o tej samej rozdzielczości co film źródłowy. Na przykład klatka z filmu w rozdzielczości 4K miałaby rozmiar 16 MB mapy bitowej, czyli znacznie większą niż w przypadku obrazu miniatury.
Interfejs API pamięci współdzielonej
Android 8.1 (poziom API 27) wprowadza nowy interfejs API SharedMemory
. Ta klasa umożliwia tworzenie i mapowanie anonimowej instancji SharedMemory
oraz zarządzanie nią. Zabezpieczenie pamięci ustawiasz na obiekcie SharedMemory
na potrzeby odczytu lub zapisu. Ponieważ obiekt SharedMemory
jest w formacie Parcelable, możesz go łatwo przekazać do innego procesu za pomocą AIDL.
Interfejs API SharedMemory
współpracuje z obiektem ASharedMemory
w NDK.
ASharedMemory
daje dostęp do deskryptora pliku, który można zmapować na potrzeby odczytu i zapisu. To świetny sposób na udostępnianie dużych ilości danych między aplikacjami lub między wieloma procesami w jednej aplikacji.
Interfejs API TapColors
Android 8.1 (poziom interfejsu API 27) umożliwia dodawanie do interfejsu systemu informacji o kolorach animowanych tapet. Można to zrobić, tworząc obiekt WallpaperColors
z bitmapy, elementu rysowalnego lub używając 3 ręcznie wybranych kolorów.
Możesz również pobrać te informacje o kolorze.
Aby utworzyć obiekt WallpaperColors
, wykonaj jedną z tych czynności:
- Aby utworzyć obiekt
WallpaperColors
przy użyciu 3 kolorów, utwórz wystąpienie klasyWallpaperColors
, przekazując kolor podstawowy, dodatkowy i trzeciorzędny. Kolor podstawowy nie może mieć wartości null. - Aby utworzyć obiekt
WallpaperColors
z bitmapy, wywołaj metodęfromBitmap()
, przesyłając jako parametr źródło bitmapy. - Aby utworzyć obiekt
WallpaperColors
z elementu rysowalnego, wywołaj metodęfromDrawable()
, przekazując jako parametr rysowalne źródło.
Aby pobrać szczegóły koloru podstawowego, dodatkowego lub trzeciorzędnego z tapety, wywołaj te metody:
getPrimaryColor()
wyświetla najbardziej reprezentatywny wizualnie kolor tapety.getSecondaryColor()
zwraca drugi pod względem wielkości kolor tapety.- Metoda
getTertiaryColor()
zwraca trzeci pod względem dominującym kolor tapety.
Aby powiadomić system o wszelkich istotnych zmianach kolorów animowanej tapety, wywołaj metodę notifyColorsChanged()
. Ta metoda wywołuje zdarzenie cyklu życia onComputeColors()
, w którym masz możliwość udostępnienia nowego obiektu WallpaperColors
.
Aby dodać detektor zmian kolorów, możesz wywołać metodę addOnColorsChangedListener()
. Możesz też wywołać metodę getWallpaperColors()
, aby pobrać kolory podstawowe tapety.
Aktualizacje odcisków palców
Klasa FingerprintManager
wprowadziła te kody błędów:
-
FINGERPRINT_ERROR_LOCKOUT_PERMANENT
– użytkownik zbyt wiele razy próbował odblokować urządzenie za pomocą czytnika linii papilarnych. -
FINGERPRINT_ERROR_VENDOR
– wystąpił błąd czytnika linii papilarnych specyficzny dla danego dostawcy.
Aktualności dotyczące kryptografii
W Androidzie 8.1 wprowadzono szereg zmian kryptograficznych:
- W Conscrypt wdrożono nowe algorytmy. Zaleca się używanie implementacji Conscrypt zamiast obecnej implementacji Bouncy Castle. Nowe algorytmy to:
AlgorithmParameters:GCM
KeyGenerator:AES
KeyGenerator:DESEDE
KeyGenerator:HMACMD5
KeyGenerator:HMACSHA1
KeyGenerator:HMACSHA224
KeyGenerator:HMACSHA256
KeyGenerator:HMACSHA384
KeyGenerator:HMACSHA512
SecretKeyFactory:DESEDE
Signature:NONEWITHECDSA
- Algorytm
Cipher.getParameters().getParameterSpec(IvParameterSpec.class)
nie działa już w przypadku algorytmów korzystających z GCM. Zamiast niego użyjgetParameterSpec(GCMParameterSpec.class)
. - Zrefaktoryzowano wiele wewnętrznych klas Conscrypt powiązanych z TLS. Czasami deweloperzy uzyskują dostęp do tych danych, więc podkładki są przechowywane w celu zapewnienia zgodności z wcześniejszymi zastosowaniami, ale niektóre szczegóły uległy zmianie. Na przykład gniazda były wcześniej typu
OpenSSLSocketImpl
, ale teraz są typuConscryptFileDescriptorSocket
lubConscryptEngineSocket
. Oba te typy rozszerzeń obejmują typOpenSSLSocketImpl
. - Metody
SSLSession
używane do wywołania funkcjiIllegalArgumentException
po przekazaniu odwołania o wartości null teraz zwracająNullPointerException
. - RSA
KeyFactory
nie umożliwia już generowania kluczy z tablic bajtów, które są większe niż zakodowany klucz. Wywołania funkcjigeneratePrivate()
igeneratePublic()
, które udostępniająKeySpec
, w których struktura klucza nie wypełnia całego bufora, powoduje wywołanieInvalidKeySpecException
. - Gdy odczyt gniazda zostaje zakłócony przez jego zamknięcie, aplikacja Conscrypt zwracała z odczytu wartość -1. Przeczytana strona wysyła błąd
SocketException
. - Zestaw głównych certyfikatów CA został zmieniony. Chodzi głównie o usunięcie dużej liczby przestarzałych certyfikatów oraz usunięcie certyfikatów głównych WoSign i StartCom. Więcej informacji na ten temat znajdziesz w poście Ostateczne usunięcie zaufania w certyfikatach WoSign i StartCom na blogu Google o bezpieczeństwie.