Изменения в поведении: приложения для Android 17 и более поздних версий

Как и в предыдущих выпусках, в Android 17 есть изменения в поведении, которые могут повлиять на ваше приложение. Изменения, описанные ниже, касаются только приложений, предназначенных для Android 17 или более поздней версии. Если ваше приложение предназначено для Android 17 или более поздней версии, вам следует изменить его, чтобы поддерживать эти функции, где это применимо.

Также ознакомьтесь со списком изменений в поведении, которые затрагивают все приложения, работающие на Android 17, независимо от targetSdkVersion.

Удобство для пользователей и системный интерфейс

В Android 17 внесены изменения, которые делают интерфейс более единообразным и интуитивно понятным.

Виджет лимита памяти

Beginning with Android 17, the system enforces a strict memory limit on RemoteViews updates for apps targeting Android 17 (API level 37) or higher. When an app passes a RemoteViews object to AppWidgetManager.updateAppWidget, system_server calculates the total memory footprint of all image data across every orientation and size bucket in the payload. If the total memory exceeds the system ceiling (mMaxWidgetBitmapMemory), the system rejects the update and throws an IllegalArgumentException:

java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: XXXXX, max: YYYYY)

For apps targeting API level 36 or lower, the system logs this memory violation as a warning (Slog.w) without throwing an exception.

How the system calculates the memory ceiling

The system sets the widget bitmap memory budget at 6 * width * height bytes (1.5 * 4 * width * height, equivalent to 1.5 times the size of a full-screen ARGB_8888 buffer) for the active display configuration. Under API level 37 and higher, this calculation includes both of the following:

  • In-memory Bitmap and bitmap-backed Icon objects (Icon.TYPE_BITMAP and Icon.TYPE_ADAPTIVE_BITMAP) stored in RemoteViews.mBitmapCache (such as calls to setImageViewBitmap, Icon.createWithBitmap, Icon.createWithAdaptiveBitmap, or Jetpack Glance ImageProvider(bitmap)). Each unique Bitmap or bitmap-backed Icon instance in mBitmapCache is counted once per RemoteViews hierarchy.
  • URI-backed images (Icon.createWithContentUri, setImageViewUri, or Glance ImageProvider(uri)) don't count toward the RemoteViews IPC byte cap in system_server, but the widget host process decodes the referenced content:// file at full resolution into its own heap. Always write a downsampled image into context.cacheDir before exposing it through a FileProvider URI.

Mitigation steps

To keep your widget updates within the memory ceiling across phones, tablets, and foldables, do the following:

  1. Compute your runtime memory budget from WindowMetrics: On API level 30 and higher, read the active window bounds from WindowManager.currentWindowMetrics.bounds rather than resources.displayMetrics. On multi-resolution devices and foldables, displayMetrics can report inactive display dimensions. Estimate your total widget image budget at 6L * bounds.width() * bounds.height() as shown in the following example:

    private const val FALLBACK_MAX_BYTES = 15_000_000L
    
    fun calculateWidgetMemoryCapBytes(context: Context): Long {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val wm = context.getSystemService(WindowManager::class.java)
                ?: return FALLBACK_MAX_BYTES
            val bounds = wm.currentWindowMetrics.bounds
            return 6L * bounds.width().toLong() * bounds.height().toLong()
        }
        val dm = context.resources.displayMetrics
        return 6L * dm.widthPixels.toLong() * dm.heightPixels.toLong()
    }
    
  2. Downsample images to the widget's viewable dimensions and use RGB_565: Decode bitmaps with power-of-two BitmapFactory.Options.inSampleSize values sized to the widget's maximum display dimensions (maxWidthDp by maxHeightDp), and use Bitmap.Config.RGB_565 (2 bytes per pixel) instead of ARGB_8888 (4 bytes per pixel) for opaque photographs and thumbnails.

  3. Hoist bitmap decoding outside provideContent in Jetpack Glance: When using SizeMode.Responsive or SizeMode.Exact, Glance invokes your provideContent lambda once per size bucket. Decode each shared Bitmap once inside provideGlance before calling provideContent so all size buckets reference the same Bitmap instance in RemoteViews.mBitmapCache.

  4. Use full updateAppWidget calls when replacing images: In classic AppWidgetProvider implementations, avoid calling AppWidgetManager.partiallyUpdateAppWidget to swap Bitmap or Icon views. Partial updates merge new actions into the existing RemoteViews tree in system_server without evicting previously cached image actions. Build a complete RemoteViews layout and call updateAppWidget instead.

  5. Provide an error fallback layout: In Jetpack Glance, override onCompositionError to render a zero-bitmap RemoteViews fallback if an update fails.

You can inspect your widget's current serialized bitmap memory usage on a connected device by running the following:

adb shell dumpsys appwidget

Основные функции

В Android 17 внесены изменения, которые модифицируют или расширяют различные основные возможности системы Android.

Новая реализация MessageQueue без блокировки

Начиная с Android 17, приложения, предназначенные для Android 17 (уровень API 37) или более поздней версии, получают новую реализацию android.os.MessageQueue без блокировки. Новая реализация повышает производительность и уменьшает количество пропущенных кадров, но может нарушить работу клиентов, которые используют закрытые поля и методы MessageQueue.

Дополнительную информацию, в том числе о стратегиях смягчения мер, можно найти в руководстве по изменению поведения MessageQueue.

Статические финальные поля теперь нельзя изменить.

Приложения, работающие на Android 17 или более поздней версии и предназначенные для Android 17 (уровень API 37) или более поздней версии, не могут изменять поля static final. Если приложение попытается изменить поле static final с помощью рефлексии, возникнет ошибка IllegalAccessException. Попытка изменить одно из этих полей с помощью JNI API (например, SetStaticLongField()) приведет к сбою приложения.

Специальные возможности

В Android 17 внесены следующие изменения, улучшающие специальные возможности.

Поддержка специальных возможностей при вводе текста с помощью физической клавиатуры и редактора метода ввода

Эта функция добавляет новые API AccessibilityEvent и TextAttribute, которые улучшают озвучивание текста на экране при вводе на китайском, японском, корейском и вьетнамском языках. Теперь приложения с редактором метода ввода для китайского, японского, корейского и вьетнамского языков могут сообщать, был ли выбран вариант преобразования текста во время его ввода. Приложения с полями редактирования могут указывать типы изменения текста при отправке событий специальных возможностей, связанных с изменением текста. Например, приложения могут указывать, что изменение текста произошло во время составления текста или что изменение текста произошло в результате фиксации. Это позволяет сервисам специальных возможностей, например программам чтения с экрана, предоставлять более точную обратную связь в зависимости от характера изменения текста.

Внедрение приложения

  • Приложения IME. При настройке текста в полях редактирования редакторы методов ввода могут использовать TextAttribute.Builder.setTextSuggestionSelected(), чтобы указать, был ли выбран определенный вариант конверсии.

  • Приложения с полями редактирования. Приложения, которые поддерживают настраиваемое поле InputConnection, могут получать данные о выбранных кандидатах, вызывая метод TextAttribute.isTextSuggestionSelected(). При отправке событий TYPE_VIEW_TEXT_CHANGED такие приложения должны вызывать метод AccessibilityEvent.setTextChangeTypes(). Для приложений, предназначенных для Android 17 (уровень API 37) и использующих стандартный TextView, эта функция будет включена по умолчанию. (то есть TextView будет обрабатывать получение данных от IME и задавать типы изменений текста при отправке событий в сервисы специальных возможностей).

  • Сервисы специальных возможностей. Сервисы специальных возможностей, которые обрабатывают события TYPE_VIEW_TEXT_CHANGED, могут вызывать AccessibilityEvent.getTextChangeTypes(), чтобы определить характер изменения и соответствующим образом скорректировать свои стратегии обратной связи.

Конфиденциальность

В Android 17 внесены следующие изменения, направленные на повышение конфиденциальности пользователей.

Расширение ECH (Encrypted Client Hello) включено

Android 17 introduces platform support for Encrypted Client Hello (ECH), a TLS extension that enhances user privacy by encrypting the Server Name Indication (SNI) in the TLS handshake. This encryption helps prevent network observers from easily identifying the specific domain your app is connecting to.

For apps targeting Android 17 (API level 37) or higher, ECH is used for TLS connections. ECH is active only if the networking library used by the app (for example, HttpEngine, WebView, or OkHttp) has integrated ECH support and the remote server also supports the ECH protocol. If ECH cannot be negotiated, the client sends an ECH extension with randomized contents (a mechanism called ECH GREASE). See RFC 9849 for more details on how ECH GREASE works.

To allow apps to customize this behavior, Android 17 adds a new <domainEncryption> element to the Network Security Configuration file. Developers can use <domainEncryption> within <base-config> or <domain-config> tags to select an ECH mode (for example, "enabled" or "disabled") on a global or per-domain basis.

For more information, see the Encrypted Client Hello documentation.

Для приложений, предназначенных для Android 17, требуется разрешение на доступ к локальной сети

В Android 17 появилось динамическое разрешение ACCESS_LOCAL_NETWORK, которое защищает пользователей от несанкционированного доступа к локальной сети. Поскольку это разрешение относится к существующей группе разрешений NEARBY_DEVICES, пользователям, которые уже предоставили другие разрешения NEARBY_DEVICES, не будет предлагаться сделать это снова. Это требование не позволяет вредоносным приложениям использовать неограниченный доступ к локальной сети для скрытого отслеживания пользователей и создания цифровых отпечатков. Объявив и запросив это разрешение, ваше приложение сможет обнаруживать устройства в локальной сети (LAN), такие как устройства умного дома или приемники трансляций, и подключаться к ним.

У приложений, предназначенных для Android 17 (уровень API 37) или более поздней версии, теперь есть два способа поддерживать связь с устройствами в локальной сети: использовать системные инструменты выбора устройств, обеспечивающие конфиденциальность, чтобы пропускать запрос разрешения, или явно запрашивать это новое разрешение во время выполнения, чтобы поддерживать связь в локальной сети.

Подробную информацию вы найдете в документации.

Скрытие паролей на физических устройствах

Если приложение поддерживает Android 17 (уровень API 37) или более позднюю версию и пользователь вводит пароль с помощью физического устройства ввода, например внешней клавиатуры, операционная система Android применяет новую настройку show_passwords_physical ко всем символам в поле пароля. По умолчанию эта настройка скрывает все символы пароля.

Система Android показывает последний введенный символ пароля, чтобы пользователь мог проверить, правильно ли он его ввел. Однако это гораздо менее необходимо при использовании больших внешних клавиатур. Кроме того, у устройств с внешними клавиатурами часто бывают большие экраны, что увеличивает риск того, что кто-то увидит вводимый пароль.

Если пользователь взаимодействует с сенсорным экраном, система применяет новое значение параметра show_passwords_touch.

Защита одноразовых кодов в стандартных SMS

Beginning with Android 17, Android is extending its SMS OTP protection to apply to standard SMS messages (SMS messages containing an OTP that do not use the WebOTP or SMS Retriever formats). For most apps targeting Android 17 (API level 37) or higher, these SMS messages do not become available until three hours after receipt. This delay is intended to help prevent OTP hijacking. During this three hour delay, the SMS_RECEIVED_ACTION broadcast is withheld and SMS provider database queries are filtered. The SMS message is available to these apps after the delay.

Certain apps such as the default SMS assistant app, connected device companion apps, etc., are exempted from this delay. All apps that rely on reading SMS messages for OTP extraction should transition to using SMS Retriever or SMS User Consent APIs to ensure continued functionality.

Безопасность

В Android 17 улучшена безопасность устройств и приложений.

Безопасность действий

In Android 17, the platform continues its shift toward a "secure-by-default" architecture, introducing a suite of enhancements designed to mitigate high-severity exploits such as phishing, interaction hijacking, and confused deputy attacks. This update requires developers to explicitly opt in to new security standards to maintain app compatibility and user protection.

Key impacts for developers include:

  • BAL hardening & improved opt-in: We are refining Background Activity Launch (BAL) restrictions by extending protections to IntentSender. Developers must migrate away from the legacy MODE_BACKGROUND_ACTIVITY_START_ALLOWED constant. Instead, you should adopt granular controls like MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE, which restricts activity starts to scenarios where the calling app is visible, significantly reducing the attack surface.
  • Adoption tools: Developers should utilize strict mode and updated lint checks to identify legacy patterns and ensure readiness for future target SDK requirements.

Включить прозрачность сертификатов по умолчанию

If an app targets Android 17 (API level 37) or higher, certificate transparency (CT) is enabled by default. (On Android 16, CT is available but apps had to opt in.)

Safer Native DCL—C

If your app targets Android 17 (API level 37) or higher, the Safer Dynamic Code Loading (DCL) protection introduced in Android 14 for DEX and JAR files now extends to native libraries.

All native files loaded using System.load() must be marked as read-only. Otherwise, the system throws UnsatisfiedLinkError.

We recommend that apps avoid dynamically loading code whenever possible, as doing so greatly increases the risk that an app can be compromised by code injection or code tampering.

Ограничение доступа к полям с информацией, позволяющей идентифицировать личность, в представлении данных CP2

В приложениях, предназначенных для Android 17 (уровень API 37) и более поздних версий, Contacts Provider 2 (CP2) ограничивает доступ к определенным столбцам, содержащим информацию, позволяющую идентифицировать личность. Когда это изменение вступит в силу, эти столбцы будут удалены из представления данных, чтобы повысить конфиденциальность пользователей. К столбцам с ограниченным доступом относятся:

Приложения, которые используют эти столбцы из ContactsContract.Data, могут извлекать их из ContactsContract.RawContacts, объединив с RAW_CONTACT_ID.

Принудительно применять строгие проверки SQL в CP2

For apps targeting Android 17 (API level 37) and higher, Contacts Provider 2 (CP2) enforces strict SQL query validation when the ContactsContract.Data table is accessed without READ_CONTACTS permission.

With this change, if an app doesn't have READ_CONTACTS permission, StrictColumns and StrictGrammar options are set when querying the ContactsContract.Data table. If a query uses a pattern that isn't compatible with these, it will be rejected and cause an exception to be thrown.

Обнаружение

В Android 17 внесены следующие изменения в системный интеллект.

Прекращение поддержки setContentCaptureEnabled

На некоторых устройствах функция "Запись контента" включена по умолчанию. Она позволяет ИИ-функциям на устройстве анализировать содержимое экрана, чтобы предлагать умные возможности.

Начиная с Android 17 метод API ContentCaptureManager.setContentCaptureEnabled(boolean) больше не поддерживается. В приложениях, предназначенных для Android 17 (уровень API 37) или более поздних версий, вызов setContentCaptureEnabled(false) больше не отключает Content Capture.

Если в вашем приложении по-прежнему нужно отключать Content Capture или запрещать системе записывать содержимое экрана, перейдите на параметр макета окна FLAG_SECURE.

Чтобы отключить захват контента, установите флаг FLAG_SECURE в окне, как показано в примере ниже.

Kotlin

window.setFlags(
    WindowManager.LayoutParams.FLAG_SECURE,
    WindowManager.LayoutParams.FLAG_SECURE
)

Java

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_SECURE,
    WindowManager.LayoutParams.FLAG_SECURE
);

Подробную информацию вы можете найти в справочной документации по WindowManager.LayoutParams.FLAG_SECURE.

Мультимедиа

В Android 17 внесены следующие изменения в работу с медиаконтентом.

Усиление защиты аудио в фоновом режиме

Beginning with Android 17, the audio framework enforces restrictions on background audio interactions including audio playback, audio focus requests, and volume change APIs to ensure that these changes are started intentionally by the user.

Some audio restrictions apply to all apps. However, the restrictions are more stringent if an app targets Android 17 (API level 37). If one of these apps interacts with audio while it is in the background, it must have a foreground service running. In addition, the app must meet one or both of these requirements:

  • The foreground service must have while-in-use (WIU) capabilities.
  • The app must have the exact alarm permission and be interacting with USAGE_ALARM audio streams.

For more information, including mitigation strategies, see Background audio hardening.

Типы устройств

В Android 17 внесены изменения, которые повышают удобство использования устройств разных размеров и форм-факторов.

Изменения в Platform API, позволяющие игнорировать ограничения на ориентацию, изменение размера и соотношение сторон на больших экранах (sw>=600 dp)

В Android 16 мы изменили API платформы, чтобы игнорировать ограничения на ориентацию, изменение размера и соотношение сторон на больших экранах (sw >= 600 dp) для приложений, предназначенных для целевого уровня API 36 или выше. Разработчики могут отказаться от этих изменений в SDK 36, но этот вариант будет недоступен для приложений, предназначенных для Android 17 (уровень API 37) или более поздней версии.

Подробнее о том, почему игнорируются ограничения на ориентацию и изменение размера…

Функции связи

В Android 17 внесены следующие изменения, чтобы улучшить согласованность и соответствие стандартному поведению InputStream в Java для сокетов RFCOMM Bluetooth.

Согласованное поведение метода read() класса BluetoothSocket для RFCOMM

For apps targeting Android 17 (API level 37), the read() method of the InputStream obtained from an RFCOMM-based BluetoothSocket now returns -1 when the socket is closed or the connection is dropped.

This change makes RFCOMM socket behavior consistent with LE CoC sockets and aligns with the standard InputStream.read() documentation, which states that -1 is returned when the end of the stream is reached.

Apps that rely solely on catching an IOException to break out of a read loop may be impacted by this change and should update the BluetoothSocket read loops to explicitly check for a return value of -1. This ensures the loop terminates correctly when the remote device disconnects or the socket is closed. For an example of the recommended implementation, see the code snippet in the Transfer Bluetooth data guide.