Zmiany w działaniu: aplikacje kierowane na Androida 15 lub nowszego

Podobnie jak w poprzednich wersjach Android 15 obejmuje zmiany w działaniu, które mogą mieć wpływ na Twoją aplikację. Poniższe zmiany w działaniu dotyczą tylko aplikacji kierowanych na Androida 15 lub nowszego. Jeśli Twoja aplikacja jest kierowana na Androida 15 lub nowszego, w razie potrzeby zmodyfikuj aplikację, aby prawidłowo obsługiwała te zachowania.

Zapoznaj się też z listą zmian w działaniu, które wpływają na wszystkie aplikacje działające na Androidzie 15, niezależnie od targetSdkVersion w Twojej aplikacji.

Główna funkcja

Android 15 zmienia lub rozszerza różne podstawowe funkcje systemu Android.

Zmiany w usługach na pierwszym planie

Wprowadzamy te zmiany w usługach działających na pierwszym planie w Androidzie 15.

Zachowanie limitu czasu oczekiwania usługi działającej na pierwszym planie w ramach synchronizacji danych

Android 15 wprowadza nowy limit czasu oczekiwania w dataSync w przypadku kierowania na aplikacje Androida w wersji 15 lub nowszej. To zachowanie dotyczy również nowej wersji mediaProcessing typ usługi na pierwszym planie.

System pozwala na działanie usług aplikacji dataSync przez łącznie 6 godzin w ciągu 24 godzin, po czym system wywołuje metodę Metoda Service.onTimeout(int, int) (wprowadzona w Androidzie) 15) W tej chwili usługa ma kilka sekund na nawiązanie połączenia Service.stopSelf() W przypadku wywołania funkcji Service.onTimeout() makro usługa nie jest już uznawana za usługę na pierwszym planie. Jeśli usługa nie wywoła Service.stopSelf(), system zgłosi wyjątek wewnętrzny. jest rejestrowany w Logcat z następującym komunikatem:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"

Aby uniknąć problemów związanych ze zmianą działania, możesz wykonać co najmniej jedną z :

  1. Pozwól usłudze wdrożyć nową metodę Service.onTimeout(int, int). Gdy Twoja aplikacja otrzyma wywołanie zwrotne, wywołaj stopSelf() w za kilka sekund. (Jeśli nie zatrzymasz aplikacji od razu, system wygeneruje komunikat niepowodzenie).
  2. Upewnij się, że usługi dataSync w Twojej aplikacji nie działają przez więcej niż 6 godzin w dowolnym okresie 24 godzin (chyba że użytkownik wejdzie w interakcję z aplikacją, resetowanie minutnika).
  3. Uruchamiaj tylko usługi na pierwszym planie (dataSync) w wyniku bezpośredniego działania użytkownika interakcja; ponieważ aplikacja działa na pierwszym planie w momencie uruchomienia usługi, możesz korzystać z usługi przez pełne 6 godzin od momentu, gdy aplikacja działała w tle.
  4. Zamiast usługi na pierwszym planie dataSync użyj alternative API.

Jeśli usługi na pierwszym planie w Twojej aplikacji (dataSync) działały przez 6 godzin w ciągu ostatnich 6 godzin 24, nie możesz uruchomić innej usługi na pierwszym planie dataSync, chyba że użytkownik przeniosła aplikację na pierwszy plan (co powoduje zresetowanie licznika). Jeśli spróbujesz uruchomienia innej usługi na pierwszym planie dataSync, system zgłasza ForegroundServiceStartNotAllowedException. z komunikatem o błędzie, np. „Limit czasu dla usługi na pierwszym planie został już wyczerpany wpisz dataSync”.

Testowanie

Aby przetestować działanie aplikacji, możesz włączyć czasy oczekiwania na synchronizację danych, nawet jeśli aplikacja nie jest kierowana na Androida 15 (o ile aplikacja działa na Androidzie 15), urządzenia). Aby włączyć limity czasu, uruchom to polecenie adb:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

Możesz też dostosować ten czas, aby łatwiej sprawdzić, działa po osiągnięciu limitu. Aby ustawić nowy limit czasu, uruchom to polecenie adb:

adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds

Nowy typ usługi na pierwszym planie przetwarzania multimediów

W Androidzie 15 wprowadziliśmy nowy typ usługi na pierwszym planie: mediaProcessing. Ten jest odpowiedni do operacji takich jak transkodowanie plików multimedialnych. Dla: np. aplikacja do multimediów może pobrać plik audio i przekonwertować go przed odtworzeniem materiału w innym formacie. Możesz użyć elementu mediaProcessing na pierwszym planie by zapewnić ciągłość konwersji nawet wtedy, gdy aplikacja jest w tle.

System zezwala na działanie usług aplikacji mediaProcessing przez łącznie 6 godz. w okresie 24-godzinnym, po czym system wywołuje metodę Metoda Service.onTimeout(int, int) (wprowadzona w Androidzie) 15) W tej chwili usługa ma kilka sekund na nawiązanie połączenia Service.stopSelf() Jeśli usługa nie wywoła Service.stopSelf(), system zgłosi wyjątek wewnętrzny. jest rejestrowany w Logcat z następującym komunikatem:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"

Aby uniknąć wyjątku, wykonaj jedną z tych czynności:

  1. Pozwól usłudze wdrożyć nową metodę Service.onTimeout(int, int). Gdy Twoja aplikacja otrzyma wywołanie zwrotne, wywołaj stopSelf() w za kilka sekund. (Jeśli nie zatrzymasz aplikacji od razu, system wygeneruje komunikat niepowodzenie).
  2. Upewnij się, że usługi mediaProcessing w Twojej aplikacji nie działają dłużej niż łącznie 6 godzin w dowolnym okresie 24 godzin (chyba że użytkownik wejdzie w interakcję z aplikacją, resetowanie minutnika).
  3. Uruchamiaj tylko usługi na pierwszym planie (mediaProcessing) w wyniku bezpośredniego działania użytkownika interakcja; ponieważ aplikacja działa na pierwszym planie w momencie uruchomienia usługi, możesz korzystać z usługi przez pełne 6 godzin od momentu, gdy aplikacja działała w tle.
  4. Zamiast usługi na pierwszym planie mediaProcessing użyj alternatywnej metody API, na przykład WorkManager.

Jeśli usługi na pierwszym planie typu mediaProcessing w Twojej aplikacji były uruchomione przez 6 godzin w ostatnich 24, nie możesz uruchomić innej usługi na pierwszym planie mediaProcessing, chyba że użytkownik przeniósł aplikację na pierwszy plan (co powoduje zresetowanie licznika). Jeśli próbuje uruchomić inną usługę na pierwszym planie mediaProcessing, system zgłasza ForegroundServiceStartNotAllowedException. z komunikatem o błędzie, np. „Limit czasu dla usługi na pierwszym planie został już wyczerpany type MediaProcessing”.

Więcej informacji o typie usługi mediaProcessing znajdziesz w artykule Zmiany w Typy usług działających na pierwszym planie w Androidzie 15: przetwarzanie multimediów.

Testowanie

Aby przetestować działanie aplikacji, możesz włączyć limity czasu przetwarzania multimediów, nawet jeśli aplikacja nie jest kierowana na Androida 15 (o ile działa na na urządzeniu z Androidem 15). Aby włączyć limity czasu, uruchom to polecenie adb:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

Możesz też dostosować ten czas, aby łatwiej sprawdzić, działa po osiągnięciu limitu. Aby ustawić nowy limit czasu, uruchom to polecenie adb:

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds

Ograniczenia dotyczące BOOT_COMPLETED odbiorników uruchamiających usługi na pierwszym planie

Wprowadziliśmy nowe ograniczenia dotyczące odbiorników BOOT_COMPLETED usług działających na pierwszym planie. Odbiorcy BOOT_COMPLETED nie mogą uruchamiać modułu te typy usług na pierwszym planie:

Jeśli odbiornik BOOT_COMPLETED próbuje uruchomić którykolwiek z tych typów działania na pierwszym planie usług, system wywołuje ForegroundServiceStartNotAllowedException.

Testowanie

Aby przetestować działanie aplikacji, możesz włączyć nowe ograniczenia, nawet jeśli aplikacja nie jest kierowana na Androida 15 (o ile działa na Androidzie 15), urządzenia). Uruchom to polecenie adb:

adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name

Aby wysłać komunikat typu BOOT_COMPLETED bez ponownego uruchamiania urządzenia: uruchom to polecenie adb:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name

Ograniczenia dotyczące uruchamiania usług na pierwszym planie, gdy aplikacja ma uprawnienie SYSTEM_ALERT_WINDOW

Wcześniej, jeśli jakaś aplikacja miała uprawnienie SYSTEM_ALERT_WINDOW, można było ją uruchomić. z usługi na pierwszym planie, nawet jeśli aplikacja działała obecnie w tle (jak omawiane w artykule wykluczenia z ograniczeń uruchamiania w tle).

Jeśli aplikacja jest kierowana na Androida 15, wykluczenie jest teraz bardziej precyzyjne. Aplikacja wymaga teraz mieć uprawnienia SYSTEM_ALERT_WINDOW oraz także mieć widoczną nakładkę okno. Oznacza to, że aplikacja musi najpierw uruchomić Okno TYPE_APPLICATION_OVERLAY i okno musi być widoczna przed uruchomieniem usługi na pierwszym planie.

Jeśli aplikacja próbuje uruchomić usługę działającej na pierwszym planie w tle bez spełnia te nowe wymagania (i nie jest objęty żadnym innym wyjątkiem), system zgłasza ForegroundServiceStartNotAllowedException.

Jeśli Twoja aplikacja deklaruje uprawnienia SYSTEM_ALERT_WINDOW i uruchamia usługi na pierwszym planie w tle, może to mieć wpływ . Jeśli Twoja aplikacja otrzymuje ForegroundServiceStartNotAllowedException, sprawdź, kolejność działania aplikacji i upewnij się, że ma ona już aktywną przed próbą uruchomienia usługi na pierwszym planie z poziomu w tle. Możesz sprawdzić, czy okno nakładki jest obecnie widoczne , dzwoniąc pod numer View.getWindowVisibility(), lub może zastąpić wartość View.onWindowVisibilityChanged() aby otrzymywać powiadomienia o zmianach widoczności.

Testowanie

Aby przetestować działanie aplikacji, możesz włączyć nowe ograniczenia, nawet jeśli aplikacja nie jest kierowana na Androida 15 (o ile działa na Androidzie 15), urządzenia). Aby włączyć nowe ograniczenia dotyczące uruchamiania usług na pierwszym planie w tle uruchom to polecenie adb:

adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name

Zmiany dotyczące tego, kiedy aplikacje mogą modyfikować globalny stan trybu Nie przeszkadzać

以 Android 15 为目标平台的应用无法再更改设备上的全局状态或勿扰 (DND) 政策(通过修改用户设置或关闭 DND 模式)。相反,应用必须提供一个 AutomaticZenRule,系统会将后者合并到一个具有现有最严格的政策胜出方案的全局政策中。调用之前影响全局状态的现有 API(setInterruptionFiltersetNotificationPolicy)会导致创建或更新隐式 AutomaticZenRule,该 AutomaticZenRule 根据这些 API 调用的调用周期而开启或关闭。

请注意,只有在应用调用 setInterruptionFilter(INTERRUPTION_FILTER_ALL) 且预期调用会停用之前由其所有者激活的 AutomaticZenRule 时,此变更才会影响可观察的行为。

Zmiany w interfejsie OpenJDK API

Android 15 kontynuuje pracę nad odświeżaniem podstawowych bibliotek Androida, aby zapewnić zgodność z funkcjami dostępnymi w najnowszych wersjach OpenJDK LTS.

Niektóre z tych zmian mogą wpłynąć na zgodność aplikacji w kierowaniu na aplikacje Android 15 (poziom API 35):

  • Zmiany w interfejsach API formatowania ciągów znaków: weryfikacja indeksu argumentu, flag, szerokość i precyzja są teraz bardziej rygorystyczne przy korzystaniu z funkcji Interfejsy API String.format() i Formatter.format():

    Na przykład następujący wyjątek jest zgłaszany, gdy indeks argumentów wynosi 0 (%0 w ciągu formatu):

    IllegalFormatArgumentIndexException: Illegal format argument index = 0
    

    W tym przypadku problem można rozwiązać, stosując indeks argumentów równy 1 (%1 w ciągu formatu).

  • Zmiany w typie komponentu Arrays.asList(...).toArray(): podczas używania funkcji Arrays.asList(...).toArray(), typ komponentu tablicy wynikowej to jest to teraz Object, a nie typ elementów tablicy bazowej. Dlatego ten kod zwraca ClassCastException:

    String[] elements = (String[]) Arrays.asList("one", "two").toArray();
    

    Aby w tym przypadku zachować String jako typ komponentu w wyniku tablica, możesz zamiast tego użyć Collection.toArray(Object[]):

    String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
    
  • Zmiany w obsłudze kodu języka: podczas korzystania z interfejsu API Locale kodów językowych w językach hebrajskim, jidysz i indonezyjskim nie są już konwertowane na ich przestarzałe formy (hebrajski: iw, jidysz: ji i indonezyjski: in). Aby określić kod języka dla jednego z tych regionów, użyj tych kodów według normy ISO 639-1 (hebrajski: he, jidysz: yi i indonezyjski: id).

  • Zmiany w losowych ciągach int: po zmianach wprowadzonych w https://bugs.openjdk.org/browse/JDK-8301574 Metody Random.ints() zwracają teraz inną sekwencję liczb niż metody Random.nextInt():

    Zwykle ta zmiana nie powinna powodować rozbijania aplikacji, ale nie powinien oczekiwać sekwencji wygenerowanej z metod Random.ints() do: Random.nextInt().

Nowy interfejs API SequencedCollection może wpływać na zgodność Twojej aplikacji po zaktualizowaniu compileSdk w konfiguracji kompilacji aplikacji, aby używać Android 15 (poziom interfejsu API 35):

  • Kolizja z MutableList.removeFirst() oraz Funkcje rozszerzeń MutableList.removeLast() w kotlin-stdlib

    Typ List w Javie jest zmapowany na typ MutableList w Kotlin. Ponieważ interfejsy API List.removeFirst() i List.removeLast() zostały wprowadzone w Androidzie 15 (poziom API 35) – kompilatorze Kotlin przekształca statycznie wywołania funkcji, na przykład list.removeFirst(), na nowych interfejsów API List zamiast funkcji rozszerzeń w kotlin-stdlib.

    Jeśli aplikacja jest ponownie skompilowana z ustawieniem compileSdk ustawionym na 35, a minSdk z wartością 34 lub niższy, a potem aplikacja działa na Androidzie 14 lub starszym, w środowisku wykonawczym jest zgłaszany błąd:

    java.lang.NoSuchMethodError: No virtual method
    removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
    

    Istniejąca opcja lintowania NewApi we wtyczce Androida do obsługi Gradle może je wychwytywać nowych zastosowań interfejsu API.

    ./gradlew lint
    
    MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi]
          list.removeFirst()
    

    Aby naprawić błędy wyjątku i lintowania w środowisku wykonawczym, funkcje removeFirst() i Wywołania funkcji removeLast() można zastąpić wyrażeniami removeAt(0) i removeAt(list.lastIndex) w aplikacji Kotlin. Jeśli używasz Android Studio Biedronka | 2024.1.3 lub nowszej, .

    Jeśli opcja lintowania została wyłączona, rozważ usunięcie interfejsów @SuppressLint("NewApi") i lintOptions { disable 'NewApi' }.

  • Kolizja z innymi metodami w Javie

    Do istniejących typów zostały dodane nowe metody, na przykład List i Deque. Te nowe metody mogą nie być zgodne w innych interfejsach z użyciem metod o tej samej nazwie i typach argumentów i zajęcia. W przypadku kolizji podpisów metod z kompilator javac zwraca błąd w czasie kompilacji. Dla: przykład:

    Przykładowy błąd 1:

    javac MyList.java
    
    MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List
      public void removeLast() {
                  ^
      return type void is not compatible with Object
      where E is a type-variable:
        E extends Object declared in interface List
    

    Przykładowy błąd 2:

    javac MyList.java
    
    MyList.java:7: error: types Deque<Object> and List<Object> are incompatible;
    public class MyList implements  List<Object>, Deque<Object> {
      both define reversed(), but with unrelated return types
    1 error
    

    Przykładowy błąd 3:

    javac MyList.java
    
    MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible;
    public static class MyList implements List<Object>, MyInterface<Object> {
      class MyList inherits unrelated defaults for getFirst() from types List and MyInterface
      where E#1,E#2 are type-variables:
        E#1 extends Object declared in interface List
        E#2 extends Object declared in interface MyInterface
    1 error
    

    Aby naprawić te błędy kompilacji, klasa implementująca te interfejsy powinna zastąpić metodę zgodnym typem zwracanym. Na przykład:

    @Override
    public Object getFirst() {
        return List.super.getLast();
    }
    

Zabezpieczenia

Android 15 zawiera zmiany, które promują bezpieczeństwo systemu, aby chronić aplikacje i użytkowników przed złośliwymi aplikacjami.

Uruchomienie bezpiecznej aktywności w tle

Android 15 chroni użytkowników przed złośliwymi aplikacjami i daje im większą kontrolę nad ich urządzeniach, dodając zmiany, które uniemożliwiają złośliwym aplikacjom działającym w tle ujawnianie innych aplikacji, podnoszenie ich przywilejów i nadużywanie interakcji użytkownika. Uruchamianie aktywności w tle jest ograniczone od Android 10 (poziom API 29).

Blokuj uruchamianie aktywności aplikacjom, które nie pasują do górnego identyfikatora UID w stosie.

Złośliwe aplikacje mogą uruchomić inną aplikację w ramach tego samego zadania, a następnie nakładają się na siebie i tworzą wrażenie, że jest to ta aplikacja. To „zadanie porwanie” atak omija obecne ograniczenia uruchamiania w tle, ponieważ występuje w ramach tego samego widocznego zadania. Aby ograniczyć to ryzyko, Android 15 dodaje flaga blokująca uruchamianie aplikacji, które nie są zgodne z górnym identyfikatorem UID w stosie aktywności. Aby wyrazić zgodę na wszystkie aktywności w aplikacji, zaktualizuj allowCrossUidActivitySwitchFromBelow w pliku AndroidManifest.xml aplikacji:

<application android:allowCrossUidActivitySwitchFromBelow="false" >

Nowe zabezpieczenia są aktywne, jeśli są spełnione wszystkie te warunki:

  • Aplikacja, w której wprowadzana jest na rynek, jest kierowana na Androida 15.
  • Aplikacja u góry stosu zadań jest kierowana na Androida 15.
  • Każda widoczna aktywność została objęta nowymi zabezpieczeniami

Jeśli zabezpieczenia są włączone, aplikacje mogą wrócić do ekranu głównego, jako ostatnia widoczna aplikacja, jeśli ukończy ona swoje zadanie.

Inne zmiany

Oprócz ograniczenia dopasowania identyfikatorów UID te inne zmiany również uwzględniono:

  • Zmień PendingIntent twórców na blokowanie uruchamiania aktywności w tle przez domyślny. Zapobiega to przypadkowemu utworzeniu przez aplikacje PendingIntent, które mogą być wykorzystywane przez hakerów.
  • Nie przenoś aplikacji na pierwszy plan, chyba że nadawca PendingIntent na to zezwala. Ta zmiana ma na celu zapobieganie wykorzystywaniu uruchamianie działań w tle. Domyślnie aplikacje nie są może przenieść stos zadań na pierwszy plan, chyba że twórca wyrazi zgodę uprawnienia do uruchamiania aktywności w tle lub nadawca ma aktywność w tle uprawnienia do uruchamiania.
  • Określ, w jaki sposób główna aktywność stosu zadań może wykonać zadanie. Jeśli które kończy zadanie, Android wróci do tego, które zostało jako ostatnia aktywność. Ponadto, jeśli aktywność inna niż główna zakończy swoje zadanie, Android powrót do ekranu głównego; Nie zablokuje ono zakończenia reklamy działania.
  • Zapobiegaj uruchamianiu dowolnych działań z innych aplikacji we własnym zakresie zadanie. Ta zmiana zapobiega wyłudzaniu informacji przez złośliwe aplikacje, tworząc aktywności, które wyglądają jak z innych aplikacji.
  • Nie zezwalaj na uwzględnianie niewidocznych okien w aktywności w tle . Pomaga to zapobiegać wykorzystywaniu działania w tle przez złośliwe aplikacje aby wyświetlać użytkownikom niechciane lub szkodliwe treści.

Bezpieczniejsze intencje

Android 15 引入了新的安全措施,可让 intent 更加安全且更安全 稳健。这些变更旨在防范潜在的漏洞和 可能会被恶意应用利用的 intent 滥用。有两个主要的 Android 15 中对 intent 安全性的改进:

  • 匹配目标 intent 过滤器:针对特定组件的 intent 准确匹配目标的 intent 过滤器规范。如果您发送 intent 来启动另一个应用的 activity,则目标 intent 组件需要 与接收 activity 声明的 intent 过滤器保持一致。
  • intent 必须具有操作:没有操作的 intent 将不再匹配 任何 intent 过滤器。也就是说,用于启动 activity 或 服务都必须有明确定义的操作。
  • 待处理 intent:待处理 intent 的创建者被视为封装 intent 的发送者,而非待处理 intent 的发送者 意图

Kotlin


fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        .detectUnsafeIntentLaunch()
        .build()
    )
}

Java


public void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
            .detectUnsafeIntentLaunch()
            .build());
}

Wygoda użytkowania i interfejs systemu

W Androidzie 15 wprowadzono kilka zmian, które mają zapewnić użytkownikom bardziej spójne i intuicyjne wrażenia.

Zmiany wstawienia okien

W Androidzie 15 wprowadzono 2 zmiany związane z wstawianiem okien: ustawienie od krawędzi do krawędzi jest domyślnie wymuszane w obszarze od krawędzi do krawędzi oraz zmiany w konfiguracji, takie jak domyślna konfiguracja pasków systemowych.

Egzekwowanie zasad od krawędzi do krawędzi

在搭载 Android 15 的设备上,应用会默认采用全屏 以 Android 15(API 级别 35)为目标平台。

<ph type="x-smartling-placeholder">
</ph>
一款以 Android 14 为目标平台且在 Android 设备上未处于无边框的应用 Android 15 设备。


<ph type="x-smartling-placeholder">
</ph>
一款以 Android 15(API 级别 35)为目标平台且采用无边框的应用 在 Android 15 设备上。此应用主要使用 Material 3 Compose 组件 自动应用边衬区此屏幕不会受到 Android 15 全屏强制执行。

这是一项可能会对应用的界面产生负面影响的破坏性更改。通过 更改会影响以下界面区域:

  • 手势手柄导航栏
    • 默认透明。
    • 底部偏移量已停用,因此内容绘制在系统导航栏后面 栏。
    • setNavigationBarColorR.attr#navigationBarColor 已弃用,不会影响手势导航。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced不会对 手势导航。
  • “三按钮”导航
    • 默认不透明度设为 80%,颜色可能与窗口一致 背景。
    • 底部偏移值已停用,因此内容绘制在系统导航栏后面 除非应用了边衬区。
    • setNavigationBarColorR.attr#navigationBarColor 默认设置为与窗口背景匹配。窗口背景 必须是颜色可绘制对象,才能应用此默认值。此 API 是 但会继续影响“三按钮”导航。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced 默认为 true,这会添加一个 “三按钮”导航模式显示 80% 不透明的背景。
  • 状态栏
    • 默认透明。
    • 顶部偏移量已停用,因此除非 边衬区。
    • setStatusBarColorR.attr#statusBarColor 已废弃,对 Android 15 没有任何影响。
    • setStatusBarContrastEnforcedR.attr#statusBarContrastEnforced 已弃用,但仍具有 对 Android 15 的影响。
  • 刘海屏
    • layoutInDisplayCutoutMode 的非浮动窗口必须是 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSSHORT_EDGESNEVER和 系统会将 DEFAULT 解读为 ALWAYS,这样用户就不会看到黑色图标 长条形尺寸,显示为无边框。

以下示例展示了定位前和定位后的应用 Android 15(API 级别 35)以及应用边衬区之前和之后。

<ph type="x-smartling-placeholder">
</ph>
一款以 Android 14 为目标平台且在 Android 设备上未处于无边框的应用 Android 15 设备。
。 <ph type="x-smartling-placeholder">
</ph>
一款以 Android 15(API 级别 35)为目标平台且采用无边框的应用 在 Android 15 设备上。不过,许多元素 栏、“三按钮”导航栏或刘海屏(由于 Android 15) 全屏强制措施。隐藏界面包含 Material 2 顶部应用栏、悬浮操作按钮和列表项。
。 <ph type="x-smartling-placeholder">
</ph>
如果应用以 Android 15(API 级别 35)为目标平台, Android 15 设备并应用边衬区,这样界面就不会 已隐藏。
检查应用是否已采用全屏的检查步骤

如果您的应用已经采用无边框且应用了边衬区, 基本未受影响,但下列情况除外。但即使您认为 您不会受到影响,但我们建议您测试自己的应用。

  • 您的非浮动窗口(例如 Activity)使用 SHORT_EDGESNEVERDEFAULT,而不是 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS。如果您的应用在启动时崩溃 可能是启动画面所致您可以升级核心 初始屏幕依赖项更改为 1.2.0-alpha01 或更高版本,或者设置 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
  • 可能会有流量较低的屏幕显示被遮挡的界面。验证这些 访问较少的屏幕也不会显示被遮挡的界面。流量较低的屏幕包括: <ph type="x-smartling-placeholder">
      </ph>
    • 初始配置或登录屏幕
    • “设置”页面
如何检查应用尚未实现无边框

如果您的应用还没有全面屏,那么您很可能会受到影响。在 除了针对已经采用无边框的应用的情况之外, 请考虑以下事项:

  • 如果您的应用使用 Material 3 组件 ( androidx.compose.material3),例如 TopAppBarBottomAppBarNavigationBar,那么这些组件可能 会受到影响,因为它们会自动处理边衬区。
  • 如果您的应用使用 Material 2 组件 ( androidx.compose.material),那么这些组件 不会自动处理边衬区。不过,您可以使用边衬区 并手动应用这些设置在 androidx.compose.material 1.6.0 中 然后使用 windowInsets 参数手动应用边衬区 BottomAppBarTopAppBarBottomNavigationNavigationRail。 同样,对以下内容使用 contentWindowInsets 形参: Scaffold
  • 如果您的应用使用视图和 Material 组件 (com.google.android.material),大多数基于 View 的 Material 如 BottomNavigationViewBottomAppBarNavigationRailViewNavigationView,处理边衬区,不需要 额外工作。但是,您需要将 android:fitsSystemWindows="true" 如果使用 AppBarLayout,则会发生此错误。
  • 对于自定义可组合项,请手动将边衬区作为内边距应用。如果您的 内容位于 Scaffold 内,因此您可以使用 Scaffold 来使用边衬区 内边距值。否则,使用 WindowInsets
  • 如果您的应用使用的是视图和 BottomSheetSideSheet 或自定义 使用 ViewCompat.setOnApplyWindowInsetsListener。对于 RecyclerView,使用此监听器应用内边距,同时添加 clipToPadding="false"
检查应用是否必须提供自定义后台保护的注意事项

如果您的应用必须为“三按钮”导航或 状态栏,则应用应将可组合项或视图放在系统栏后面 使用 WindowInsets.Type#tappableElement() 获取三按钮 导航栏高度或 WindowInsets.Type#statusBars

其他无边框资源

请参阅无边框视图无边框 Compose 了解应用边衬区的其他注意事项。

已弃用的 API

以下 API 现已弃用:

Stabilna konfiguracja

Jeśli Twoja aplikacja jest kierowana na Androida 15 (poziom interfejsu API 35) lub nowszego, Configuration nie nie uwzględnia słupków systemowych. Jeśli użyjesz rozmiaru ekranu w Configuration do obliczania układu, zastąp ją lepszym alternatywne opcje, takie jak odpowiednie ViewGroup, WindowInsets lub WindowMetricsCalculator w zależności od potrzeb.

Interfejs Configuration jest dostępny od wersji API 1. Zazwyczaj jest pozyskiwany Activity.onConfigurationChanged Dostarcza informacji takich jak gęstość okien, orientacja i rozmiary. Ważna cecha określająca rozmiary okien zwracanych przez funkcję Configuration oznacza, że wcześniej były wykluczone słupki systemowe.

Rozmiar konfiguracji jest zwykle używany do wyboru zasobów, na przykład /res/layout-h500dp. Jest to nadal prawidłowy przypadek użycia. Jednak użycie go obliczanie układu zawsze jest odradzane. W takim przypadku z dala od siebie. Wyrażenie Configuration należy zastąpić czymś w zależności od konkretnego przypadku użycia.

Jeśli używasz go do obliczenia układu, użyj odpowiedniej wartości ViewGroup, np. CoordinatorLayout lub ConstraintLayout. Jeśli używasz go do określania wysokości, na pasku nawigacyjnym systemu użyj funkcji WindowInsets. Jeśli chcesz poznać aktualny rozmiar okna aplikacji, użyj computeCurrentWindowMetrics.

Poniższa lista zawiera opis pól, na które wpływa ta zmiana:

AtrybuteleTextHeight ma domyślną wartość true (prawda)

W przypadku aplikacji kierowanych na Androida 15 atrybut elegantTextHeight TextView ma domyślnie wartość true, co powoduje zastąpienie domyślnie używanej domyślnie kompaktowej czcionki pewnymi skryptami o dużych danych pionowych inną, która jest znacznie bardziej czytelna. Wprowadzono kompaktową czcionkę, aby zapobiec naruszaniu układów. Android 13 (poziom interfejsu API 33) zapobiega wielu z tych problemów, umożliwiając układowi tekstu rozciąganie wysokości w pionie za pomocą atrybutu fallbackLineSpacing.

W Androidzie 15 kompaktowa czcionka pozostaje w systemie, więc aplikacja może ustawić elegantTextHeight na false, aby uzyskać takie samo działanie jak wcześniej, ale prawdopodobnie nie będzie obsługiwana w kolejnych wersjach. Jeśli Twoja aplikacja obsługuje te skrypty: arabski, laotański, birmański, tamilski, gudżarati, kannada, malajalam, orija, telugu lub tajski, przetestuj ją, ustawiając w polu elegantTextHeight opcję true.

Zachowanie elegantTextHeight w przypadku aplikacji kierowanych na Androida 14 (poziom API 34) i starsze.
elegantTextHeight w przypadku aplikacji kierowanych na Androida 15.

Zmiany szerokości obiektu TextView w przypadku złożonych kształtów liter

在之前的 Android 版本中,某些手写字体或语言会 复杂形状时,可能会在上一个或下一个字符的区域绘制字母。 在某些情况下,此类字母会在开头或结尾处截断。 从 Android 15 开始,TextView 会分配宽度以绘制足够的空间 并允许应用请求在左侧填充额外的内边距, 请勿裁剪。

由于此更改会影响 TextView 确定宽度的方式,因此 TextView 如果应用以 Android 15 或更高版本为目标平台,则默认分配更多宽度。您可以 通过对以下对象调用 setUseBoundsForWidth API 来启用或停用此行为: TextView

由于添加左侧内边距可能会导致现有布局出现错位, 默认情况下,系统不会添加内边距,即使是以 Android 15 或更高版本为目标平台的应用也是如此。 不过,您可以通过调用 setShiftDrawingOffsetForStartOverhang

以下示例展示了这些更改可如何改进某些客户的文本布局 字体和语言。

以手写字体显示英文文本的标准布局。其中一些 会截断字母。对应的 XML 文件如下:

<TextView
    android:fontFamily="cursive"
    android:text="java" />
相同英文文本的布局,提供额外宽度和 内边距。对应的 XML 文件如下:

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />
泰语文本的标准布局。部分字母被截断了。 对应的 XML 文件如下:

<TextView
    android:text="คอมพิวเตอร์" />
相同的泰语文本的布局,具有额外的宽度和 内边距。对应的 XML 文件如下:

<TextView
    android:text="คอมพิวเตอร์"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />

Domyślna wysokość wiersza z uwzględnieniem języka dla interfejsu EditText

在以前的 Android 版本中,文本布局拉伸了文本的高度,使其适应与当前语言区域匹配的字体的行高。例如,如果内容是日语,由于日语字体的行高比拉丁字体的行高略大,因此文本的高度就略大了。不过,尽管行高存在这些差异,但无论使用何种语言区域,EditText 元素的大小都是一致的,如下图所示:

三个表示 EditText 元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText 的高度相同,即使这两种语言的行高不同。

对于以 Android 15 为目标平台的应用,系统现在会为 EditText 预留最小行高,以匹配指定语言区域的参考字体,如下图所示:

三个表示 EditText 元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText 的高度现在包含空间,可适应这些语言字体的默认行高。

如果需要,您的应用可以通过将 useLocalePreferredLineHeightForMinimum 属性设置为 false 来恢复之前的行为,并且可以通过 Kotlin 和 Java 中的 setMinimumFontMetrics API 设置自定义最小行业指标。

Aparat i multimedia

Android 15 wprowadza te zmiany w działaniu aparatu i multimediów w aplikacjach kierowanych na Androida 15 lub nowszego.

Ograniczenia dotyczące żądania skupienia się na dźwięku

Aplikacje kierowane na Androida 15 muszą być najlepszą aplikacją lub obsługiwać usługę na pierwszym planie, aby żądać aktywności audio. Jeśli aplikacja próbuje poprosić o koncentrację, gdy nie spełnia jednego z tych wymagań, wywołanie zwraca AUDIOFOCUS_REQUEST_FAILED.

Więcej informacji o aktywności audio znajdziesz w artykule Zarządzanie aktywnością audio.

Zaktualizowano ograniczenia spoza pakietu SDK

Android 15 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.

If your app does not target Android 15, some of these changes might not immediately affect you. However, while it's possible for your app to access some non-SDK interfaces depending on your app's target API level, using any non-SDK method or field always carries a high risk of breaking your app.

If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you can't find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.

Więcej informacji o zmianach w tej wersji Androida znajdziesz w artykule Aktualizacje ograniczeń interfejsu innego niż SDK na Androidzie 15. Więcej informacji o interfejsach innych niż SDK znajdziesz w tym artykule.