Как и в предыдущих выпусках, в 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.
Android skills
View on GitHub
Manage AppWidget updates and bitmap memory
android skills add glance-appwidget-updates-and-memory
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
Bitmapand bitmap-backedIconobjects (Icon.TYPE_BITMAPandIcon.TYPE_ADAPTIVE_BITMAP) stored inRemoteViews.mBitmapCache(such as calls tosetImageViewBitmap,Icon.createWithBitmap,Icon.createWithAdaptiveBitmap, or Jetpack GlanceImageProvider(bitmap)). Each uniqueBitmapor bitmap-backedIconinstance inmBitmapCacheis counted once perRemoteViewshierarchy. - URI-backed images (
Icon.createWithContentUri,setImageViewUri, or GlanceImageProvider(uri)) don't count toward theRemoteViewsIPC byte cap insystem_server, but the widget host process decodes the referencedcontent://file at full resolution into its own heap. Always write a downsampled image intocontext.cacheDirbefore exposing it through aFileProviderURI.
Mitigation steps
To keep your widget updates within the memory ceiling across phones, tablets, and foldables, do the following:
Compute your runtime memory budget from
WindowMetrics: On API level 30 and higher, read the active window bounds fromWindowManager.currentWindowMetrics.boundsrather thanresources.displayMetrics. On multi-resolution devices and foldables,displayMetricscan report inactive display dimensions. Estimate your total widget image budget at6L * 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() }Downsample images to the widget's viewable dimensions and use
RGB_565: Decode bitmaps with power-of-twoBitmapFactory.Options.inSampleSizevalues sized to the widget's maximum display dimensions (maxWidthDpbymaxHeightDp), and useBitmap.Config.RGB_565(2bytes per pixel) instead ofARGB_8888(4bytes per pixel) for opaque photographs and thumbnails.Hoist bitmap decoding outside
provideContentin Jetpack Glance: When usingSizeMode.ResponsiveorSizeMode.Exact, Glance invokes yourprovideContentlambda once per size bucket. Decode each sharedBitmaponce insideprovideGlancebefore callingprovideContentso all size buckets reference the sameBitmapinstance inRemoteViews.mBitmapCache.Use full
updateAppWidgetcalls when replacing images: In classicAppWidgetProviderimplementations, avoid callingAppWidgetManager.partiallyUpdateAppWidgetto swapBitmaporIconviews. Partial updates merge new actions into the existingRemoteViewstree insystem_serverwithout evicting previously cached image actions. Build a completeRemoteViewslayout and callupdateAppWidgetinstead.Provide an error fallback layout: In Jetpack Glance, override
onCompositionErrorto render a zero-bitmapRemoteViewsfallback 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 legacyMODE_BACKGROUND_ACTIVITY_START_ALLOWEDconstant. Instead, you should adopt granular controls likeMODE_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_ALARMaudio 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.