Zmiany w działaniu: wszystkie aplikacje

Platforma Android 17 zawiera zmiany w działaniu, które mogą mieć wpływ na Twoją aplikację. Poniższe zmiany w działaniu dotyczą wszystkich aplikacji działających na Androidzie 17 niezależnie od targetSdkVersion. Przetestuj aplikację, a następnie w razie potrzeby zmodyfikuj ją, aby obsługiwała te zmiany.

Zapoznaj się też z listą zmian w działaniu, które wpływają tylko na aplikacje kierowane na Androida 17.

Główna funkcja

Android 17 (API na poziomie 37) zawiera te zmiany, które modyfikują lub rozszerzają różne podstawowe funkcje systemu Android.

Limity pamięci aplikacji

Android 17 wprowadza limity pamięci aplikacji oparte na całkowitej pamięci RAM urządzenia, aby zapewnić bardziej stabilne i deterministyczne środowisko dla aplikacji i użytkowników Androida. Te limity koncentrują się na wyciekach pamięci i innych wartościach odstających, zanim spowodują niestabilność całego systemu, co skutkuje przeskokami interfejsu, szybszym zużyciem baterii i zamykaniem aplikacji. Spodziewamy się, że zmiana ta będzie miała minimalny wpływ na zdecydowaną większość sesji aplikacji, ale zalecamy stosowanie sprawdzonych metod dotyczących pamięci, w tym ustalenie wartości bazowej pamięci.

Aby sprawdzić, czy sesja aplikacji została objęta tym problemem, wywołaj funkcję getDescriptionApplicationExitInfo. Jeśli aplikacja została objęta tym problemem, powód zakończenia sesji będzie miał wartość REASON_OTHER, a opis będzie zawierać ciąg znaków "MemoryLimiter:AnonSwap" wraz z innymi informacjami. Możesz też użyć profilowania opartego na wyzwalaczachTRIGGER_TYPE_ANOMALY, aby uzyskać zrzuty sterty zbierane po osiągnięciu limitu pamięci.

Dokumentacja Zarządzanie pamięcią aplikacji zawiera informacje, które pomogą Ci zdiagnozować problemy z pamięcią aplikacji i zoptymalizować zużycie zasobów.

Testowanie działania aplikacji w warunkach ograniczonej pamięci

Za pomocą Android Debug Bridge (adb) możesz dostosować lub wyłączyć limity pamięci na dowolnym urządzeniu, na którym są one nałożone. Polecenie powłoki am zawiera 3 podpolecenia do dostosowywania limitów pamięci. (Te polecenia nie mają wpływu na urządzenie, które nie nakłada limitów pamięci).

  • am memory-limiter ignore <uid>|none|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am memory-limiter status
ignore

Nakazuje ogranicznikowi pamięci ignorowanie niektórych lub wszystkich procesów. Przekazanie identyfikatora UID (identyfikatora użytkownika Androida) powoduje, że ogranicznik pamięci ignoruje egzekwowanie limitów we wszystkich procesach powiązanych z tym identyfikatorem. Możesz też przekazać wartość all (ignoruj wszystkie aplikacje) lub none (nie ignoruj żadnych aplikacji). Przekazanie wartości none zastępuje wszystkie poprzednie wywołania funkcji am memory-limiter ignore.

Jeśli polecisz ogranicznikowi pamięci zignorować identyfikator UID, nadal możesz ręcznie zastosować limit pamięci do procesu w aplikacji, wywołując funkcję am memory-limiter manual.

manual

Nakazuje systemowi nałożenie ograniczenia pamięci na proces o określonym identyfikatorze PID (Process ID). Ograniczenie pamięci jest podawane jako liczba całkowita MB. Na przykład podanie wartości 30 oznacza, że proces jest ograniczony do 30 MB pamięci. Przekazanie max usuwa wszystkie limity pamięci w tym procesie. Przekazanie wartości none usuwa wszystkie ręcznie ustawione limity procesu i przywraca domyślny limit systemu (jeśli taki istnieje).

status

Zwraca bieżący stan ogranicznika pamięci. Stan obejmuje limity pamięci nałożone na widoczne i niewidoczne procesy.

Prywatność

W Androidzie 17 wprowadziliśmy te zmiany, aby zwiększyć prywatność użytkowników.

Ochrona haseł jednorazowych SMS

Od Androida 17 rozszerzamy ochronę SMS-ów zawierających hasła jednorazowe.

W poprzednich wersjach Androida ta ochrona była skoncentrowana głównie na formacie SMS Retriever. Dostarczanie wiadomości zawierających hash SMS Retriever było opóźnione w przypadku większości aplikacji o 3 godziny. Niektóre aplikacje (np. domyślny program do obsługi SMS-ów) były jednak zwolnione z tego opóźnienia, podobnie jak aplikacja, która była właścicielem skrótu.

Począwszy od Androida 17, zabezpieczenie jest też stosowane w przypadku wiadomości w formacie WebOTP. Jeśli aplikacja ma uprawnienia do odczytywania SMS-ów, ale nie jest zamierzonym odbiorcą wiadomości WebOTP (co zostało ustalone na podstawie weryfikacji domeny), nie będzie mieć do niej dostępu przez 3 godziny od jej otrzymania. Ta zmiana ma na celu zwiększenie bezpieczeństwa użytkowników poprzez zapewnienie, że tylko aplikacje powiązane z domeną wymienioną w wiadomości mogą programowo odczytywać kod weryfikacyjny.

Podczas tego 3-godzinnego opóźnienia transmisja SMS_RECEIVED_ACTION jest wstrzymywana, a zapytania do bazy danych dostawcy SMS-ów są filtrowane. Wiadomość SMS jest dostępna w tych aplikacjach po upływie tego czasu. Ta zmiana dotyczy wszystkich aplikacji, niezależnie od poziomu interfejsu API, na który są kierowane.

Niektóre aplikacje, takie jak domyślna aplikacja asystenta SMS, aplikacje towarzyszące połączonym urządzeniom itp., są zwolnione z tego opóźnienia. Wszystkie aplikacje, które do wyodrębniania kodów OTP korzystają z odczytywania wiadomości SMS, powinny przejść na interfejsy SMS Retriever lub SMS User Consent, aby zapewnić dalsze działanie.

Bezpieczeństwo

Android 17 zawiera te ulepszenia zabezpieczeń urządzenia i aplikacji:

Harmonogram wycofywania atrybutu usesCleartextTraffic

W przyszłej wersji planujemy wycofać element usesCleartextTraffic. Aplikacje, które muszą nawiązywać połączenia nieszyfrowane (HTTP), powinny przejść na korzystanie z pliku konfiguracji zabezpieczeń sieciowych, który umożliwia określenie, z jakimi domenami aplikacja musi nawiązywać połączenia nieszyfrowane.

Pamiętaj, że pliki konfiguracji zabezpieczeń sieci są obsługiwane tylko na poziomach interfejsu API 24 i wyższych. Jeśli minimalny poziom interfejsu API Twojej aplikacji jest niższy niż 24, musisz wykonać oba te działania:

  • Ustaw atrybut usesCleartextTraffic na true
  • Używanie pliku konfiguracji sieci

Jeśli minimalny poziom interfejsu API aplikacji to 24 lub wyższy, możesz użyć pliku konfiguracji sieci i nie musisz ustawiać wartości usesCleartextTraffic.

Ograniczanie niejawnych uprawnień do identyfikatorów URI

Obecnie, jeśli aplikacja uruchamia intencję z URI, która ma działanie ACTION_SEND, ACTION_SEND_MULTIPLE lub ACTION_IMAGE_CAPTURE, system automatycznie przyznaje aplikacji docelowej uprawnienia do odczytu i zapisu URI. Od Androida 18 system nie będzie już automatycznie przyznawać tych uprawnień. Z tego powodu zalecamy, aby aplikacje wyraźnie przyznawały odpowiednie uprawnienia dotyczące identyfikatora URI, zamiast polegać na systemie.

Aby wykryć użycie tych intencji w aplikacji, użyj StrictModedetectImplicitUriPermissionGrant(), aby wywołać naruszenie:

Kotlin

val policy = StrictMode.VmPolicy.Builder()
    .detectImplicitUriPermissionGrant()
    .penaltyLog()
    .build()
StrictMode.setVmPolicy(policy)

Java

StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
    .detectImplicitUriPermissionGrant()
    .penaltyLog()
    .build();
StrictMode.setVmPolicy(policy);

Możesz też monitorować zarejestrowane wyjątki zawierające komunikat Please set the grant explicitly in the app, który pojawia się, gdy system niejawnie ustawia uprawnienia. Możesz monitorować te logi za pomocą tego adb polecenia:

adb logcat | grep "Please set the grant explicitly in the app"

Aby wyraźnie przyznać niezbędne uprawnienia, dodaj flagę FLAG_GRANT_READ_URI_PERMISSION do intencji ACTION_SENDACTION_SEND_MULTIPLE:

Kotlin

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

Java

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

Uwzględnij flagi FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION w przypadku intencji ACTION_IMAGE_CAPTURE:

Kotlin

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

Java

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

Limity magazynu kluczy poszczególnych aplikacji

Aplikacje powinny unikać tworzenia nadmiernej liczby kluczy w magazynie kluczy Androida, ponieważ jest to zasób współdzielony przez wszystkie aplikacje na urządzeniu. Od Androida 17 system egzekwuje limit liczby kluczy, które może posiadać aplikacja. Limit wynosi 50 tys. kluczy w przypadku aplikacji innych niż systemowe, które są kierowane na Androida 17 (poziom interfejsu API 37) lub nowszego, oraz 200 tys. kluczy w przypadku wszystkich innych aplikacji. Aplikacje systemowe mają limit 200 tys. kluczy niezależnie od poziomu interfejsu API, na który są kierowane.

Jeśli aplikacja spróbuje utworzyć klucze ponad limit, utworzenie nie powiedzie się i zostanie zgłoszony wyjątek a KeyStoreException. Ciąg komunikatu wyjątku zawiera informacje o limicie kluczy. Jeśli aplikacja wywoła getNumericErrorCode() w przypadku wyjątku, wartość zwracana zależy od poziomu interfejsu API, na który jest kierowana:

  • Aplikacje kierowane na Androida 17 (poziom interfejsu API 37) lub nowszego: getNumericErrorCode() zwraca nową wartość ERROR_TOO_MANY_KEYS.
  • Wszystkie inne aplikacje: getNumericErrorCode() zwraca ERROR_INCORRECT_USAGE.

Blokowanie ruchu sprzężenia zwrotnego profilu połączonego

Począwszy od Androida 17, ruch zwrotny między profilami nie jest już domyślnie dozwolony. Nie ma to wpływu na ruch zwrotny w ramach tego samego profilu. Ta zmiana dotyczy wszystkich aplikacji działających na Androidzie 17 lub nowszym, niezależnie od docelowego poziomu interfejsu API.

Wrażenia użytkowników i interfejs systemu

Android 17 zawiera te zmiany, które mają na celu zapewnienie bardziej spójnego i intuicyjnego środowiska użytkownika.

Przywracanie domyślnej widoczności IME po obróceniu

Od Androida 17, gdy konfiguracja urządzenia ulegnie zmianie (np. w wyniku obrócenia ekranu), a aplikacja nie obsłuży tej zmiany, poprzednia widoczność IME nie zostanie przywrócona.

Jeśli w aplikacji nastąpi zmiana konfiguracji, której nie obsługuje, a po zmianie klawiatura musi być widoczna, musisz wyraźnie o to poprosić. Możesz przesłać taką prośbę na jeden z tych sposobów:

  • Ustaw atrybut android:windowSoftInputMode na stateAlwaysVisible.
  • Programowo poproś o wyświetlenie klawiatury ekranowej w metodzie onCreate() aktywności lub dodaj metodę onConfigurationChanged().

Dane wejściowe od człowieka

Android 17 zawiera te zmiany, które wpływają na sposób, w jaki aplikacje korzystają z urządzeń wejściowych, takich jak klawiatury i touchpady.

Touchpady domyślnie dostarczają zdarzenia względne podczas przechwytywania wskaźnika

Od Androida 17, jeśli aplikacja zażąda przechwytywania wskaźnika za pomocą funkcji View.requestPointerCapture(), a użytkownik będzie korzystać z touchpada, system będzie rozpoznawać ruch wskaźnika i gesty przewijania wykonywane przez użytkownika i zgłaszać je do aplikacji w taki sam sposób jak ruchy wskaźnika i kółka myszy. W większości przypadków eliminuje to konieczność dodawania przez aplikacje obsługujące przechwycone myszy specjalnej logiki obsługi touchpadów. Więcej szczegółów znajdziesz w dokumentacji View.POINTER_CAPTURE_MODE_RELATIVE.

Wcześniej system nie próbował rozpoznawać gestów na touchpadzie, ale przekazywał do aplikacji surowe, bezwzględne lokalizacje palców w formacie podobnym do dotknięć ekranu dotykowego. Jeśli aplikacja nadal wymaga tych danych bezwzględnych, powinna wywoływać nową metodę View.requestPointerCapture(int) z parametrem View.POINTER_CAPTURE_MODE_ABSOLUTE.

Multimedia

W Androidzie 17 wprowadziliśmy te zmiany w działaniu multimediów.

Wzmacnianie zabezpieczeń dźwięku w tle

Od Androida 17 platforma audio wymusza ograniczenia dotyczące interakcji audio w tle, w tym odtwarzania dźwięku, żądań aktywności audio i interfejsów API zmiany głośności, aby mieć pewność, że te zmiany są inicjowane celowo przez użytkownika.

Jeśli aplikacja spróbuje wywołać interfejsy API audio, gdy nie znajduje się w prawidłowym cyklu życia, interfejsy API odtwarzania dźwięku i zmiany głośności zakończą działanie bez zgłaszania wyjątku ani wyświetlania komunikatu o błędzie. Interfejs API aktywności audio zwraca kod wyniku AUDIOFOCUS_REQUEST_FAILED.

Więcej informacji, w tym strategie ograniczania ryzyka, znajdziesz w artykule Zwiększanie bezpieczeństwa dźwięku w tle.

Łączność

W Androidzie 17 wprowadziliśmy te zmiany, aby zwiększyć łączność urządzeń.

Autonomiczne ponowne parowanie w przypadku utraty połączenia Bluetooth

Android 17 wprowadza autonomiczne ponowne parowanie, czyli ulepszenie na poziomie systemu, które automatycznie rozwiązuje problem utraty połączenia Bluetooth.

Wcześniej, jeśli połączenie zostało utracone, użytkownicy musieli ręcznie przejść do Ustawień, aby rozłączyć, a następnie ponownie połączyć urządzenie peryferyjne. Ta funkcja opiera się na ulepszeniach zabezpieczeń wprowadzonych w Androidzie 16, ponieważ umożliwia systemowi ponowne nawiązywanie połączeń w tle bez konieczności ręcznego przechodzenia przez użytkowników do Ustawień w celu rozłączenia i ponownego sparowania urządzeń peryferyjnych.

Większość aplikacji nie będzie wymagać zmian w kodzie, ale deweloperzy powinni pamiętać o tych zmianach w działaniu stosu Bluetooth:

  • Nowy kontekst parowania: ACTION_PAIRING_REQUEST zawiera teraz dodatkowy element EXTRA_PAIRING_CONTEXT, który umożliwia aplikacjom odróżnienie standardowego żądania parowania od próby ponownego parowania zainicjowanej przez autonomiczny system.
  • Warunkowe aktualizacje kluczy: istniejące klucze bezpieczeństwa zostaną zastąpione tylko wtedy, gdy ponowne parowanie zakończy się pomyślnie, a nowe połączenie osiągnie lub przekroczy poziom bezpieczeństwa poprzedniego połączenia.
  • Zmodyfikowany czas intencji: intencja ACTION_KEY_MISSING jest teraz wysyłana tylko wtedy, gdy nie uda się automatyczne ponowne parowanie. Dzięki temu w aplikacji nie trzeba będzie obsługiwać niepotrzebnych błędów, jeśli systemowi uda się odzyskać połączenie w tle.
  • Powiadomienie dla użytkownika: system zarządza ponownym parowaniem za pomocą nowych powiadomień i okien dialogowych interfejsu. Użytkownicy będą proszeni o potwierdzenie próby ponownego sparowania, aby mieć pewność, że wiedzą o ponownym połączeniu.

Producenci urządzeń peryferyjnych i deweloperzy aplikacji towarzyszących powinni sprawdzić, czy sprzęt i aplikacja prawidłowo obsługują przejścia między stanami połączenia. Aby przetestować to zachowanie, zasymuluj utratę połączenia zdalnego za pomocą jednej z tych metod:

  • Ręczne usuwanie informacji o parowaniu z urządzenia peryferyjnego
  • Ręcznie odłącz urządzenie: Ustawienia > Połączone urządzenia