Zmiany w działaniu Androida 8.0

Oprócz nowych funkcji i możliwości Android 8.0 (poziom API 26) obejmuje różne zmiany w działaniu systemu i interfejsu API. Ten dokument Wyróżniamy najważniejsze zmiany, o których należy pamiętać i które warto wziąć pod uwagę. w Twoich aplikacjach.

Większość tych zmian dotyczy wszystkich aplikacji, niezależnie od wersji Android, na który są kierowane. Kilka zmian wpływa jednak tylko na kierowanie na aplikacje Android 8.0 Aby zwiększyć przejrzystość, składa się z 2 sekcji: Zmiany dla wszystkich aplikacji i Zmiany w kierowaniu na aplikacje Android 8.0

Zmiany dotyczące wszystkich aplikacji

Zmiany w działaniu mają zastosowanie do wszystkich aplikacji, jeśli działa na platformie Android 8.0 (poziom interfejsu API 26) niezależnie od Docelowy poziom interfejsu API. Wszyscy deweloperzy powinni sprawdzić tych zmian i modyfikować aplikacje, aby były właściwie obsługiwane, w odpowiednich przypadkach.

Limity wykonywania w tle

Jedną ze zmian, jakie wprowadza Android 8.0 (poziom interfejsu API 26) wydłużać czas pracy na baterii, gdy aplikacja w pamięci podręcznej stan, bez aktywnej components, system uruchamia wszystkie blokady wybudzenia ustawione przez aplikację.

Aby poprawić wydajność urządzenia, system ogranicza też zachowanie aplikacji niedziałających na pierwszym planie. Więcej szczegółów:

  • Aplikacje działające w tle mają teraz ograniczenia dostęp do usług w tle.
  • Aplikacje nie mogą używać plików manifestu do rejestrowania większości komunikatów niejawnych (czyli transmisji, które nie są kierowane bezpośrednio do aplikacji).

Domyślnie te ograniczenia dotyczą tylko aplikacji kierowanych na O. Pamiętaj jednak: użytkownicy mogą włączyć te ograniczenia dla każdej aplikacji z poziomu ekranu Ustawienia, nawet jeśli aplikacja nie jest kierowana na O.

Android 8.0 (poziom interfejsu API 26) zapewnia też te zmiany w konkretnych metodach:

  • Metoda startService() zgłasza teraz błąd IllegalStateException, jeśli aplikacja kierowanie na Androida 8.0 próbuje użyć tej metody. w sytuacji, gdy tworzenie usług w tle nie jest dozwolone.
  • Nowa metoda Context.startForegroundService() rozpoczyna usługę działającą na pierwszym planie. System zezwala na aplikacje aby dzwonić pod numer Context.startForegroundService(), nawet gdy aplikacja jest w tle. Aplikacja musi jednak wywołać metodę startForeground() tej usługi w ciągu pięciu sekund po utworzeniu usługi.

Więcej informacji: Limity wykonywania w tle.

Ograniczenia lokalizacji w tle na Androidzie

Aby oszczędzać baterię, zadbać o wygodę użytkowników i stan systemu, aplikacje działające w tle otrzymują aktualizacje lokalizacji rzadziej, gdy są używane na urządzeniu z Androidem 8.0. Ta zmiana działania wpływa na wszystkie aplikacje które otrzymują aktualizacje lokalizacji, w tym Usług Google Play.

Te zmiany dotyczą tych interfejsów API:

  • Dostawca uśrednionej lokalizacji (FLP)
  • Geofencing
  • Pomiary GNSS
  • Menedżer lokalizacji
  • Menedżer Wi-Fi

Aby upewnić się, że aplikacja działa zgodnie z oczekiwaniami, wykonaj te czynności:

  • Sprawdź mechanizmy działania aplikacji i upewnij się, że używasz najnowszej lokalizacji API.
  • Sprawdź, czy aplikacja działa zgodnie z oczekiwaniami przy każdym użyciu tych kwestii.
  • Rozważ użycie Scalona Dostawca lokalizacji (ang. Location Provider, FLP) lub geofencing na potrzeby obsługi przypadków użycia, w których bieżącej lokalizacji użytkownika.

Więcej informacji o tych zmianach znajdziesz w artykule Lokalizacja w tle Limity.

Skróty do aplikacji

Android 8.0 (poziom interfejsu API 26) zawiera te zmiany w skrótach do aplikacji:

  • Transmisja nr com.android.launcher.action.INSTALL_SHORTCUT nie ma już żadnego wpływu na aplikację, ponieważ jest ona prywatna, domyślnie transmisję. Zamiast tego utwórz skrót do aplikacji za pomocą requestPinShortcut() z klasy ShortcutManager.
  • ACTION_CREATE_SHORTCUT intencja może teraz tworzyć skróty do aplikacji, którymi zarządzasz za pomocą ShortcutManager zajęcia. Ten zamiar może też starsze skróty programu uruchamiającego, które nie współdziałają z ShortcutManager Wcześniej ta intencja mogła tworzyć tylko starsze skróty programu uruchamiającego.
  • Skróty utworzone za pomocą requestPinShortcut() i skrótów utworzonych w aktywności, która obsługuje ACTION_CREATE_SHORTCUT to w pełni funkcjonalne skróty do aplikacji. W związku z tym aplikacje mogą je teraz aktualizować za pomocą metod w ShortcutManager.
  • Starsze skróty zachowują funkcję z poprzednich wersji Androida, ale musisz ręcznie przekonwertować je na skróty do aplikacji.

Więcej informacji o zmianach w skrótach do aplikacji znajdziesz w Przypinanie skrótów Przewodnik po funkcjach widżetów.

Języki i internacjonalizacja

W Androidzie 7.0 (poziom API 24) wprowadziliśmy koncepcję możliwości określić domyślny język kategorii, ale niektóre interfejsy API nadal używały parametru ogólny Locale.getDefault() bez argumentów, gdy zamiast tego powinni użyć domyślnego języka kategorii DISPLAY. W Androidzie 8.0 (poziom interfejsu API 26) następujące metody używają teraz Locale.getDefault(Category.DISPLAY) zamiast Locale.getDefault():

Locale.getDisplayScript(Locale) również przywraca wartość Locale.getDefault(), gdy Dla parametru Locale określono wartość displayScript – argument jest niedostępny.

Dodatkowe zmiany dotyczące języka i internacjonalizacji następujące:

  • Dzwonienie pod Currency.getDisplayName(null) zwraca NullPointerException. które pasują do udokumentowanego zachowania.
  • Analiza nazwy strefy czasowej została zmieniona. Wcześniej, Urządzenia z Androidem używały wartości zegara systemowego próbkowanej podczas uruchamiania czas do buforowania nazw stref czasowych używanych do analizy daty razy. Mogło to negatywnie wpłynąć na analizę, jeśli system Podczas uruchamiania lub w innych, rzadkich przypadkach zegar był błędny.

    Obecnie w typowych przypadkach logika analizy wykorzystuje teraz dane z pola OIOM bieżącej wartości zegara systemowego podczas analizowania nazw stref czasowych. Ten zmiana dostarcza bardziej poprawne wyniki, które mogą się różnić od wcześniejszych Wersje Androida, w których aplikacja używa zajęć takich jak SimpleDateFormat

  • Android 8.0 (poziom interfejsu API 26) aktualizuje wersję ICU do wersji 58.

Okna alertów

Jeśli aplikacja używa SYSTEM_ALERT_WINDOW uprawnienia i używa jednego z następujących typów okien, aby spróbować wyświetlić alertów nad innymi aplikacjami i oknami systemowymi:

...te okna są zawsze wyświetlane pod oknami, które korzystają z Okno TYPE_APPLICATION_OVERLAY typu. Jeśli aplikacja jest kierowana na Androida 8.0 (poziom interfejsu API 26), korzysta ona z TYPE_APPLICATION_OVERLAY typu okna.

Więcej informacji znajdziesz w artykule Typowe typy okien dla okna alertów w sekcji zmian działania aplikacji, na Androida 8.0.

Wpisywanie i nawigacja

Wraz z pojawieniem się aplikacji na Androida na ChromeOS i innych dużych formatów takich jak tablety. Użytkownicy coraz częściej korzystają z nawigacji za pomocą klawiatury. Aplikacje na Androida. W Androidzie 8.0 (poziom interfejsu API 26) zmieniliśmy działanie za pomocą używać klawiatury jako urządzenia wejściowego nawigacji, co zwiększa niezawodność, przewidywalny model nawigacji za pomocą strzałek i tabulatorów.

Wprowadziliśmy następujące zmiany w zaznaczaniu elementów. zachowanie:

  • Jeśli nie zdefiniowano żadnych kolorów stanu zaznaczenia dla View obiekt (pierwszy plan lub tło) rysowalna), platforma ustawia teraz domyślny kolor wyróżnienia View To wyróżnienie to faliste rysy, które jest na podstawie tematu aktywności.

    Jeśli nie chcesz, aby obiekt View używał tej wartości domyślnej podświetlić, kiedy android:defaultFocusHighlightEnabled dla atrybutu false w pliku XML układu zawierającego View lub wsiądź w false do setDefaultFocusHighlightEnabled() w logice interfejsu aplikacji.

  • Aby sprawdzić, jak wprowadzanie za pomocą klawiatury wpływa na fokus elementu interfejsu, możesz włączyć Rysunek > Pokaż granice układu. Na Androidzie 8.0, wyświetla się „X” nad elementem, który obecnie ma ostrość.

Poza tym wszystkie elementy paska narzędzi w Androidzie 8.0 są automatycznie klastry nawigacji z klawiaturą, co ułatwia użytkownikom poruszanie się po pasku narzędzi całość.

Aby dowiedzieć się więcej o poprawianiu obsługi nawigacji za pomocą klawiatury w Twojej aplikacji, zapoznaj się z Pomocą techniczną Przewodnik ponawigacji za pomocą klawiatury.

Autouzupełnianie formularzy internetowych

Gdy dzięki Androidowi Autouzupełnianie Framework zapewnia wbudowaną obsługę autouzupełniania, następujące metody związane z obiektami WebView uległy zmianie w przypadku aplikacji zainstalowanych na urządzeniach z Androidem 8.0 (poziom interfejsu API 26):

WebSettings
WebViewDatabase
  • Łączę Nie: clearFormData() nie ma już żadnego skutku.
  • hasFormData() metoda zwraca teraz false. Wcześniej ta metoda zwracała true, gdy formularz zawierał dane.

Ułatwienia dostępu

Android 8.0 (poziom interfejsu API 26) zawiera te zmiany w ułatwieniach dostępu:

  • Platforma ułatwień dostępu konwertuje teraz wszystkie gesty dwukrotnego dotknięcia na ACTION_CLICK . Ta zmiana sprawia, że TalkBack działa bardziej jak inne usług ułatwień dostępu.

    Jeśli obiekty View w Twojej aplikacji korzystają z dotyku niestandardowego musisz sprawdzić, czy nadal działa z TalkBack. Możesz wystarczy zarejestrować moduł obsługi kliknięć, który View których używają obiekty. Jeśli TalkBack nadal nie rozpoznaje gestów wykonywanych na tych urządzeniach View obiekty, zastąp performAccessibilityAction()

  • Usługi ułatwień dostępu są już znane ClickableSpan wystąpienia w Twojej aplikacji TextView obiektów.

Aby dowiedzieć się więcej o ułatwieniach dostępu w aplikacji, zobacz Ułatwienia dostępu.

Sieć i połączenia HTTP(S)

Android 8.0 (poziom interfejsu API 26) obejmuje te zmiany w działaniu połączenia sieciowe i połączenia HTTP(S):

  • Żądania OPTIONS bez treści mają atrybut Content-Length: 0 nagłówek. Wcześniej nie miały nagłówka Content-Length.
  • HttpURLConnection normalizuje adresy URL zawierające puste ścieżki przez dodanie ukośnik za nazwą hosta lub urzędu. Na przykład: konwertuje http://example.com na http://example.com/
  • Niestandardowy selektor serwera proxy ustawiony przez ProxySelector.setDefault() kieruje reklamy tylko na adres (schemat, host i port) żądanego adresu URL. Dlatego wybór serwera proxy może być oparty tylko na tych wartościach. Adres URL przekazywane do niestandardowego selektora serwera proxy nie zawiera żądanych adresów URL ścieżki, parametrów zapytania czy fragmentów.
  • Identyfikatory URI nie mogą zawierać pustych etykiet.

    Wcześniej platforma obsługiwała obejście polegające na akceptowanie pustych etykiet w nazwy hostów, co jest niedozwolone w przypadku identyfikatorów URI. To obejście było przeznaczone dla zgodność ze starszymi wersjami libcore. Deweloperzy używający interfejsu API nieprawidłowo zobaczy komunikat ADB: „Identyfikator URI example.com ma puste etykiety w nazwa hosta. Ten format ma nieprawidłowy format i nie zostanie zaakceptowany w przyszłości na Androidzie wydania”. Android 8.0 usuwa to obejście, system zwraca wartość null w przypadku nieprawidłowych identyfikatorów URI.

  • Implementacja HttpsURLConnection w Androidzie 8.0 nie obsługuje niezabezpieczonej wersji protokołu TLS/SSL.
  • Obsługa tunelowania połączeń HTTP(S) zmieniła się w ten sposób:
    • Podczas tunelowania połączenia HTTPS przez połączenie system prawidłowo umieszcza numer portu (:443) w wierszu Host podczas wysyłania. te informacje na serwer pośredni. Wcześniej, jest wyświetlany tylko w wierszu CONNECT.
    • System nie wysyła już klientów użytkownika i autoryzacji serwera proxy z żądania tunelowanego do serwera proxy.

      System nie wysyła już na stronę przeprowadzono tunelowanie Http(s)URLConnection na serwerze proxy podczas konfigurowania przez tunel. Zamiast tego system generuje nagłówek autoryzacji proxy, i wysyła ją do serwera proxy, gdy ten serwer Kod HTTP 407 w odpowiedzi na początkowe żądanie.

      System przestanie też kopiować nagłówek klienta użytkownika. z żądania tunelowanego do żądania serwera proxy, które konfiguruje przez tunel. Zamiast tego biblioteka generuje dla niej nagłówek klienta użytkownika, użytkownika.

  • send(java.net.DatagramPacket) zwraca wyjątek SocketException, jeśli wcześniej wykonana metoda Connect() niepowodzenie.
    • DatagramSocket.connect() ustawia pendingSocketException, jeśli błąd wewnętrzny. Przed Androidem 8.0 kolejna funkcja recv() wywołał błąd SocketException, mimo że wywołanie send() powiodło się. Aby zachować spójność, oba wywołania zgłaszają teraz wyjątek SocketException.
  • InetAddress.isReachable() próbuje wykonać ICMP, zanim przełączy się na protokół TCP Echo protokołu.
    • Niektóre hosty blokujące port 7 (TCP Echo), takie jak google.com, mogą mogą być teraz osiągalne, jeśli zaakceptują protokół ICMP Echo.
    • W przypadku naprawdę niedostępnych hostów ta zmiana oznacza 2-krotnie ile czasu zostało do ponowienia połączenia.

Bluetooth

Android 8.0 (poziom interfejsu API 26) wprowadza te zmiany w długości dane używane przez funkcję ScanRecord.getBytes() pobiera:

  • Metoda getBytes() nie przyjmuje żadnych założeń liczba otrzymanych bajtów. Nie należy więc stosować żadnych minimalnej lub maksymalnej liczby zwracanych bajtów. Zamiast tego powinni ocenić długość tablicy wynikowej.
  • Urządzenia zgodne z Bluetooth 5 mogą zwracać dane dłuższe niż wcześniejsze maksimum wynoszące ok. 60 bajtów.
  • Jeśli urządzenie zdalne nie dostarcza odpowiedzi na skanowanie – mniej niż 60 bajtów które mogą zostać zwrócone.

Sprawne łączenie

Android 8.0 (poziom interfejsu API 26) wprowadza wiele ulepszeń w ustawieniach Wi-Fi, aby ułatwić wybór Wybierz sieć Wi-Fi, która zapewni użytkownikom najlepsze wrażenia. Konkretne zmiany to m.in.:

  • Większa stabilność i niezawodność.
  • Bardziej intuicyjny interfejs użytkownika.
  • Jedno, skonsolidowane menu Ustawienia Wi-Fi.
  • Na zgodnych urządzeniach automatyczna aktywacja Wi-Fi w przypadku zapisanej sieci wysokiej jakości jest w pobliżu.

Bezpieczeństwo

Android 8.0 obejmuje te funkcje zabezpieczeń zmiany:

  • Platforma nie obsługuje już protokołu SSLv3.
  • Podczas nawiązywania połączenia HTTPS z serwerem, które nieprawidłowo implementuje negocjacje wersji protokołu TLS, HttpsURLConnection nie próbuje już obejść tego problemu na korzystanie z wcześniejszych wersji protokołu TLS i ponawianie ponownych prób.
  • Android 8.0 (poziom interfejsu API 26) stosuje bezpieczne przetwarzanie (SECCOMP) filtr do wszystkich aplikacji. Lista dozwolonych wywołań Syscall jest ograniczona do tych narażone na kontakt bionikowy. Chociaż dostępnych jest kilka innych wywołań Syscall dla zgodności wstecznej odradzamy ich używanie.
  • Obiekty WebView Twojej aplikacji są teraz uruchamiane w trybie wieloprocesowym i trybu uzyskiwania zgody. Treści internetowe są przetwarzane w ramach osobnego, osobnego procesu o procesie aplikacji zwiększającym bezpieczeństwo.
  • Nie możesz już zakładać, że pliki APK znajdują się w katalogach, których nazwy kończą się -1 lub -2. Aplikacje, które powinny używać sourceDir, aby uzyskać z katalogu i nie bezpośrednio polegać na formacie katalogu.
  • Informacje o ulepszeniach zabezpieczeń związanych z korzystaniem z reklam natywnych Więcej informacji znajdziesz w artykule na temat bibliotek natywnych.

Oprócz tego w Androidzie 8.0 (poziom interfejsu API 26) wprowadzamy następujące zmiany związane z instalowaniem nieznane aplikacje z nieznanych źródeł:

Dodatkowe informacje o instalowaniu nieznanych aplikacji znajdziesz w Nieznana aplikacja Przewodnik po uprawnieniach instalacji.

Dodatkowe wskazówki na temat zwiększania bezpieczeństwa aplikacji znajdziesz tutaj: Bezpieczeństwo dla deweloperów aplikacji na Androida

Prywatność

Android 8.0 (poziom interfejsu API 26) powoduje, że następujące funkcje związane z ochroną prywatności zmian na platformie.

  • Platforma obsługuje teraz identyfikatory w inny sposób.
    • W przypadku aplikacji, które zostały zainstalowane przed aktualizacją OTA do wersji Android 8.0 (poziom API 26) (poziom interfejsu API 26), wartość Pole ANDROID_ID pozostaje bez zmian chyba że odinstalujesz aplikację, a potem zainstalujesz ponownie po aktualizacji OTA. Aby zachować wartości w po zakończeniu aktualizacji OTA, programiści mogą powiązać starą i nową wartość za pomocą Kopia zapasowa pary klucz/wartość.
    • W przypadku aplikacji zainstalowanych na urządzeniach z Androidem 8.0 wartość ANDROID_ID ma teraz zakres na klucz podpisywania aplikacji i na użytkownika. Wartość Adres ANDROID_ID jest unikalny dla każdej kombinacji klucza podpisywania aplikacji, użytkownika i urządzenia. W rezultacie na tym samym urządzeniu mogą działać aplikacje z różnymi kluczami podpisywania nie zobaczą już takiego samego identyfikatora Androida (nawet dla tego samego użytkownika).
    • Wartość ANDROID_ID nie zmienia się podczas odinstalowywania ani ponownego instalowania pakietu, o ile klucz podpisywania jest taki sam (a aplikacja nie została zainstalowana przed aktualizacją OTA (wersja Androida 8.0).
    • Wartość ANDROID_ID nie zmienia się, nawet jeśli aktualizacja systemu spowoduje zmianę klucza podpisywania pakietu.
    • na urządzeniach wysyłanych z użyciem Usług Google Play i identyfikatora wyświetlania reklam. musisz użyć Identyfikator wyświetlania reklam. Prosty, standardowy system do zarabiania na aplikacjach, Identyfikator wyświetlania reklam to unikalny, możliwy do zresetowania przez użytkownika identyfikator wyświetlania reklam. Jest on dostępny przez Usługi Google Play.

      Urządzenia innych producentów powinny kontynuować aby dostarczyć ANDROID_ID.

  • Zapytanie o właściwość systemową net.hostname zwraca wartość null wynik.

Logowanie niewykrytych wyjątków

Jeśli aplikacja zainstaluje Thread.UncaughtExceptionHandler, który robi to nie możesz połączyć się z domyślnym numerem Thread.UncaughtExceptionHandler, system nie powoduje zamknięcia aplikacji w przypadku wystąpienia nieobsłużonego wyjątku. Od w Androidzie 8.0 (poziom interfejsu API 26), system rejestruje zapis stosu wyjątków w tej sytuacja; we wcześniejszych wersjach platformy system nie musiałby mieć zarejestrowano zapis stosu wyjątków.

Zalecamy niestandardowy atrybut Thread.UncaughtExceptionHandler zawsze wyzwalają metodę domyślny moduł obsługi, na aplikacje stosujące się do tej rekomendacji nie mają wpływu zmiany w Androidzie 8.0.

zmiana podpisu za pomocą funkcji findViewById()

Wszystkie instancje metody findViewById() zwracają teraz <T extends View> T zamiast View. Ta zmiana ma takie konsekwencje:

  • Może to spowodować, że istniejący kod będzie mieć niejednoznaczny typ zwrotu, na przykład, jeśli jest zarówno someMethod(View), jak i someMethod(TextView), który przenosi wynik wywołania do findViewById()
  • Jeśli używany jest język źródłowy Java 8, wymaga to jawnego rzutu na View, gdy typ zwrotu nie jest ograniczony (na przykład assertNotNull(findViewById(...)).someViewMethod())
  • Zastąpienia nieostatecznych metod findViewById() (dla (np. Activity.findViewById()) będą potrzebować zwrotu Zaktualizowano typ.

Zmiana statystyk użytkowania dostawcy kontaktów

W poprzednich wersjach Androida komponent Dostawca kontaktów pozwala programistom uzyskać dane o korzystaniu dla każdego kontaktu. Te dane o korzystaniu ujawnia informacje o każdym adresie e-mail i powiązanym numerze telefonu; z kontaktem, w tym liczbę prób nawiązania z nim kontaktu i kiedy po raz ostatni skontaktowano się z danym kontaktem. Aplikacje, które proszą o oznaczenie READ_CONTACTS uprawnienia do odczytu tych danych.

Aplikacje mogą odczytać te dane, jeśli o to poprosisz READ_CONTACTS uprawnienia. W Androidzie 8.0 (poziom interfejsu API 26) i nowszych zapytania o dane o korzystaniu są zwracane wartości przybliżone, a nie dokładne. System Android utrzymuje wartości wewnętrznie, tak więc ta zmiana nie będzie miała wpływu API autouzupełniania.

Ta zmiana działania wpływa na te parametry zapytania:

Obsługa odbioru

AbstractCollection.removeAll() i AbstractCollection.retainAll() teraz zawsze zwraca NullPointerException; poprzednia wersja Element NullPointerException nie został odrzucony, gdy kolekcja została puste. Ta zmiana sprawia, że zachowanie jest zgodne z dokumentacją.

Android Enterprise

Android 8.0 (poziom interfejsu API 26) zmienia działania niektórych interfejsów API i funkcji aplikacji firmowych, w tym kontrolerów zasad (DPC). Wprowadzone zmiany:

  • Nowe zachowania ułatwiające aplikacjom obsługę profili służbowych na w pełni zarządzanych urządzeniach.
  • Zmiany dotyczące obsługi aktualizacji systemu, weryfikacji aplikacji oraz uwierzytelniania zwiększyć integralność urządzenia i systemu.
  • Ulepszenia obsługi administracyjnej, powiadomień, Ekran ostatnich danych i zawsze włączona sieć VPN.

Aby poznać wszystkie zmiany wprowadzone w Androidzie 8.0 (poziom interfejsu API 26) i dowiedzieć się, jak mogą ma wpływ na Twoją aplikację, przeczytaj Android w firmach

Aplikacje kierowane na Androida 8.0

Te zmiany w działaniu dotyczą wyłącznie aplikacji, na które są kierowane Android 8.0 (poziom interfejsu API 26) lub nowszy. aplikacje kompatybilne z Androidem 8.0, lub ustaw targetSdkVersion na Androida 8.0 lub nowszego ich aplikacje do prawidłowej obsługi tych zachowań (w stosownych przypadkach).

Okna alertów

Aplikacje używające uprawnienia SYSTEM_ALERT_WINDOW uprawnienia nie mogą już używać następujących typów okien do wyświetlania okien alertów nad innymi aplikacjami i oknami systemowymi:

Aplikacje muszą używać nowego typu okna o nazwie TYPE_APPLICATION_OVERLAY

Jeśli korzystasz z metody Okno TYPE_APPLICATION_OVERLAY wpisz w celu wyświetlenia okien alertów dotyczących aplikacji, zachowaj te cechy o nowym typie okna:

  • Okna alertów aplikacji są zawsze widoczne w kluczowych oknach systemowych, takich jak takie jak pasek stanu czy edytory IME.
  • System może przenosić okna lub zmieniać ich rozmiar TYPE_APPLICATION_OVERLAY typu okna.
  • W obszarze powiadomień można wybrać ustawienia blokowania wyświetlania przez aplikację okien z alertami wyświetlanych przy użyciu TYPE_APPLICATION_OVERLAY typu okna.

Powiadomienia o zmianach treści

W Androidzie 8.0 (poziom interfejsu API 26) zmienia się sposób ContentResolver.notifyChange() i registerContentObserver(Uri, boolean, ContentObserver) w aplikacjach kierowanych na Androida 8.0.

Te interfejsy API wymagają teraz prawidłowego atrybutu ContentProvider jest zdefiniowany dla urzędu we wszystkich identyfikatorach URI. Zdefiniowanie prawidłowego ContentProvider z odpowiednimi uprawnieniami spowoduje pomagają chronić aplikację przed zmianami treści przez złośliwe aplikacje i zapobiegać przed wyciekiem potencjalnie prywatnych danych do szkodliwych aplikacji.

Wyświetl fokus

Klikalne obiekty View mogą teraz zaznaczać również wartość domyślną. Jeśli chcesz, aby obiekt View mógł być klikalny, ale nie ustaw Atrybut android:focusable do false w układzie Plik XML zawierający View lub przekaż w false do setFocusable() w interfejsie aplikacji logikę logiczną.

Dopasowywanie klienta użytkownika w funkcji wykrywania przeglądarki

Android 8.0 (poziom interfejsu API 26) i nowsze zawierają ciąg identyfikatora kompilacji OPR. Niektóre dopasowania do wzorca mogą powoduje, że logika wykrywania przeglądarki błędnie identyfikuje przeglądarkę inną niż Opera jako Opera. Przykładem dopasowania do wzorca może być:

if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}

Aby uniknąć problemów wynikających z takiej nieprawidłowej identyfikacji, użyj ciągu innego niż OPR jako dopasowanie do wzorca w przeglądarce Opera.

Bezpieczeństwo

Te zmiany wpływają na bezpieczeństwo w Androidzie 8.0 (poziom interfejsu API 26):

  • Jeśli konfiguracja zabezpieczeń sieci aplikacji opcje obsługi ruchu nieszyfrowanego, Obiekty WebView nie mają dostępu do stron internetowych przez HTTP. Każdy Obiekt WebView musi używać protokołu HTTPS.
  • Ustawienie systemowe Zezwalaj na nieznane źródła zostało usunięte. w uprawnienie Instalowanie nieznanych aplikacji umożliwia zarządzanie nieznanymi instalacjami aplikacji z nieznanych źródeł. Więcej informacji o tym nowym uprawnieniu: Nieznana aplikacja Przewodnik po uprawnieniach instalacji.

Dodatkowe wskazówki na temat zwiększania bezpieczeństwa aplikacji znajdziesz tutaj: Bezpieczeństwo dla deweloperów aplikacji na Androida

Dostęp do konta i wykrywalność

W Androidzie 8.0 (poziom interfejsu API 26) aplikacje nie mają już dostępu z kontami użytkowników, chyba że podmiot uwierzytelniający jest właścicielem kont lub użytkownik udziela takiego dostępu. GET_ACCOUNTS uprawnienie już nie wystarcza. Aby aplikacja mogła mieć dostęp do konta, możesz użyć funkcji AccountManager.newChooseAccountIntent() lub aplikacji uwierzytelniającej . Po uzyskaniu dostępu do kont aplikacja może zadzwonić AccountManager.getAccounts() aby uzyskać do nich dostęp.

Wycofywanie Androida 8.0 LOGIN_ACCOUNTS_CHANGED_ACTION aplikacji; powinni zamiast tego użyć addOnAccountsUpdatedListener() aby otrzymywać informacje o kontach w trakcie działania.

Informacje na temat nowych interfejsów API i metod dodanych do dostępu do konta oraz wykrywalność, patrz Dostęp do konta i wykrywalność.

Prywatność

Poniższe zmiany wpływają na prywatność w Androidzie 8.0 (poziom interfejsu API 26).

  • Właściwości systemowe net.dns1, net.dns2, net.dns3 i net.dns4 nie są już jest to zmiana, która zwiększa prywatność na platformie.
  • Aby uzyskać informacje o sieci, takie jak serwery DNS, aplikacje z ACCESS_NETWORK_STATE może zarejestrować NetworkRequest lub NetworkCallback obiekt. Te klasy są dostępne w Androidzie 5.0 (poziom interfejsu API 21) i nowszych.
  • Plik Build.SERIAL został wycofany. Aplikacje, które muszą znać numer seryjny sprzętu, powinny nowej metody Build.getSerial(), która wymaga parametru READ_PHONE_STATE uprawnienia.
  • Interfejs API LauncherApps nie zezwala już na profil służbowy aby uzyskać informacje o profilu głównym. Gdy użytkownik jest w pracy profil, interfejs API LauncherApps działa tak, jakby żadna aplikacja są zainstalowane w innych profilach w tej samej grupie profili. Tak jak wcześniej, próby uzyskania dostępu do niepowiązanych profili powodują wyjątek SecurityExceptions.

Uprawnienia

Przed Androidem 8.0 (poziom interfejsu API 26) jeśli aplikacja prosiła o uprawnienia w czasie działania aplikacji i przyznano odpowiednie uprawnienia, aplikacji otrzymały pozostałe uprawnienia należące do tego samego grupy uprawnień i zarejestrowanych w pliku manifestu.

W aplikacjach kierowanych na Androida 8.0 poprawiono. Aplikacja otrzymuje tylko te uprawnienia, które ma bezpośrednio poproszono o dostęp. Jeśli jednak użytkownik przyzna aplikacji uprawnienia, kolejne prośby o uprawnienia w tej grupie przyznanych automatycznie.

Załóżmy na przykład, że aplikacja zawiera zarówno READ_EXTERNAL_STORAGE, jak i WRITE_EXTERNAL_STORAGE w pliku manifestu. Aplikacja prosi o READ_EXTERNAL_STORAGE i przyznanych przez użytkownika. Jeśli aplikacja jest kierowana na interfejs API na poziomie 25 lub niższym, system też przyznaje WRITE_EXTERNAL_STORAGE w tym samym ponieważ należy do tej samej grupy uprawnień STORAGE oraz jest zarejestrowanych w pliku manifestu. Jeśli aplikacja jest kierowana na Androida 8.0 (poziom interfejsu API 26), system przyznaje w tym momencie tylko READ_EXTERNAL_STORAGE; jeśli jednak aplikacja zażąda później WRITE_EXTERNAL_STORAGE, system natychmiast przyznaje to uprawnienie bez pytania użytkownika o zgodę.

Multimedia

  • Platforma może osiągnąć automatyczne wyciszanie tła, o samej treści. W tym przypadku, gdy inna aplikacja żąda koncentracji na AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, aplikacja zmniejsza głośność, ale zwykle nie otrzymuje onAudioFocusChange() oddzwanianie i nie utratą ostrości audio. Dostępne są nowe interfejsy API, które mogą zastąpić to zachowanie w przypadku które wymagają wstrzymywania zamiast ukrywania się.
  • Gdy użytkownik odbierze połączenie telefoniczne, aktywne strumienie multimediów zostaną wyciszone na czas .
  • Wszystkie interfejsy API związane z dźwiękiem powinny używać protokołu AudioAttributes a nie typów strumieni audio. Nadal używaj typów strumieni audio wyłącznie do sterowania głośnością. Inne sposoby wykorzystania typów strumieni nadal działają (np. argument streamType w wycofanym AudioTrack), ale system rejestruje to jako błąd.
  • W przypadku korzystania z narzędzia AudioTrack, jeśli aplikacja żąda odpowiednio dużego bufora audio, jeśli będzie ona dostępna, spróbuje użyć danych wyjściowych z głębokiego bufora.
  • W Androidzie 8.0 (poziom interfejsu API 26) obsługa zdarzeń związanych z przyciskami multimediów wygląda inaczej:
    1. Obsługa przycisków multimediów w działaniu interfejsu użytkownika nie uległo zmianie: działania na pierwszym planie nadal mają priorytet podczas obsługi zdarzeń związanych z przyciskiem multimedialnym.
    2. Jeśli działanie na pierwszym planie nie obsługuje zdarzenia przycisku multimediów, system kieruje to zdarzenie. w aplikacji, która ostatnio odtwarzała dźwięk lokalnie. Stan aktywności, flagi i odtwarzanie stan sesji multimedialnej nie jest brany pod uwagę przy określaniu, która aplikacja otrzymuje multimedia zdarzenia przycisków.
    3. Jeśli sesja multimediów w aplikacji została opublikowana, system wysyła zdarzenie przycisku multimediów do sekcji MediaButtonReceiver, jeśli ją ma.
    4. W każdym innym przypadku system odrzuca zdarzenie związane z przyciskiem multimediów.

Biblioteki natywne

W aplikacjach kierowanych na Androida 8.0 (poziom interfejsu API 26) biblioteki natywne nie mogą być dłużej wczytywane, jeśli zawierają segmenty wczytywania, które są zarówno dostępne do zapisu, . Z powodu tej zmiany niektóre aplikacje mogą przestać działać, jeśli: biblioteki natywne z nieprawidłowymi segmentami wczytywania. To jest zabezpieczeń.

Więcej informacji można znaleźć w sekcji Segmenty możliwe do zapisu i wykonywalne.

Zmiany tagu łączącego są powiązane z poziomem interfejsu API, na który kierowana jest aplikacja. Jeśli to zmiana tagu łączącego docelowym poziomie interfejsu API, aplikacja nie może wczytać biblioteki. Jeśli kierujesz reklamy poziom interfejsu API niższy niż poziom interfejsu API, na którym następuje zmiana tagu łączącego; logcat wyświetla ostrzeżenie.

Obsługa odbioru

W Androidzie 8.0 (poziom API 26): Metoda Collections.sort() została wdrożona od List.sort(). Na odwrót dotyczyło Androida 7.x (poziomy interfejsu API 24 i 25): Domyślna implementacja interfejsu List.sort() pod tytułem Collections.sort().

Ta zmiana zezwala na: Collections.sort() aby korzystać ze zoptymalizowanej kategorii List.sort() z implementacjami z tymi ograniczeniami:

  • Implementacje klucza List.sort() nie może wywoływać funkcji Collections.sort(), ponieważ spowodowałoby to przepełnienie stosu z powodu nieskończonej rekurencji. Jeśli chcesz, aby ustawienia domyślne w implementacji List, nie zastępuj sort()

    Jeśli klasa nadrzędna nieprawidłowo zaimplementuje funkcję sort(), to jest to zwykle wystarczy zastąpić wartość List.sort() dzięki implementacji opartej na List.toArray(), Arrays.sort() i ListIterator.set(). Na przykład:

    @Override
    public void sort(Comparator<? super E> c) {
      Object[] elements = toArray();
      Arrays.sort(elements, c);
      ListIterator<E> iterator = (ListIterator<Object>) listIterator();
      for (Object element : elements) {
        iterator.next();
        iterator.set((E) element);
      }
    }
    

    W większości przypadków możesz też zastąpić List.sort() z która deleguje różne ustawienia domyślne implementacji w zależności od poziomu interfejsu API. Na przykład:

    @Override
    public void sort(Comparator<? super E> comparator) {
      if (Build.VERSION.SDK_INT <= 25) {
        Collections.sort(this);
      } else {
        super.sort(comparator);
      }
    }
    

    Jeśli korzystasz z drugiej strony tylko dlatego, że chcesz mieć sort() dostępnej na wszystkich poziomach interfejsu API, warto nadać jej unikalną nazwę, na przykład sortCompat(), zamiast zastępowania sort()

  • Collections.sort() jest teraz liczone jako modyfikacji strukturalnej Wyświetl listę implementacji, które wywołują sort(). Na przykład w wersjach z platformy sprzed Androida 8.0 (poziom interfejsu API 26) ArrayList i dzwonię pod sort() w trakcie iteracji rzuciłby ConcurrentModificationException czy sortowanie zostało wykonane, dzwoniąc pod numer List.sort(). Collections.sort() nie zgłosił wyjątku.

    Ta zmiana sprawi, że zachowanie platformy będzie bardziej spójne: daje teraz ConcurrentModificationException.

Sposób ładowania klas

Android 8.0 (poziom interfejsu API 26) sprawdza, czy moduły ładowania klas nie narusza założenia dotyczące środowiska wykonawczego przy wczytywaniu nowych klas. Te weryfikacje są jest wykonywana niezależnie od tego, czy klasa jest odwołuje się do języka Java (z forName()), Kod bajtowy Dalvik lub JNI. Platforma nie przechwytuje bezpośrednich wywołań z Javy do metody loadClass(), która też nie jest sprawdzana. wyniki takich rozmów. Takie zachowanie nie powinno wpływać na prawidłowe zachowanie z programów ładujących klas.

Platforma sprawdza, czy deskryptor klasy zwracany przez program wczytujący klasy pasuje do oczekiwanego deskryptora. Jeśli zwrócony deskryptor nie pasuje, platforma zgłasza błąd NoClassDefFoundError i zapisuje w z wyjątkiem precyzyjnego komunikatu informującego o rozbieżności.

Platforma sprawdza też, czy deskryptory żądanych klas są prawidłowe. Ten wykrywa wywołania JNI, które pośrednio ładują klasy, takie jak GetFieldID(), przekazywania nieprawidłowych deskryptorów do tych klas. np. pole z podpisem Nie można znaleźć java/lang/String, ponieważ podpis jest nieprawidłowy. powinna być Ljava/lang/String;.

Różni się od wywołania JNI do FindClass() gdzie java/lang/String jest prawidłową pełną nazwą.

Android 8.0 (poziom interfejsu API 26) nie obsługuje definiowania klas przez wiele modułów ładowania klas za pomocą tego samego obiektu DexFile. Jeśli spróbujesz to zrobić, środowisko wykonawcze Androida zgłasza błąd InternalError z komunikatem „Próbuję zarejestrować plik .dex <filename> z wieloma programami wczytującymi klasy”.

Interfejs DexFile API został wycofany, ale zdecydowanie zalecamy korzystanie z jednym z programów uruchamiających klasy platformy, w tym PathClassLoader lub BaseDexClassLoader.

Uwaga: możesz utworzyć wiele modułów ładowania klas, które odwołują się do ten sam kontener plików APK lub JAR z systemu plików. Zazwyczaj nie zawsze spowoduje duże obciążenie pamięci. Jeśli pliki DEX w kontenerze są przechowywane zamiast skompresowane, platforma może wykonać na nich operację mmap, a nie ich bezpośrednie wyodrębnianie. Jeśli jednak platforma musi wyodrębnić plik DEX z kontenera, odwoływanie się do pliku DEX może zużywać dużo pamięci.

W Androidzie wszystkie moduły ładowania klas są uważane za zdolne do równoległego wczytywania. Gdy wiele wątków próbuje wczytać tę samą klasę z tą samą klasą program uruchamiający, wygrywa pierwszy wątek, który ukończy operację, a wynik jest używany do w innych wątkach. Dzieje się tak niezależnie od tego, czy program wczytujący klasy zwrócił tę samą klasę, zwrócił inną klasę lub zgłosił wyjątek. Platforma dyskretnie ignoruje takie wyjątki.

Uwaga: w wersjach platformy niż w Androidzie 8.0 (poziom interfejsu API 26), naruszenie tych założeń może spowodować zdefiniowanie tej samej klasa wiele razy, uszkodzenie stosu z powodu pomylenia klas i inne niepożądane skutki.