Zmiany zachowania: aplikacje kierowane na Androida 16 lub nowszego

Podobnie jak w przypadku poprzednich wersji, Android 16 wprowadza zmiany w działaniu, które mogą mieć wpływ na Twoją aplikację. Poniższe zmiany w działaniu dotyczą wyłącznie aplikacji kierowanych na Androida 16 lub nowszego. Jeśli Twoja aplikacja jest kierowana na Androida 16 lub nowszego, w razie potrzeby zmodyfikuj ją, aby obsługiwała te funkcje.

Zapoznaj się też z listą zmian w działaniu, które dotyczą wszystkich aplikacji działających na Androidzie 16, niezależnie od tego, czy Twoja aplikacja ma targetSdkVersion.

Wrażenia użytkownika i interfejs systemu

Android 16 (poziom interfejsu API 36) zawiera te zmiany, które mają na celu zapewnienie bardziej spójnego i intuicyjnego interfejsu.

Odrzucenie wyświetlania bez ramki

Android 15 wymusza wyświetlanie bez ramki w przypadku aplikacji kierowanych na Androida 15 (poziom API 35), ale Twoja aplikacja może z tego zrezygnować, ustawiając wartość R.attr#windowOptOutEdgeToEdgeEnforcement na true. W przypadku aplikacji kierowanych na Androida 16 (poziom interfejsu API 36) interfejs R.attr#windowOptOutEdgeToEdgeEnforcement został wycofany i wyłączony, a Twoja aplikacja nie może zrezygnować z wyświetlania bez ramki.

  • Jeśli Twoja aplikacja jest kierowana na Androida 16 (API na poziomie 36) i działa na urządzeniu z Androidem 15, R.attr#windowOptOutEdgeToEdgeEnforcementnadal działa.
  • Jeśli Twoja aplikacja jest kierowana na Androida 16 (poziom API 36) i działa na urządzeniu z Androidem 16, R.attr#windowOptOutEdgeToEdgeEnforcement jest wyłączona.

Aby przetestować Androida 16 w wersji beta 3, sprawdź, czy Twoja aplikacja obsługuje wyświetlacz od krawędzi do krawędzi, i usuń wszelkie odwołania do R.attr#windowOptOutEdgeToEdgeEnforcement, aby aplikacja obsługiwała też wyświetlacz od krawędzi do krawędzi na urządzeniu z Androidem 15. Aby obsługiwać krawędzie, zapoznaj się z informacjami w sekcji KompozycjaWidok.

Wymagane przeprowadzenie migracji lub rezygnacja z funkcji przewidywania wstecz.

For apps targeting Android 16 (API level 36) or higher and running on an Android 16 or higher device, the predictive back system animations (back-to-home, cross-task, and cross-activity) are enabled by default. Additionally, onBackPressed is not called and KeyEvent.KEYCODE_BACK is not dispatched anymore.

If your app intercepts the back event and you haven't migrated to predictive back yet, update your app to use supported back navigation APIs. or temporarily opt out by setting the android:enableOnBackInvokedCallback attribute to false in the <application> or <activity> tag of your app's AndroidManifest.xml file.

The predictive back-to-home animation.
The predictive cross-activity animation.
The predictive cross-task animation.

Wycofanie i wyłączenie interfejsów API czcionek elegant

Aplikacje kierowane na Androida 15 (poziom API 35) mają atrybut elegantTextHeight TextView ustawiony domyślnie na true, co zastępuje czcionkę kompaktową czcionką znacznie łatwiejszą do odczytania. Możesz to zmienić, ustawiając atrybut elegantTextHeight na false.

W Androidzie 16 atrybut elegantTextHeight jest przestarzały. Gdy Twoja aplikacja będzie kierowana na Androida 16, atrybut ten zostanie zignorowany. Czcionki interfejsu kontrolowane przez te interfejsy API zostaną wycofane, dlatego należy dostosować wszelkie układy, aby zapewnić spójne i przyszłe renderowanie tekstu w języku arabskim, laotam, tamilskim, gudżarati, kannada, malajalam, orija, telugu i tajskim.

elegantTextHeightzachowanie w przypadku aplikacji kierowanych na Androida 14 (poziom API 34) lub starszego albo w przypadku aplikacji kierowanych na Androida 15 (poziom API 35), które zastąpiły domyślne ustawienie, ustawiając atrybut elegantTextHeight na false.
elegantTextHeight zachowanie w przypadku aplikacji kierowanych na Androida 16 lub na Androida 15 (poziom API 35), które nie zastąpiły wartości domyślnej przez ustawienie atrybutu elegantTextHeight na false.

Główna funkcja

Android 16 (poziom interfejsu API 36) zawiera te zmiany, które modyfikują lub rozszerzają różne podstawowe funkcje systemu Android.

Optymalizacja harmonogramu pracy z ustaloną stawką

Prior to targeting Android 16, when scheduleAtFixedRate missed a task execution due to being outside a valid process lifecycle, all missed executions immediately execute when the app returns to a valid lifecycle.

When targeting Android 16, at most one missed execution of scheduleAtFixedRate is immediately executed when the app returns to a valid lifecycle. This behavior change is expected to improve app performance. Test this behavior in your app to check if your app is impacted. You can also test by using the app compatibility framework and enabling the STPE_SKIP_MULTIPLE_MISSED_PERIODIC_TASKS compat flag.

Formaty urządzeń

Android 16 (poziom interfejsu API 36) wprowadza te zmiany w aplikacjach wyświetlanych na urządzeniach z dużym ekranem.

Układy adaptacyjne

With Android apps now running on a variety of devices (such as phones, tablets, foldables, desktops, cars, and TVs) and windowing modes on large screens (such as split screen and desktop windowing), developers should build Android apps that adapt to any screen and window size, regardless of device orientation. Paradigms like restricting orientation and resizability are too restrictive in today's multidevice world.

Ignore orientation, resizability, and aspect ratio restrictions

For apps targeting Android 16 (API level 36), Android 16 includes changes to how the system manages orientation, resizability, and aspect ratio restrictions. On displays with smallest width >= 600dp, the restrictions no longer apply. Apps also fill the entire display window, regardless of aspect ratio or a user's preferred orientation, and pillarboxing isn't used.

This change introduces a new standard platform behavior. Android is moving toward a model where apps are expected to adapt to various orientations, display sizes, and aspect ratios. Restrictions like fixed orientation or limited resizability hinder app adaptability, so we recommend making your app adaptive to deliver the best possible user experience.

You can also test this behavior by using the app compatibility framework and enabling the UNIVERSAL_RESIZABLE_BY_DEFAULT compat flag.

Common breaking changes

Ignoring orientation, resizability, and aspect ratio restrictions might impact your app's UI on some devices, especially elements that were designed for small layouts locked in portrait orientation: for example, issues like stretched layouts and off-screen animations and components. Any assumptions about aspect ratio or orientation can cause visual issues with your app. Learn more about how to avoid them and improve your app's adaptive behaviour.

Allowing device rotation results in more activity re-creation, which can result in losing user state if not properly preserved. Learn how to correctly save UI state in Save UI states.

Implementation details

The following manifest attributes and runtime APIs are ignored across large screen devices in full-screen and multi-window modes:

The following values for screenOrientation, setRequestedOrientation(), and getRequestedOrientation() are ignored:

  • portrait
  • reversePortrait
  • sensorPortrait
  • userPortrait
  • landscape
  • reverseLandscape
  • sensorLandscape
  • userLandscape

Regarding display resizability, android:resizeableActivity="false", android:minAspectRatio, and android:maxAspectRatio have no effect.

For apps targeting Android 16 (API level 36), app orientation, resizability, and aspect ratio constraints are ignored on large screens by default, but every app that isn't fully ready can temporarily override this behavior by opting out (which results in the previous behavior of being placed in compatibility mode).

Exceptions

The Android 16 orientation, resizability, and aspect ratio restrictions don't apply in the following situations:

  • Games (based on the android:appCategory flag)
  • Users explicitly opting in to the app's default behavior in aspect ratio settings of the device
  • Screens that are smaller than sw600dp

Opt out temporarily

To opt out a specific activity, declare the PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY manifest property:

<activity ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
  ...
</activity>

If too many parts of your app aren't ready for Android 16, you can opt out completely by applying the same property at the application level:

<application ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
</application>

Zdrowie i fitness

Android 16 (poziom interfejsu API 36) zawiera te zmiany dotyczące danych o zdrowiu i aktywności fizycznej:

Uprawnienia dotyczące zdrowia i fitnessu

For apps targeting Android 16 (API level 36) or higher, BODY_SENSORS permissions use more granular permissions under android.permissions.health, which Health Connect also uses. As of Android 16, any API previously requiring BODY_SENSORS or BODY_SENSORS_BACKGROUND requires the corresponding android.permissions.health permission instead. This affects the following data types, APIs, and foreground service types:

If your app uses these APIs, it should request the respective granular permissions:

These permissions are the same as those that guard access to reading data from Health Connect, the Android datastore for health, fitness, and wellness data.

Mobile apps

Mobile apps migrating to use the READ_HEART_RATE and other granular permissions must also declare an activity to display the app's privacy policy. This is the same requirement as Health Connect.

Łączność

Android 16 (poziom interfejsu API 36) zawiera te zmiany w pakiecie Bluetooth, które mają na celu poprawę łączności z urządzeniami peryferyjnymi:

Nowe intencje do obsługi utraty powiązań i zmian szyfrowania

作为改进了对键值对丢失的处理的一部分,Android 16 还引入了 2 个新 intent,以便应用更好地了解键值对丢失和加密更改。

以 Android 16 为目标平台的应用现在可以:

  • 在检测到远程键盘连接丢失时接收 ACTION_KEY_MISSING intent,以便提供更具信息量的用户反馈并采取适当的措施。
  • 每当链接的加密状态发生变化时,都会收到 ACTION_ENCRYPTION_CHANGE intent。这包括加密状态更改、加密算法更改和加密密钥大小更改。如果应用在稍后收到 ACTION_ENCRYPTION_CHANGE intent 时成功加密了链接,则必须将该绑定视为已恢复。

适应不同的 OEM 实现

虽然 Android 16 引入了这些新 intent,但其实现和广播可能会因不同的设备制造商 (OEM) 而异。为了确保您的应用在所有设备上都能提供一致且可靠的体验,开发者应设计其绑定丢失处理机制,以妥善适应这些潜在的变化。

我们建议您采用以下应用行为:

  • 如果广播 ACTION_KEY_MISSING intent:

    系统会断开 ACL(异步无连接)链接,但会保留设备的配对信息(如此处所述)。

    您的应用应将此 intent 用作检测配对丢失的主要信号,并在发起设备忘记或重新配对之前引导用户确认远程设备是否在范围内。

    如果设备在收到 ACTION_KEY_MISSING 后断开连接,您的应用应谨慎重新连接,因为设备可能已不再与系统绑定。

  • 如果未广播 ACTION_KEY_MISSING intent:

    ACL 链接将保持连接状态,系统会移除设备的配对信息,与 Android 15 中的行为相同。

    在这种情况下,您的应用应继续使用与之前的 Android 版本相同的现有配对丢失处理机制,以检测和管理配对丢失事件。

Nowy sposób usuwania połączenia Bluetooth

All apps targeting Android 16 are now able to unpair bluetooth devices using a public API in CompanionDeviceManager. If a companion device is being managed as a CDM association, then the app can trigger bluetooth bond removal by using the new removeBond(int) API on the associated device. The app can monitor the bond state changes by listening to the bluetooth device broadcast event ACTION_BOND_STATE_CHANGED.

Bezpieczeństwo

Android 16 (poziom API 36) zawiera te zmiany dotyczące zabezpieczeń:

Blokada wersji MediaStore

W przypadku aplikacji kierowanych na Androida 16 lub nowszego ciąg MediaStore#getVersion() będzie teraz niepowtarzalny dla każdej aplikacji. Pozwoli to wyeliminować z ciągu wersji właściwości identyfikujące, aby zapobiec nadużyciom i użyciu w ramach technik odciskania palca. Aplikacje nie powinny zakładać niczego w stosunku do formatu tej wersji. Aplikacje powinny już obsługiwać zmiany wersji podczas korzystania z tego interfejsu API i w większości przypadków nie trzeba zmieniać ich bieżącego działania, chyba że deweloper próbował wywnioskować dodatkowe informacje wykraczające poza zamierzony zakres tego interfejsu API.

Bezpieczniejsze intencje

The Safer Intents feature is a multi-phase security initiative designed to improve the security of Android's intent resolution mechanism. The goal is to protect apps from malicious actions by adding checks during intent processing and filtering intents that don't meet specific criteria.

In Android 15 the feature focused on the sending app, now with Android 16, shifts control to the receiving app, allowing developers to opt-in to strict intent resolution using their app manifest.

Two key changes are being implemented:

  1. Explicit Intents Must Match the Target Component's Intent Filter: If an intent explicitly targets a component, it should match that component's intent filter.

  2. Intents Without an Action Cannot Match any Intent Filter: Intents that don't have an action specified shouldn't be resolved to any intent filter.

These changes only apply when multiple apps are involved and don't affect intent handling within a single app.

Impact

The opt-in nature means that developers must explicitly enable it in their app manifest for it to take effect. As a result, the feature's impact will be limited to apps whose developers:

  • Are aware of the Safer Intents feature and its benefits.
  • Actively choose to incorporate stricter intent handling practices into their apps.

This opt-in approach minimizes the risk of breaking existing apps that may rely on the current less-secure intent resolution behavior.

While the initial impact in Android 16 may be limited, the Safer Intents initiative has a roadmap for broader impact in future Android releases. The plan is to eventually make strict intent resolution the default behavior.

The Safer Intents feature has the potential to significantly enhance the security of the Android ecosystem by making it more difficult for malicious apps to exploit vulnerabilities in the intent resolution mechanism.

However, the transition to opt-out and mandatory enforcement must be carefully managed to address potential compatibility issues with existing apps.

Implementation

Developers need to explicitly enable stricter intent matching using the intentMatchingFlags attribute in their app manifest. Here is an example where the feature is opt-in for the entire app, but disabled/opt-out on a receiver:

<application android:intentMatchingFlags="enforceIntentFilter">
    <receiver android:name=".MyBroadcastReceiver" android:exported="true" android:intentMatchingFlags="none">
        <intent-filter>
            <action android:name="com.example.MY_CUSTOM_ACTION" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.example.MY_ANOTHER_CUSTOM_ACTION" />
        </intent-filter>
    </receiver>
</application>

More on the supported flags:

Flag Name Description
enforceIntentFilter Enforces stricter matching for incoming intents
none Disables all special matching rules for incoming intents. When specifying multiple flags, conflicting values are resolved by giving precedence to the "none" flag
allowNullAction Relaxes the matching rules to allow intents without an action to match. This flag to be used in conjunction with "enforceIntentFilter" to achieve a specific behavior

Testing and Debugging

When the enforcement is active, apps should function correctly if the intent caller has properly populated the intent. However, blocked intents will trigger warning log messages like "Intent does not match component's intent filter:" and "Access blocked:" with the tag "PackageManager." This indicates a potential issue that could impact the app and requires attention.

Logcat filter:

tag=:PackageManager & (message:"Intent does not match component's intent filter:" | message: "Access blocked:")

Prywatność

Android 16 (poziom API 36) zawiera te zmiany dotyczące prywatności:

Dostęp do sieci lokalnej

Do urządzeń w sieci LAN można uzyskać dostęp z dowolnej aplikacji, która ma uprawnienia INTERNET. Ułatwia to aplikacjom nawiązywanie połączeń z urządzeniami lokalnymi, ale ma też wpływ na prywatność, np. tworzy odcisk palca użytkownika i działa jako serwer proxy w przypadku lokalizacji.

Projekt Ochrona sieci lokalnej ma na celu ochronę prywatności użytkownika przez ograniczenie dostępu do sieci lokalnej za pomocą nowego uprawnienia w czasie wykonywania.

Plan wydania

Ta zmiana zostanie wdrożona między 2 wersjami: 25Q2 i TBD. Deweloperzy muszą przestrzegać tych wskazówek dotyczących 25Q2 i przekazywać opinie, ponieważ te zabezpieczenia zostaną wprowadzone w późniejszej wersji Androida. Ponadto deweloperzy będą musieli zaktualizować scenariusze, które zależą od domyślnego dostępu do sieci lokalnej, korzystając z tych wskazówek, oraz przygotować się na odrzucenie przez użytkownika i wycofanie nowego uprawnienia.

Wpływ

Obecnie jest to funkcja opcjonalna, co oznacza, że dotyczy ona tylko aplikacji, które ją obsługują. Celem fazy zgód jest umożliwienie deweloperom zrozumienia, które części ich aplikacji są zależne od domyślnego dostępu do sieci lokalnej, aby mogli przygotować się do wprowadzenia ochrony uprawnień w przyszłej wersji.

Dotyczy to aplikacji, które uzyskują dostęp do sieci lokalnej użytkownika za pomocą:

  • bezpośrednie lub biblioteczne korzystanie z nieprzetworzonych gniazd na adresy sieci lokalnej (np. protokół wykrywania usług mDNS lub SSDP);
  • Używanie klas na poziomie frameworku, które uzyskują dostęp do sieci lokalnej (np.NsdManager).

Ruch doz adresu sieci lokalnej wymaga uprawnień dostępu do sieci lokalnej. W tabeli poniżej znajdziesz kilka typowych przypadków:

Operacje sieciowe na niskim poziomie aplikacji Wymagany dostęp przez sieć lokalną
Nawiązywanie wychodzącego połączenia TCP tak
Akceptowanie przychodzących połączeń TCP tak
Wysyłanie transmisji unicast, multicast i broadcast UDP tak
Odbieranie przychodzącego pakietu UDP unicast, multicast lub broadcast tak

Te ograniczenia są wdrażane głęboko w składniku sieciowym, dlatego dotyczą wszystkich interfejsów API sieciowych. Dotyczy to gniazd utworzonych w kodzie natywnym lub zarządzanym, bibliotek sieciowych, takich jak Cronet i OkHttp, oraz interfejsów API zaimplementowanych na ich podstawie. Próba rozwiązania usług w sieci lokalnej (czyli usług z przyrostkiem .local) wymaga uprawnień do sieci lokalnej.

Wyjątki od powyższych zasad:

  • Jeśli serwer DNS urządzenia znajduje się w sieci lokalnej, ruch do niego i z niego (na porcie 53) nie wymaga uprawnień dostępu do sieci lokalnej.
  • Aplikacje korzystające z przełącznika wyjścia jako selektora w aplikacji nie będą wymagać uprawnień do sieci lokalnej (więcej wskazówek pojawi się w IV kwartale 2025 r.).

Wskazówki dla programistów (włączanie funkcji)

Aby włączyć ograniczenia sieci lokalnej, wykonaj te czynności:

  1. Przeprowadź flashowanie urządzenia z użyciem wersji 25Q2 Beta 3 lub nowszej.
  2. Zainstaluj aplikację, którą chcesz przetestować.
  3. Przełącz flagę Appcompat w adb:

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. Uruchom ponownie urządzenie

Teraz dostęp aplikacji do sieci lokalnej jest ograniczony, a próba uzyskania dostępu do sieci lokalnej spowoduje błąd gniazda. Jeśli używasz interfejsów API, które wykonują operacje sieci lokalnej poza procesem aplikacji (np. NsdManager), nie będą one miały wpływu na fazę akceptacji.

Aby przywrócić dostęp, musisz przyznać aplikacji uprawnienia do NEARBY_WIFI_DEVICES.

  1. Upewnij się, że aplikacja deklaruje uprawnienie NEARBY_WIFI_DEVICES w pliku manifestu.
  2. Kliknij Ustawienia > Aplikacje > [Nazwa aplikacji] > Uprawnienia > Urządzenia w pobliżu > Zezwalaj.

Teraz dostęp aplikacji do sieci lokalnej powinien zostać przywrócony, a wszystkie scenariusze powinny działać tak samo jak przed włączeniem aplikacji.

Gdy zaczniemy egzekwować ochronę sieci lokalnej, w ten sposób wpłynie to na ruch w sieci aplikacji:

Uprawnienia Wychodzące żądanie LAN Wychodzące/przychodzące żądanie internetowe Żądanie przychodzące z sieci LAN
Przyznano Works Works Works
Nie przyznano Wpadki Works Wpadki

Aby wyłączyć flagę zgodności aplikacji, użyj tego polecenia:

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

Błędy

Błędy wynikające z tych ograniczeń będą zwracane do wywołującego gniazda, gdy wywoła on metodę send lub jej wariant na potrzeby wysyłania do lokalnego adresu sieci.

Przykładowe błędy:

sendto failed: EPERM (Operation not permitted)

sendto failed: ECONNABORTED (Operation not permitted)

Definicja sieci lokalnej

Sieć lokalna w tym projekcie to sieć IP, która korzysta z interfejsu sieciowego obsługującego transmisję, np. Wi-Fi lub Ethernet, ale wyklucza połączenia komórkowe (WWAN) i VPN.

Do sieci lokalnych zaliczamy:

IPv4:

  • 169.254.0.0/16 // Link Local
  • 100.64.0.0/10 // CGNAT
  • 10.0.0.0/8 // RFC1918
  • 172.16.0.0/12 // RFC1918
  • 192.168.0.0/16 // RFC1918

IPv6:

  • Link-local
  • Trasy połączone bezpośrednio
  • siecie typu stub, takie jak Thread;
  • Wiele podsieci (TBD)

Dodatkowo zarówno adresy multicast (224.0.0.0/4, ff00::/8), jak i adres rozgłoszeniowy IPv4 (255.255.255.255) są klasyfikowane jako adresy sieci lokalnej.

Zdjęcia należące do aplikacji

当面向 SDK 36 或更高版本的应用在搭载 Android 16 或更高版本的设备上提示用户授予照片和视频权限时,如果用户选择限制对所选媒体的访问权限,则会在照片选择器中看到该应用拥有的所有照片。用户可以取消选择任何这些预选项,这会撤消该应用对这些照片和视频的访问权限。