Изменения поведения: все приложения

Android 9 (уровень API 28) вносит ряд изменений в систему Android. Следующие изменения поведения применяются ко всем приложениям , работающим на платформе Android 9, независимо от уровня API, на который они нацелены. Всем разработчикам следует просмотреть эти изменения и модифицировать свои приложения для их надлежащей поддержки, если это применимо к приложению.

Изменения, которые затрагивают только приложения, ориентированные на уровень API 28 или выше, см. в разделе Изменения поведения: приложения, ориентированные на уровень API 28+ .

Управление питанием

В Android 9 представлены новые функции для улучшения управления питанием устройства. Эти изменения, а также функции, которые уже присутствовали до Android 9, помогают обеспечить доступность системных ресурсов для приложений, которые в них нуждаются больше всего.

Подробности см. в разделе Управление питанием .

Изменения конфиденциальности

Чтобы повысить конфиденциальность пользователей, в Android 9 внесено несколько изменений поведения, таких как ограничение доступа фоновых приложений к датчикам устройства, ограничение информации, получаемой при сканировании Wi-Fi, а также новые правила разрешений и группы разрешений, связанные с телефонными звонками, состоянием телефона и Wi-Fi. Fi сканирует.

Эти изменения затрагивают все приложения, работающие на Android 9, независимо от целевой версии SDK.

Ограниченный доступ к датчикам в фоновом режиме

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

  • Ваше приложение не может получить доступ к микрофону или камере.
  • Датчики, использующие режим непрерывной отчетности, такие как акселерометры и гироскопы, не получают событий.
  • Датчики, использующие режимы отчетов при изменении или однократном сообщении, не получают событий.

Если вашему приложению необходимо обнаруживать события датчиков на устройствах под управлением Android 9, используйте службу переднего плана .

Ограниченный доступ к журналам вызовов

В Android 9 представлена ​​группа разрешений CALL_LOG и перемещены разрешения READ_CALL_LOG , WRITE_CALL_LOG и PROCESS_OUTGOING_CALLS в эту группу. В предыдущих версиях Android эти разрешения находились в группе разрешений PHONE .

Эта группа разрешений CALL_LOG дает пользователям лучший контроль и видимость приложений, которым необходим доступ к конфиденциальной информации о телефонных звонках, например чтение записей телефонных звонков и определение телефонных номеров.

Если вашему приложению требуется доступ к журналам вызовов или обработка исходящих вызовов, вы должны явно запросить эти разрешения у группы разрешений CALL_LOG . В противном случае возникает SecurityException .

Примечание. Поскольку эти разрешения изменили группы и предоставляются во время выполнения, пользователь может запретить вашему приложению доступ к информации журналов телефонных вызовов. В этом случае ваше приложение должно иметь возможность корректно справляться с отсутствием доступа к информации.

Если ваше приложение уже следует рекомендациям по разрешениям во время выполнения , оно может обработать изменение группы разрешений.

Ограниченный доступ к телефонным номерам

Приложения, работающие на Android 9, не могут считывать номера телефонов или состояние телефона без предварительного получения разрешения READ_CALL_LOG в дополнение к другим разрешениям, которые требуются для сценариев использования вашего приложения.

Номера телефонов, связанные с входящим и исходящим вызовами, отображаются в широковещательной передаче состояния телефона , например, для входящих и исходящих вызовов, и доступны из класса PhoneStateListener . Однако без разрешения READ_CALL_LOG поле номера телефона, предоставляемое в широковещательных рассылках PHONE_STATE_CHANGED и через PhoneStateListener , пусто.

Чтобы читать номера телефонов из состояния телефона, обновите приложение, чтобы оно запрашивало необходимые разрешения в зависимости от вашего варианта использования:

Ограниченный доступ к данным о местоположении и подключении Wi-Fi.

В Android 9 требования к разрешениям приложения на сканирование Wi-Fi более строгие, чем в предыдущих версиях. Подробную информацию см. в разделе Ограничения сканирования Wi-Fi .

Аналогичные ограничения также применяются к методу getConnectionInfo() , который возвращает объект WifiInfo , описывающий текущее соединение Wi-Fi. Вы можете использовать методы этого объекта для получения значений SSID и BSSID только в том случае, если вызывающее приложение имеет следующие разрешения:

  • ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

Для получения SSID или BSSID также необходимо включить службы определения местоположения на устройстве (в разделе «Настройки» > «Местоположение »).

Информация удалена из методов обслуживания Wi-Fi.

В Android 9 следующие события и трансляции не получают информацию о местоположении пользователя или личные данные:

Системная трансляция NETWORK_STATE_CHANGED_ACTION из Wi-Fi больше не содержит SSID (ранее EXTRA_SSID), BSSID (ранее EXTRA_BSSID) или информацию о соединении (ранее EXTRA_NETWORK_INFO). Если вашему приложению нужна эта информация, вместо этого вызовите getConnectionInfo() .

Информация о телефонии теперь зависит от настроек местоположения устройства.

Если пользователь отключил определение местоположения устройства на устройстве под управлением Android 9, следующие методы не дадут результатов:

Ограничения на использование интерфейсов, отличных от SDK.

Чтобы обеспечить стабильность и совместимость приложения, платформа ограничивает использование некоторых методов и полей, отличных от SDK; эти ограничения применяются независимо от того, пытаетесь ли вы получить доступ к этим методам и полям напрямую, через отражение или с помощью JNI. В Android 9 ваше приложение может продолжать получать доступ к этим ограниченным интерфейсам; платформа использует всплывающие уведомления и записи журнала, чтобы привлечь к ним ваше внимание. Если в вашем приложении отображается такое всплывающее уведомление, важно, чтобы вы придерживались стратегии реализации, отличной от ограниченного интерфейса. Если вы считаете, что никакая альтернативная стратегия невозможна, вы можете сообщить об ошибке и потребовать пересмотра ограничения.

Ограничения на интерфейсы без SDK содержат дополнительную важную информацию. Вам следует просмотреть его, чтобы убедиться, что ваше приложение продолжает работать правильно.

Изменения в поведении безопасности

Изменения безопасности устройства

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

Изменения реализации TLS

Реализация TLS в системе претерпела несколько изменений в Android 9:

  • Если экземпляру SSLSocket не удается подключиться во время его создания, система выдает IOException вместо NullPointerException .
  • Класс SSLEngine аккуратно обрабатывает любые возникающие оповещения close_notify .

Дополнительные сведения о выполнении безопасных веб-запросов в приложении Android см. в разделе «Пример HTTPS» .

Более строгий фильтр SECOMP

Android 9 дополнительно ограничивает системные вызовы, доступные приложениям. Такое поведение является расширением фильтра SECCOMP, который включен в Android 8.0 (уровень API 26) .

Криптографические изменения

В Android 9 внесено несколько изменений в реализацию и обработку криптографических алгоритмов.

Коншифровать реализации параметров и алгоритмов

Android 9 предоставляет дополнительные реализации параметров алгоритма в Conscrypt . К этим параметрам относятся: AES, DESEDE, OAEP и EC. Версии этих параметров и многих алгоритмов в Bouncy Castle устарели, начиная с Android 9.

Если ваше приложение предназначено для Android 8.1 (уровень API 27) или ниже, вы получите предупреждение при запросе реализации Bouncy Castle одного из этих устаревших алгоритмов. Однако если вы ориентируетесь на Android 9, каждый из этих запросов генерирует NoSuchAlgorithmException .

Другие изменения

В Android 9 представлено несколько других изменений, связанных с криптографией:

  • Если при использовании ключей PBE Bouncy Castle ожидает вектор инициализации (IV), а ваше приложение его не предоставляет, вы получите предупреждение.
  • Реализация шифра ARC4 в Conscrypt позволяет указать либо ARC4/ECB/NoPadding , либо ARC4/NONE/NoPadding .
  • Поставщик криптографической архитектуры Java (JCA) был удален. В результате, если ваше приложение вызывает SecureRandom.getInstance("SHA1PRNG", "Crypto") , возникает NoSuchProviderException .
  • Если ваше приложение анализирует ключи RSA из буферов, размер которых превышает структуру ключей, исключение больше не возникает.

Дополнительные сведения об использовании криптографических возможностей Android см. в разделе Криптография .

Безопасные зашифрованные файлы Android больше не поддерживаются.

В Android 9 полностью удалена поддержка безопасных зашифрованных файлов Android (ASEC).

В Android 2.2 (уровень API 8) Android представил ASEC для поддержки функций приложений на SD-карте. В Android 6.0 (уровень API 23) платформа представила адаптируемую технологию устройств хранения данных , которую разработчики могут использовать вместо ASEC.

Обновления библиотек ICU

Android 9 использует библиотеку ICU версии 60. Android 8.0 (уровень API 26) и Android 8.1 (уровень API 27) используют ICU 58.

ICU используется для предоставления общедоступных API в android.icu package и используется внутри платформы Android для поддержки интернационализации. Например, он используется для реализации классов Android в java.util , java.text и android.text.format .

Обновление ICU 60 содержит множество небольших, но полезных изменений, включая поддержку данных Emoji 5.0 и улучшенные форматы даты и времени, как описано в примечаниях к выпуску ICU 59 и ICU 60.

Заметные изменения в этом обновлении:

  • Изменился способ обработки часовых поясов платформой.
    • Платформа лучше обрабатывает GMT и UTC; UTC больше не является синонимом GMT.

      ICU теперь предоставляет переведенные названия зон для GMT и UTC. Это изменение влияет на форматирование и анализ данных android.icu для таких зон, как «GMT», «Etc/GMT», «UTC», «Etc/UTC» и «Zulu».

    • java.text.SimpleDateFormat теперь использует ICU для предоставления отображаемых имен для UTC/GMT, что означает:
      • Форматирование zzzz создает длинную локализованную строку для многих локалей. Раньше он создавал «UTC» для UTC и строки типа «GMT+00:00» для GMT.
      • Анализ zzzz распознает такие строки, как «Всемирное координированное время» и «Среднее время по Гринвичу».
      • Приложения могут столкнуться с проблемами совместимости, если предполагают, что для zzzz на всех языках выводятся «UTC» или «GMT+00:00».
    • Поведение java.text.DateFormatSymbols.getZoneStrings() изменилось:
      • Как и в случае с SimpleDateFormat , UTC и GMT теперь имеют длинные имена. Варианты названий часовых поясов летнего времени для зоны UTC, такие как «UTC», «Etc/UTC» и «Zulu», становятся GMT+00:00, что является стандартным запасным вариантом, когда нет доступных имен, а не жестко закодированная строка UTC .
      • Некоторые идентификаторы зон правильно распознаются как синонимы других зон, поэтому Android находит строки для устаревших идентификаторов зон, таких как Eire , которые ранее не могли быть разрешены.
    • Азия/Ханой больше не является признанной зоной. По этой причине java.util.TimeZones.getAvailableIds() не возвращает это значение, а java.util.TimeZone.getTimeZone() не распознает его. Такое поведение соответствует существующему поведению android.icu .
  • Метод android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) может вызывать исключение ParseException даже при анализе текста допустимой валюты. Избегайте этой проблемы, используя NumberFormat.parseCurrency , доступный начиная с Android 7.0 (уровень API 24), для текста валюты в стиле PLURALCURRENCYSTYLE .

Изменения в тесте Android

В Android 9 внесено несколько изменений в библиотеку и структуру классов платформы Android Test. Эти изменения помогают разработчикам использовать общедоступные API, поддерживаемые платформой, но изменения также обеспечивают большую гибкость при создании и запуске тестов с использованием сторонних библиотек или пользовательской логики.

Библиотеки удалены из фреймворка

В Android 9 классы на основе JUnit реорганизуются в три библиотеки: android.test.base , android.test.runner и android.test.mock . Это изменение позволяет вам запускать тесты на той версии JUnit, которая лучше всего работает с зависимостями вашего проекта. Эта версия JUnit может отличаться от той, которую предоставляет android.jar .

Чтобы узнать больше о том, как классы на основе JUnit организованы в эти библиотеки, а также о том, как подготовить проект вашего приложения к написанию и запуску тестов, см. раздел Настройка проекта для Android Test .

Изменения в сборке тестового набора

Метод addRequirements() в классе TestSuiteBuilder был удален, а сам класс TestSuiteBuilder объявлен устаревшим. Метод addRequirements() требовал от разработчиков предоставления аргументов, типы которых являются скрытыми API, что делало API недействительным.

Java-декодер UTF

UTF-8 — это кодировка по умолчанию в Android. Последовательность байтов UTF-8 можно декодировать с помощью конструктора String , например String(byte[] bytes) .

Декодер UTF-8 в Android 9 более строго соответствует стандартам Unicode, чем в предыдущих версиях. Изменения включают в себя следующее:

  • Несамая короткая форма UTF-8, такая как <C0, AF> , считается неправильной.
  • Суррогатная форма UTF-8, такая как U+D800 .. U+DFFF , считается неправильной.
  • Максимальная часть заменяется одним U+FFFD . Например, в последовательности байтов « 41 C0 AF 41 F4 80 80 41 » максимальными частями являются « C0 », « AF » и « F4 80 80 ». « F4 80 80 » может быть начальной подпоследовательностью « F4 80 80 80 », но « C0 » не может быть начальной подпоследовательностью любой правильно сформированной последовательности кодовой единицы. Таким образом, результат должен быть « A\ufffd\ufffdA\ufffdA ».
  • Чтобы декодировать измененную последовательность UTF-8/CESU-8 в Android 9 или более поздней версии, используйте метод DataInputStream.readUTF() или метод JNI NewStringUTF() .

Проверка имени хоста с помощью сертификата

RFC 2818 описывает два метода сопоставления имени домена с сертификатом — использование доступных имен в расширении subjectAltName ( SAN ) или, при отсутствии расширения SAN , использование commonName ( CN ).

Однако возврат к CN объявлен устаревшим в RFC 2818. По этой причине Android больше не возвращается к использованию CN . Чтобы проверить имя хоста, сервер должен предоставить сертификат с соответствующим SAN . Сертификаты, которые не содержат SAN , соответствующий имени хоста, больше не считаются доверенными.

Поиск сетевых адресов может вызвать сетевые нарушения

Поиск сетевых адресов, требующий разрешения имен, может включать сетевой ввод-вывод и поэтому считается блокирующими операциями. Блокирование операций в основном потоке может привести к паузам или зависаниям.

Класс StrictMode — это инструмент разработки, который помогает разработчикам обнаруживать проблемы в их коде.

В Android 9 и более поздних версиях StrictMode обнаруживает сетевые нарушения, вызванные поиском сетевых адресов, требующим разрешения имен.

Не следует поставлять свои приложения с включенным StrictMode . Если вы это сделаете, то в ваших приложениях могут возникать исключения, такие как NetworkOnMainThreadException при использовании методов detectNetwork() detectAll() для получения политики, обнаруживающей сетевые нарушения.

Разрешение числового IP-адреса не считается операцией блокировки. Разрешение числовых IP-адресов работает так же, как и в версиях до Android 9.

Маркировка сокетов

В версиях платформы ниже Android 9, если сокет помечен с помощью метода setThreadStatsTag() , сокет не помечен, когда он отправляется в другой процесс с использованием связывателя IPC с контейнером ParcelFileDescriptor .

В Android 9 и более поздних версиях тег сокета сохраняется, когда он отправляется в другой процесс с помощью связывателя IPC. Это изменение может повлиять на статистику сетевого трафика, например, при использовании метода queryDetailsForUidTag() .

Если вы хотите сохранить поведение предыдущих версий, которые снимают теги с сокета, отправляемого другому процессу, вы можете вызвать untagSocket() перед отправкой сокета.

Сообщаемое количество доступных байтов в сокете

Метод available() возвращает 0 когда он вызывается после вызова метода shutdownInput() .

Более подробные отчеты о сетевых возможностях VPN.

В Android 8.1 (уровень API 27) и ниже класс NetworkCapabilities сообщал только ограниченный набор информации для VPN, например TRANSPORT_VPN , но опускал NET_CAPABILITY_NOT_VPN . Эта ограниченная информация затрудняла определение того, приведет ли использование VPN к взиманию платы с пользователя приложения. Например, проверка NET_CAPABILITY_NOT_METERED не позволит определить, измерялись ли базовые сети или нет.

В Android 9 и более поздних версиях, когда VPN вызывает метод setUnderlyingNetworks() , система Android объединяет транспорты и возможности любых базовых сетей и возвращает результат как эффективные сетевые возможности сети VPN.

В Android 9 и более поздних версиях приложения, которые уже проверяют NET_CAPABILITY_NOT_METERED получают сетевые возможности VPN и базовых сетей.

Файлы в папке xt_qtaguid больше не доступны приложениям.

Начиная с Android 9, приложениям не разрешен прямой доступ для чтения к файлам в папке /proc/net/xt_qtaguid . Причина в том, чтобы обеспечить согласованность с некоторыми устройствами, на которых эти файлы вообще отсутствуют.

Публичные API, использующие эти файлы, TrafficStats и NetworkStatsManager , продолжают работать должным образом. Однако неподдерживаемые функции Cutils , такие как qtaguid_tagSocket() , могут работать не так, как ожидалось, или вообще не работать на разных устройствах.

Требование FLAG_ACTIVITY_NEW_TASK теперь применяется.

В Android 9 вы не можете запустить действие из контекста бездействия, если не передадите флаг намерения FLAG_ACTIVITY_NEW_TASK . Если вы попытаетесь запустить действие без передачи этого флага, действие не запустится, и система выведет сообщение в журнал.

Изменения поворота экрана

Начиная с Android 9, в режим поворота портретной ориентации внесены существенные изменения. В Android 8.0 (уровень API 26) пользователи могли переключаться между режимами автоматического поворота и портретного поворота с помощью плитки быстрых настроек или настроек дисплея. Портретный режим был переименован в « Блокировку вращения» и активен, когда автоматический поворот отключен. В режиме автоповорота изменений нет.

Когда устройство находится в режиме блокировки поворота, пользователи могут заблокировать свой экран для любого поворота, поддерживаемого верхним видимым действием. Действие не должно предполагать, что оно всегда будет отображаться в портретной ориентации. Если верхнее действие может быть отображено в нескольких поворотах в режиме автоматического поворота, те же параметры должны быть доступны в режиме блокировки вращения, за некоторыми исключениями, основанными на настройке screenOrientation действия (см. таблицу ниже).

Действия, запрашивающие определенную ориентацию (например, screenOrientation=landscape ), игнорируют предпочтения блокировки пользователя и ведут себя так же, как в Android 8.0.

Предпочтение ориентации экрана можно установить на уровне активности в манифесте Android или программно с помощью setRequestedOrientation() .

Режим блокировки вращения работает путем установки предпочтений вращения пользователя, которые WindowManager использует при обработке вращения действий. Предпочтение ротации пользователей может быть изменено в следующих случаях. Обратите внимание, что существует тенденция возврата к естественному повороту устройства, который обычно является портретным для устройств форм-фактора телефона:

  • Когда пользователь принимает предложение о ротации, предпочтение ротации меняется на это предложение.
  • Когда пользователь переключается на приложение с принудительной портретной ориентацией (включая экран блокировки или панель запуска), предпочтение поворота меняется на портретное.

В следующей таблице приведены сведения о поведении вращения для распространенных ориентаций экрана:

Ориентация экрана Поведение
не указано, пользователь При автоматическом повороте и блокировке вращения действие можно отображать в книжной или альбомной ориентации (и наоборот). Ожидайте поддержку как книжной, так и альбомной ориентации.
ПользовательЛандшафт При автоматическом повороте и блокировке вращения действие может отображаться как в альбомной, так и в обратной альбомной ориентации. Ожидайте поддержку только альбомной ориентации.
Пользовательский портрет При автоматическом повороте и блокировке вращения активность может отображаться как в портретной, так и в обратной портретной ориентации. Ожидайте поддержку только книжной ориентации.
полный пользователь При автоматическом повороте и блокировке вращения действие можно отображать в книжной или альбомной ориентации (и наоборот). Ожидайте поддержку как книжной, так и альбомной ориентации.

Пользователям блокировки поворота будет предоставлена ​​возможность заблокировать перевернутую портретную ориентацию, часто на 180°.
сенсор, полныйСенсор, сенсорПортрет, сенсорЛандшафт Предпочтение режима блокировки вращения игнорируется и рассматривается как активный автоматический поворот. Используйте это только в исключительных случаях и с очень тщательным учетом UX.

Устаревание HTTP-клиента Apache влияет на приложения с нестандартным ClassLoader

В Android 6.0 мы удалили поддержку HTTP-клиента Apache . Это изменение не повлияет на подавляющее большинство приложений, не предназначенных для Android 9 или более поздних версий. Однако это изменение может повлиять на некоторые приложения, использующие нестандартную структуру ClassLoader , даже если эти приложения не предназначены для Android 9 или более поздней версии.

Приложение может быть затронуто, если оно использует нестандартный ClassLoader , который явно делегирует системному ClassLoader . Вместо этого этим приложениям необходимо делегировать приложение ClassLoader при поиске классов в org.apache.http.* . Если они делегируют системному ClassLoader , приложения на Android 9 или более поздних версиях завершатся с ошибкой NoClassDefFoundError , поскольку эти классы больше не известны системному ClassLoader . Чтобы предотвратить подобные проблемы в будущем, приложения обычно должны загружать классы через ClassLoader приложения, а не обращаться к системному ClassLoader напрямую.

Перечисление камер

Приложения, работающие на устройствах Android 9, могут обнаружить каждую доступную камеру, вызвав getCameraIdList() . Приложение не должно предполагать, что устройство имеет только одну заднюю камеру или только одну переднюю камеру.

Например, если в вашем приложении есть кнопка для переключения между передней и задней камерами, на выбор может быть несколько передних или задних камер. Вам следует просмотреть список камер, изучить характеристики каждой камеры и решить, какие камеры предоставить пользователю.

,

Android 9 (уровень API 28) вносит ряд изменений в систему Android. Следующие изменения поведения применяются ко всем приложениям , работающим на платформе Android 9, независимо от уровня API, на который они нацелены. Всем разработчикам следует просмотреть эти изменения и модифицировать свои приложения для их надлежащей поддержки, если это применимо к приложению.

Изменения, которые затрагивают только приложения, ориентированные на уровень API 28 или выше, см. в разделе Изменения поведения: приложения, ориентированные на уровень API 28+ .

Управление питанием

В Android 9 представлены новые функции для улучшения управления питанием устройства. Эти изменения, а также функции, которые уже присутствовали до Android 9, помогают обеспечить доступность системных ресурсов для приложений, которые в них нуждаются больше всего.

Подробности см. в разделе Управление питанием .

Изменения конфиденциальности

Чтобы повысить конфиденциальность пользователей, в Android 9 внесено несколько изменений поведения, таких как ограничение доступа фоновых приложений к датчикам устройства, ограничение информации, получаемой при сканировании Wi-Fi, а также новые правила разрешений и группы разрешений, связанные с телефонными звонками, состоянием телефона и Wi-Fi. Fi сканирует.

Эти изменения затрагивают все приложения, работающие на Android 9, независимо от целевой версии SDK.

Ограниченный доступ к датчикам в фоновом режиме

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

  • Ваше приложение не может получить доступ к микрофону или камере.
  • Датчики, использующие режим непрерывной отчетности, такие как акселерометры и гироскопы, не получают событий.
  • Датчики, использующие режимы отчетов при изменении или однократном сообщении, не получают событий.

Если вашему приложению необходимо обнаруживать события датчиков на устройствах под управлением Android 9, используйте службу переднего плана .

Ограниченный доступ к журналам вызовов

В Android 9 представлена ​​группа разрешений CALL_LOG и перемещены разрешения READ_CALL_LOG , WRITE_CALL_LOG и PROCESS_OUTGOING_CALLS в эту группу. В предыдущих версиях Android эти разрешения находились в группе разрешений PHONE .

Эта группа разрешений CALL_LOG дает пользователям лучший контроль и видимость приложений, которым необходим доступ к конфиденциальной информации о телефонных звонках, например чтение записей телефонных звонков и определение телефонных номеров.

Если вашему приложению требуется доступ к журналам вызовов или обработка исходящих вызовов, вы должны явно запросить эти разрешения у группы разрешений CALL_LOG . В противном случае возникает SecurityException .

Примечание. Поскольку эти разрешения изменили группы и предоставляются во время выполнения, пользователь может запретить вашему приложению доступ к информации журналов телефонных вызовов. В этом случае ваше приложение должно иметь возможность корректно справляться с отсутствием доступа к информации.

Если ваше приложение уже следует рекомендациям по разрешениям во время выполнения , оно может обработать изменение группы разрешений.

Ограниченный доступ к телефонным номерам

Приложения, работающие на Android 9, не могут считывать номера телефонов или состояние телефона без предварительного получения разрешения READ_CALL_LOG в дополнение к другим разрешениям, которые требуются для сценариев использования вашего приложения.

Номера телефонов, связанные с входящим и исходящим вызовами, отображаются в широковещательной передаче состояния телефона , например, для входящих и исходящих вызовов, и доступны из класса PhoneStateListener . Однако без разрешения READ_CALL_LOG поле номера телефона, предоставляемое в широковещательных рассылках PHONE_STATE_CHANGED и через PhoneStateListener , пусто.

Чтобы читать номера телефонов из состояния телефона, обновите приложение, чтобы оно запрашивало необходимые разрешения в зависимости от вашего варианта использования:

Ограниченный доступ к данным о местоположении и подключении Wi-Fi.

В Android 9 требования к разрешениям приложения на сканирование Wi-Fi более строгие, чем в предыдущих версиях. Подробную информацию см. в разделе Ограничения сканирования Wi-Fi .

Аналогичные ограничения также применяются к методу getConnectionInfo() , который возвращает объект WifiInfo , описывающий текущее соединение Wi-Fi. Вы можете использовать методы этого объекта для получения значений SSID и BSSID только в том случае, если вызывающее приложение имеет следующие разрешения:

  • ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

Для получения SSID или BSSID также необходимо включить службы определения местоположения на устройстве (в разделе «Настройки» > «Местоположение »).

Информация удалена из методов обслуживания Wi-Fi.

В Android 9 следующие события и трансляции не получают информацию о местоположении пользователя или личные данные:

Системная трансляция NETWORK_STATE_CHANGED_ACTION из Wi-Fi больше не содержит SSID (ранее EXTRA_SSID), BSSID (ранее EXTRA_BSSID) или информацию о соединении (ранее EXTRA_NETWORK_INFO). Если вашему приложению нужна эта информация, вместо этого вызовите getConnectionInfo() .

Информация о телефонии теперь зависит от настроек местоположения устройства.

Если пользователь отключил определение местоположения устройства на устройстве под управлением Android 9, следующие методы не дадут результатов:

Ограничения на использование интерфейсов, отличных от SDK.

Чтобы обеспечить стабильность и совместимость приложения, платформа ограничивает использование некоторых методов и полей, отличных от SDK; эти ограничения применяются независимо от того, пытаетесь ли вы получить доступ к этим методам и полям напрямую, через отражение или с помощью JNI. В Android 9 ваше приложение может продолжать получать доступ к этим ограниченным интерфейсам; платформа использует всплывающие уведомления и записи журнала, чтобы привлечь к ним ваше внимание. Если в вашем приложении отображается такое всплывающее уведомление, важно, чтобы вы придерживались стратегии реализации, отличной от ограниченного интерфейса. Если вы считаете, что никакая альтернативная стратегия невозможна, вы можете сообщить об ошибке и потребовать пересмотра ограничения.

Ограничения на интерфейсы без SDK содержат дополнительную важную информацию. Вам следует просмотреть его, чтобы убедиться, что ваше приложение продолжает работать правильно.

Изменения в поведении безопасности

Изменения безопасности устройства

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

Изменения реализации TLS

Реализация TLS в системе претерпела несколько изменений в Android 9:

  • Если экземпляру SSLSocket не удается подключиться во время его создания, система выдает IOException вместо NullPointerException .
  • Класс SSLEngine аккуратно обрабатывает любые возникающие оповещения close_notify .

Дополнительные сведения о выполнении безопасных веб-запросов в приложении Android см. в разделе «Пример HTTPS» .

Более строгий фильтр SECOMP

Android 9 дополнительно ограничивает системные вызовы, доступные приложениям. Такое поведение является расширением фильтра SECCOMP, который включен в Android 8.0 (уровень API 26) .

Криптографические изменения

В Android 9 внесено несколько изменений в реализацию и обработку криптографических алгоритмов.

Коншифровать реализации параметров и алгоритмов

Android 9 предоставляет дополнительные реализации параметров алгоритма в Conscrypt . К этим параметрам относятся: AES, DESEDE, OAEP и EC. Версии этих параметров и многих алгоритмов в Bouncy Castle устарели, начиная с Android 9.

Если ваше приложение предназначено для Android 8.1 (уровень API 27) или ниже, вы получите предупреждение при запросе реализации Bouncy Castle одного из этих устаревших алгоритмов. Однако если вы ориентируетесь на Android 9, каждый из этих запросов генерирует NoSuchAlgorithmException .

Другие изменения

В Android 9 представлено несколько других изменений, связанных с криптографией:

  • Если при использовании ключей PBE Bouncy Castle ожидает вектор инициализации (IV), а ваше приложение его не предоставляет, вы получите предупреждение.
  • Реализация шифра ARC4 в Conscrypt позволяет указать либо ARC4/ECB/NoPadding , либо ARC4/NONE/NoPadding .
  • Поставщик криптографической архитектуры Java (JCA) был удален. В результате, если ваше приложение вызывает SecureRandom.getInstance("SHA1PRNG", "Crypto") , возникает NoSuchProviderException .
  • Если ваше приложение анализирует ключи RSA из буферов, размер которых превышает структуру ключей, исключение больше не возникает.

Дополнительные сведения об использовании криптографических возможностей Android см. в разделе Криптография .

Безопасные зашифрованные файлы Android больше не поддерживаются.

В Android 9 полностью удалена поддержка безопасных зашифрованных файлов Android (ASEC).

В Android 2.2 (уровень API 8) Android представил ASEC для поддержки функций приложений на SD-карте. В Android 6.0 (уровень API 23) платформа представила адаптируемую технологию устройств хранения данных , которую разработчики могут использовать вместо ASEC.

Обновления библиотек ICU

Android 9 использует библиотеку ICU версии 60. Android 8.0 (уровень API 26) и Android 8.1 (уровень API 27) используют ICU 58.

ICU используется для предоставления общедоступных API в android.icu package и используется внутри платформы Android для поддержки интернационализации. Например, он используется для реализации классов Android в java.util , java.text и android.text.format .

Обновление ICU 60 содержит множество небольших, но полезных изменений, включая поддержку данных Emoji 5.0 и улучшенные форматы даты и времени, как описано в примечаниях к выпуску ICU 59 и ICU 60.

Заметные изменения в этом обновлении:

  • То, как платформа обрабатывает часовые пояса, изменилось.
    • Платформа лучше обрабатывает GMT и UTC; UTC больше не является синонимом GMT.

      ICU теперь предоставляет переведенные названия зон для GMT и UTC. Это изменение влияет на форматирование форматирования android.icu и поведение анализа для зон, таких как «GMT», «и т. Д./GMT», «UTC», «и т. Д./UTC» и «Зулу».

    • java.text.SimpleDateFormat теперь использует ICU для предоставления имен отображения для UTC /GMT, значение:
      • Форматирование zzzz генерирует длинную локализованную строку для многих мест. Ранее он производил «UTC» для UTC и струн, таких как «GMT+00: 00» для GMT.
      • Расположение zzzz распознает такие струны, как «Универсальное скоординированное время», и «Среднее время Гринвича».
      • Приложения могут столкнуться с проблемами совместимости, если они предполагают, что «UTC» или «Gmt+00: 00: 00» выводится для zzzz на всех языках.
    • Поведение java.text.DateFormatSymbols.getZoneStrings() изменилось:
      • Как и в случае с SimpleDateFormat , UTC и GMT теперь имеют длинные имена. Варианты DST вариантов часовых поясов для зоны UTC, таких как «UTC», «ETC/UTC» и «Zulu», станьте GMT+00: 00, что является стандартным отрывом, когда нет доступных имен, а не Строка с жесткой кодировкой UTC .
      • Некоторые идентификаторы зоны правильно распознаются как синонимы для других зон, так что Android находит строки для идентификаторов архаичной зоны, таких как Eire , которые ранее не могли быть разрешены.
    • Азия/Ханой больше не является признанной зоной. По этой причине java.util.TimeZones.getAvailableIds() не возвращает это значение, и java.util.TimeZone.getTimeZone() не распознает его. Такое поведение согласуется с существующим поведением android.icu .
  • Метод android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) может выбросить ParseException , даже при пакете законного текста валюты. Избегайте этой проблемы, используя NumberFormat.parseCurrency , доступную с момента Android 7.0 (API -уровне 24), для текста валюты в стиле PLURALCURRENCYSTYLE .

Андоид Тест изменения

Android 9 вводит несколько изменений в библиотеку библиотеки и структуры Class Framework Android. Эти изменения помогают разработчикам использовать общедоступные API-интерфейсы, поддерживаемые структурой, но изменения также позволяют получить большую гибкость в создании и запуске тестов, используя сторонние библиотеки или пользовательскую логику.

Библиотеки удалены из рамки

Android 9 реорганизует классы на базе JUNIT в три библиотеки: Android.test.base , Android.test.Runner и Android.test.Mock . Это изменение позволяет вам запускать тесты против версии Junit, которая лучше всего работает с зависимостью вашего проекта. Эта версия Junit может отличаться от той, которую предоставляет android.jar .

Чтобы узнать больше о том, как в этих библиотеках организованы классы на базе JUNIT, а также о том, как подготовить проект вашего приложения для написания и запуска тестов, см. Project Set Up для Android Test .

Тестовые изменения в сборе набора

Метод addRequirements() в классе TestSuiteBuilder был удален, и сам класс TestSuiteBuilder был устарел. Метод addRequirements() потребовал, чтобы разработчики подавали аргументы, типы которых являются скрытыми API, что делает API недействительным.

Java UTF Декодер

UTF-8-charset по умолчанию в Android. Последовательность UTF-8 байтов может быть декодирована String конструктором, таким как String(byte[] bytes) .

Декодер UTF-8 в Android 9 соответствует стандартам Unicode более строго, чем в предыдущих версиях. Изменения включают следующее:

  • Неопределенная форма UTF-8, такая как <C0, AF> , рассматривается как плохо сформированная.
  • Суррогатная форма UTF-8, такая как U+D800 .. U+DFFF , рассматривается как плохо сформированная.
  • Максимальный подраздел заменяется одним U+FFFD . Например, в последовательности байта « 41 C0 AF 41 F4 80 80 41 , «максимальные подразделы -« C0 »,« AF », и« F4 80 80 ». « F4 80 80 » может быть начальной последующей последовательностью « F4 80 80 80 », но « C0 » не может быть начальной последующей последовательностью любой хорошо сформированной последовательности кода. Таким образом, вывод должен быть « A\ufffd\ufffdA\ufffdA ».
  • Чтобы расшифровать модифицированную последовательность UTF-8 / CESU-8 в Android 9 или выше, используйте метод DataInputStream.readUTF() или метод NewStringUTF() JNI.

Проверка имени хоста с использованием сертификата

RFC 2818 описывает два метода, чтобы соответствовать доменному имени с сертификатом - используя доступные имена в рамках subjectAltName ( SAN ) или в отсутствие расширения SAN , возвращаясь к commonName ( CN ).

Тем не менее, запасной удар в CN был устарел в RFC 2818. По этой причине Android больше не возвращается к использованию CN . Чтобы проверить имя хоста, сервер должен представить сертификат с соответствующим SAN . Сертификатам, которые не содержат SAN , соответствующего имени хоста, больше не доверяют.

Поиск сетевых адресов может вызвать нарушения сети

Поиск сетевых адресов, которые требуют разрешения имен, могут включать сетевой ввод -вывод и поэтому считаются операциями блокировки. Блокировка операций на главной резьбе может вызвать паузы или казнь.

Класс StrictMode - это инструмент разработки, который помогает разработчикам обнаружить проблемы в своем коде.

В Android 9 и выше StrictMode обнаруживает нарушения сети, вызванные поиском сетевых адресов, которые требуют разрешения имен.

Вы не должны отправлять свои приложения с включенной StrictMode . Если вы это сделаете, то ваши приложения могут испытывать исключения, такие как NetworkOnMainThreadException при использовании методов detectNetwork() или detectAll() для получения политики, которая обнаруживает нарушения сети.

Решение числового IP -адреса не считается операцией блокировки. Числовое разрешение IP -адреса работает так же, как в версиях до Android 9.

Тегинг сокета

В версиях платформы ниже, чем Android 9, если сокет помечается с использованием метода setThreadStatsTag() , розетка не натмевается, когда он отправляется в другой процесс с использованием связующего IPC с контейнером ParcelFileDescriptor .

В Android 9 и выше тег сокета сохраняется, когда он отправляется в другой процесс с использованием Binder IPC. Это изменение может повлиять на статистику сетевого трафика, например, при использовании метода queryDetailsForUidTag() .

Если вы хотите сохранить поведение предыдущих версий, которые разворачивают розетку, которое отправляется в другой процесс, вы можете назвать untagSocket() перед отправкой гнезда.

Сообщаемое количество доступных байтов в розетке

Метод available() возвращает 0 при вызове после вызова метода shutdownInput() .

Более подробная отчетность о сетевых возможностях для VPN

В Android 8.1 (API -уровне 27) и ниже, класс NetworkCapabilities сообщил только о ограниченном наборе информации для VPN, такой как TRANSPORT_VPN , но опустил NET_CAPABILITY_NOT_VPN . Эта ограниченная информация затрудняет определение того, приведет ли использование VPN к пользователю приложения. Например, проверка NET_CAPABILITY_NOT_METERED не будет определять, были ли базовые сети измерены или нет.

В Android 9 и выше, когда VPN вызывает метод setUnderlyingNetworks() , система Android объединяет транспорты и возможности любых базовых сетей и возвращает результат в качестве эффективных сетевых возможностей сети VPN.

В Android 9 и выше приложения, которые уже проверяют на NET_CAPABILITY_NOT_METERED получают сетевые возможности VPN и базовых сетей.

Файлы в папке XT_QTAGUID больше не доступны для приложений

Начиная с Android 9, приложениям не разрешается иметь прямой доступ к чтению файлов в папке /proc/net/xt_qtaguid . Причина в том, чтобы обеспечить согласованность с некоторыми устройствами, у которых нет этих файлов вообще.

Общественные API, которые полагаются на эти файлы, TrafficStats и NetworkStatsManager , продолжают работать в соответствии с задумами. Тем не менее, неподдерживаемые функции Cutils , такие как qtaguid_tagSocket() , могут не работать, как и ожидалось или вообще - на разных устройствах.

FLAG_ACTIVITION_NEW_TASK теперь применяется

С помощью Android 9 вы не можете начать деятельность из контекста неактивности, если вы не пройдете на FLAG FLAG FLAG_ACTIVITY_NEW_TASK . Если вы пытаетесь запустить деятельность, не проходя этот флаг, деятельность не запускается, и система печатает сообщение в журнал.

Вращение экрана меняется

Начиная с Android 9, существуют значительные изменения в режиме вращения портрета . В Android 8.0 (API-уровне 26) пользователи могут переключаться между режимами автоматического ротации и портрета , используя настройки QuickSettings Tile или дисплея. Портретный режим был переименован в блокировку вращения , и он активен, когда автоматическое переключение переключено. В режиме автоматического режима нет изменений.

Когда устройство находится в режиме блокировки вращения, пользователи могут заблокировать свой экран на любое вращение, поддерживаемое верхней, видимой активностью. Деятельность не должна предполагать, что оно всегда будет отображаться в портрете. Если верхняя активность может быть отображена в нескольких вращениях в режиме автоматического перехода, те же параметры должны быть доступны в режиме блокировки вращения, за некоторыми исключениями на основе настройки screenOrientation активности (см. Таблицу ниже).

Действия, которые запрашивают конкретную ориентацию (например, screenOrientation=landscape ) игнорируют предпочтения блокировки пользователя и ведут себя так же, как в Android 8.0.

Предпочтение ориентации экрана может быть установлено на уровне активности в манифесте Android или программно с SetRequestOrientation () .

Режим блокировки вращения работает, установив предпочтения вращения пользователя, которое использует Windowmanager при обращении с вращением активности. Предпочтение вращения пользователя может быть изменено в следующих случаях. Обратите внимание, что существует предвзятость, чтобы вернуться к естественному вращению устройства, которое обычно является портретом для устройств форм -фактора телефона:

  • Когда пользователь принимает предложение о ротации, предпочтение вращения изменяется в предложении.
  • Когда пользователь переключается на приложение принудительного портрета (включая экран блокировки или пусковую установку), предпочтение вращения изменяется на портрет.

В следующей таблице приведено поведение вращения для общей ориентации экрана:

Ориентация на экран Поведение
Неучетный, пользователь В автоматическом ротации и блокировке вращения деятельность может быть отображена в портрете или ландшафте (и наоборот). Ожидайте поддержать как портретные, так и ландшафтные макеты.
UserlandScape В автоматическом ротации и блокировке вращения деятельность может быть оказана в ландшафте или в обратном ландшафте. Ожидайте поддержать только ландшафтные макеты.
userPortrait В автоматическом перевороте и блокировке вращения деятельность может быть отображена либо в портрете, либо в обратном портрете. Ожидайте поддержать только макеты портретов.
Fulluser В автоматическом ротации и блокировке вращения деятельность может быть отображена в портрете или ландшафте (и наоборот). Ожидайте поддержать как портретные, так и ландшафтные макеты.

Пользователям вращения будет предоставлена ​​возможность заблокировать для перевода портрета, часто 180º.
датчик, фуллсенсор, Sensorportrait, SensorlandScape Предпочтение режима блокировки вращения игнорируется и обрабатывается так, как будто активна автоматическая доходность. Используйте это только в исключительных обстоятельствах с очень тщательным учетом UX.

Apache HTTP Client Demercation влияет на приложения с нестандартным классовым загрузчиком

С Android 6.0 мы удалили поддержку клиента Apache HTTP . Это изменение не влияет на подавляющее большинство приложений, которые не нацелены на Android 9 или выше. Тем не менее, изменение может повлиять на определенные приложения, которые используют нестандартную структуру ClassLoader , даже если приложения не нацелены на Android 9 или выше.

Приложение может быть затронуто, если оно использует нестандартный ClassLoader , который явно делегирует в системный ClassLoader . Эти приложения должны вместо этого делегировать в приложение ClassLoader при поиске классов в org.apache.http.* . Если они делегируют в системный ClassLoader , приложения не будут в сборе на Android 9 или выше с NoClassDefFoundError , потому что эти классы больше не известны системному ClassLoader . Чтобы предотвратить аналогичные проблемы в будущем, приложения должны в целом загружать классы через ClassLoader приложения, а не обращаться к системному ClassLoader .

Перечисление камер

Приложения, работающие на устройствах Android 9, могут обнаружить каждую доступную камеру, вызывая getCameraIdList() . Приложение не должно предполагать, что устройство имеет только одну заднюю камеру или только одну фронтальную камеру.

Например, если в вашем приложении есть кнопка для переключения между передней и задней камерами, может быть более одной передней или задней камеры. Вы должны пройти список камеры, изучить характеристики каждой камеры и решить, какие камеры можно подвергать пользователю.

,

Android 9 (API -уровень 28) вводит ряд изменений в системе Android. Следующие изменения поведения применяются ко всем приложениям , когда они работают на платформе Android 9, независимо от уровня API, на который они нацелены. Все разработчики должны просмотреть эти изменения и изменить свои приложения для правильной поддержки, где это применимо к приложению.

Для изменений, которые влияют только на приложения, которые нацелены на уровень API 28 или выше, см. Изменения поведения: приложения, нацеленные на уровень API 28+ .

Управление энергетикой

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

Для получения подробной информации см. Управление энергетикой .

Замена конфиденциальности

Чтобы повысить конфиденциальность пользователей, Android 9 вводит несколько изменений поведения, таких как ограничение доступа фоновых приложений к датчикам устройств, ограничение информации, полученной от сканирования Wi-Fi, а также новые правила разрешения и группы разрешений, связанные с телефонными звонками, состоянием телефона и Wi- FI сканирование.

Эти изменения влияют на все приложения, работающие на Android 9, независимо от целевой версии SDK.

Ограниченный доступ к датчикам на фоне

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

  • Ваше приложение не может получить доступ к микрофону или камере.
  • Датчики, которые используют режим непрерывной отчетности, такие как акселерометры и гироскопы, не получают события.
  • Датчики, которые используют режимы отчетности или одноразовый отчетность, не получают события.

Если ваше приложение необходимо обнаружить события датчиков на устройствах под управлением Android 9, используйте службу переднего плана .

Ограниченный доступ к журналам вызовов

Android 9 представляет группу разрешений CALL_LOG и перемещает разрешения READ_CALL_LOG , WRITE_CALL_LOG и PROCESS_OUTGOING_CALLS в эту группу. В предыдущих версиях Android эти разрешения были расположены в группе разрешений PHONE .

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

Если ваше приложение требует доступа к журналам вызовов или необходимости обрабатывать исходящие вызовы, вы должны явно запросить эти разрешения в группе разрешений CALL_LOG . В противном случае происходит SecurityException .

ПРИМЕЧАНИЕ. Поскольку эти разрешения изменили группы и предоставляются во время выполнения, пользователь может отказаться от доступа вашего приложения для информации о журналах телефонных звонков. В этом случае ваше приложение должно иметь возможность обработать отсутствие доступа к информации изящно.

Если ваше приложение уже следит за лучшими практиками разрешений на выполнение , оно может обрабатывать изменение группы разрешений.

Ограниченный доступ к номерам телефонов

Приложения, работающие на Android 9, не могут читать номера телефонов или состояние телефона без сначала получения разрешения READ_CALL_LOG , в дополнение к другим разрешениям, которые требуются варианты использования вашего приложения.

Телефонные номера, связанные с входящими и исходящими звонками, видны в трансляции штата телефон , например, для входящих и исходящих звонков и доступны из класса PhoneStateListener . Однако без разрешения READ_CALL_LOG поле номера телефона, которое предоставляется в трансляции PHONE_STATE_CHANGED и через PhoneStateListener , пусто.

Чтобы прочитать телефонные номера из состояния телефона, обновите свое приложение, чтобы запросить необходимые разрешения на основе вашего варианта использования:

Ограниченный доступ к местоположению Wi-Fi и подключению

В Android 9 требования разрешения для приложения для выполнения сканирования Wi-Fi более строгие, чем в предыдущих версиях. Подробнее см. Ограничения сканирования Wi-Fi .

Аналогичные ограничения также применимы к методу getConnectionInfo() , который возвращает объект WifiInfo , описывающий текущее соединение Wi-Fi. Вы можете использовать методы этого объекта для получения значений SSID и BSSID, если у приложения вызовов есть следующие разрешения:

  • Access_fine_location или access_coarse_location
  • Access_wifi_state

Для получения SSID или BSSID также требуется, чтобы службы местоположения были включены на устройство (в разделе «Настройки> местоположение »).

Информация, удаленная из методов обслуживания Wi-Fi

В Android 9 следующие события и трансляции не получают информацию о местоположении пользователя или лично идентифицируемых данных:

Система NETWORK_STATE_CHANGED_ACTION , транслирующая от Wi-Fi, больше не содержит SSID (ранее Extra_ssid), BSSID (ранее Extra_BSSID) или информацию об соединении (ранее Extra_Network_info). Если вашему приложению нужна эта информация, вызовите getConnectionInfo() вместо этого.

Информация о телефонии теперь полагается на настройку местоположения устройства

Если пользователь отключен местоположение устройства на устройстве, работающее на Android 9, следующие методы не дают результатов:

Ограничения на использование не-SDK-интерфейсов

Чтобы обеспечить стабильность и совместимость приложения, платформа ограничивает использование некоторых не SDK-методов и полей; Эти ограничения применяются, если вы пытаетесь получить доступ к этим методам и полям напрямую, посредством отражения или использования JNI. В Android 9 ваше приложение может продолжать доступ к этим ограниченным интерфейсам; Платформа использует тосты и записывает записи, чтобы привлечь их к вам. Если ваше приложение показывает такой тост, важно, чтобы вы занимались стратегией реализации, кроме ограниченного интерфейса. Если вы чувствуете, что никакой альтернативной стратегии невозможна, вы можете подать ошибку для запроса пересмотра ограничения.

Ограничения на не-SDK-интерфейсы содержат дополнительную важную информацию. Вы должны просмотреть его, чтобы убедиться, что ваше приложение продолжает функционировать должным образом.

Поведение безопасности меняется

Изменения в безопасности устройства

Android 9 добавляет несколько возможностей, которые повышают безопасность вашего приложения, независимо от того, на какую версию нацелены на ваше приложение.

Изменения реализации TLS

Реализация системы TLS претерпела несколько изменений в Android 9:

  • Если экземпляр SSLSocket не может подключаться во время его создания, система бросает IOException вместо NullPointerException .
  • Класс SSLEngine чисто обрабатывает любые возникающие оповещения close_notify .

Чтобы узнать больше о выполнении безопасных веб -запросов в приложении Android, см. Пример HTTPS .

Более строгий фильтр seccomp

Android 9 еще больше ограничивает системные вызовы, доступные для приложений. Такое поведение является расширением фильтра SecComp, который включает Android 8.0 (уровень API 26) .

Криптографические изменения

Android 9 вводит несколько изменений в реализацию и обработку криптографических алгоритмов.

Реализации созрипта параметров и алгоритмов

Android 9 предоставляет дополнительные реализации параметров алгоритма в Совесщике . Эти параметры включают в себя: AES, DESEED, OAEP и EC. Версии этих параметров и множество алгоритмов устарели от Android 9.

Если ваше приложение предназначено для Android 8.1 (уровень 27) или ниже, вы получаете предупреждение при запросе реализации Buncy Castle одного из этих устаревших алгоритмов. Однако, если вы нацелитесь на Android 9, каждый из них запрашивает, каждый бросает NoSuchAlgorithmException .

Другие изменения

Android 9 вводит несколько других изменений, связанных с криптографией:

  • При использовании клавиш PBE, если Buncy Castle ожидает вектор инициализации (IV), а ваше приложение не предоставляет его, вы получаете предупреждение.
  • Реализация созрипта шифра ARC4 позволяет указать либо ARC4/ECB/NOPADDING , либо ARC4/NOT/NOPADDING .
  • Поставщик крипто -криптографии архитектуры криптографии (JCA) был удален. В результате, если ваше приложение вызывает SecureRandom.getInstance("SHA1PRNG", "Crypto") , происходит NoSuchProviderException .
  • Если ваше приложение анализирует клавиши RSA из буферов, которые больше, чем ключевая структура, исключение больше не происходит.

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

Android безопасные зашифрованные файлы больше не поддерживаются

Android 9 полностью удаляет поддержку Android Secure Encrypted Files (ASEC).

В Android 2.2 (API-уровне 8) Android представил ASEC для поддержки функций Apps-On-SD-Card. На Android 6.0 (API -уровне 23) платформа представила технологию устройства для хранения , которую разработчики могут использовать вместо ASEC.

Обновления библиотек ICU

Android 9 использует версию 60 библиотеки ICU. Android 8.0 (API -уровень 26) и Android 8.1 (API -уровень 27) используют ICU 58.

ICU используется для предоставления публичных API под android.icu package и используется внутренне на платформе Android для поддержки интернационализации. Например, он используется для реализации классов Android в java.util , java.text и android.text.format .

Обновление ICU 60 содержит много небольших, но полезных изменений, включая поддержку данных Emoji 5.0 и улучшенные форматы даты/времени, как задокументировано в примечаниях ICU 59 и ICU 60.

Примечательные изменения в этом обновлении:

  • То, как платформа обрабатывает часовые пояса, изменилось.
    • Платформа лучше обрабатывает GMT и UTC; UTC больше не является синонимом GMT.

      ICU теперь предоставляет переведенные названия зон для GMT и UTC. Это изменение влияет на форматирование форматирования android.icu и поведение анализа для зон, таких как «GMT», «и т. Д./GMT», «UTC», «и т. Д./UTC» и «Зулу».

    • java.text.SimpleDateFormat теперь использует ICU для предоставления имен отображения для UTC /GMT, значение:
      • Форматирование zzzz генерирует длинную локализованную строку для многих мест. Ранее он производил «UTC» для UTC и струн, таких как «GMT+00: 00» для GMT.
      • Расположение zzzz распознает такие струны, как «Универсальное скоординированное время», и «Среднее время Гринвича».
      • Приложения могут столкнуться с проблемами совместимости, если они предполагают, что «UTC» или «Gmt+00: 00: 00» выводится для zzzz на всех языках.
    • Поведение java.text.DateFormatSymbols.getZoneStrings() изменилось:
      • Как и в случае с SimpleDateFormat , UTC и GMT теперь имеют длинные имена. Варианты DST вариантов часовых поясов для зоны UTC, таких как «UTC», «ETC/UTC» и «Zulu», станьте GMT+00: 00, что является стандартным отрывом, когда нет доступных имен, а не Строка с жесткой кодировкой UTC .
      • Некоторые идентификаторы зоны правильно распознаются как синонимы для других зон, так что Android находит строки для идентификаторов архаичной зоны, таких как Eire , которые ранее не могли быть разрешены.
    • Азия/Ханой больше не является признанной зоной. По этой причине java.util.TimeZones.getAvailableIds() не возвращает это значение, и java.util.TimeZone.getTimeZone() не распознает его. Такое поведение согласуется с существующим поведением android.icu .
  • Метод android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) может выбросить ParseException , даже при пакете законного текста валюты. Избегайте этой проблемы, используя NumberFormat.parseCurrency , доступную с момента Android 7.0 (API -уровне 24), для текста валюты в стиле PLURALCURRENCYSTYLE .

Андоид Тест изменения

Android 9 вводит несколько изменений в библиотеку библиотеки и структуры Class Framework Android. Эти изменения помогают разработчикам использовать общедоступные API-интерфейсы, поддерживаемые структурой, но изменения также позволяют получить большую гибкость в создании и запуске тестов, используя сторонние библиотеки или пользовательскую логику.

Библиотеки удалены из рамки

Android 9 реорганизует классы на базе JUNIT в три библиотеки: Android.test.base , Android.test.Runner и Android.test.Mock . Это изменение позволяет вам запускать тесты против версии Junit, которая лучше всего работает с зависимостью вашего проекта. Эта версия Junit может отличаться от той, которую предоставляет android.jar .

Чтобы узнать больше о том, как в этих библиотеках организованы классы на базе JUNIT, а также о том, как подготовить проект вашего приложения для написания и запуска тестов, см. Project Set Up для Android Test .

Тестовые изменения в сборе набора

Метод addRequirements() в классе TestSuiteBuilder был удален, и сам класс TestSuiteBuilder был устарел. Метод addRequirements() потребовал, чтобы разработчики подавали аргументы, типы которых являются скрытыми API, что делает API недействительным.

Java UTF Декодер

UTF-8-charset по умолчанию в Android. Последовательность UTF-8 байтов может быть декодирована String конструктором, таким как String(byte[] bytes) .

Декодер UTF-8 в Android 9 соответствует стандартам Unicode более строго, чем в предыдущих версиях. Изменения включают следующее:

  • Неопределенная форма UTF-8, такая как <C0, AF> , рассматривается как плохо сформированная.
  • Суррогатная форма UTF-8, такая как U+D800 .. U+DFFF , рассматривается как плохо сформированная.
  • Максимальный подраздел заменяется одним U+FFFD . Например, в последовательности байта « 41 C0 AF 41 F4 80 80 41 , «максимальные подразделы -« C0 »,« AF », и« F4 80 80 ». « F4 80 80 » может быть начальной последующей последовательностью « F4 80 80 80 », но « C0 » не может быть начальной последующей последовательностью любой хорошо сформированной последовательности кода. Таким образом, вывод должен быть « A\ufffd\ufffdA\ufffdA ».
  • Чтобы расшифровать модифицированную последовательность UTF-8 / CESU-8 в Android 9 или выше, используйте метод DataInputStream.readUTF() или метод NewStringUTF() JNI.

Проверка имени хоста с использованием сертификата

RFC 2818 описывает два метода, чтобы соответствовать доменному имени с сертификатом - используя доступные имена в рамках subjectAltName ( SAN ) или в отсутствие расширения SAN , возвращаясь к commonName ( CN ).

Тем не менее, запасной удар в CN был устарел в RFC 2818. По этой причине Android больше не возвращается к использованию CN . Чтобы проверить имя хоста, сервер должен представить сертификат с соответствующим SAN . Сертификатам, которые не содержат SAN , соответствующего имени хоста, больше не доверяют.

Поиск сетевых адресов может вызвать нарушения сети

Поиск сетевых адресов, которые требуют разрешения имен, могут включать сетевой ввод -вывод и поэтому считаются операциями блокировки. Блокировка операций на главной резьбе может вызвать паузы или казнь.

Класс StrictMode - это инструмент разработки, который помогает разработчикам обнаружить проблемы в своем коде.

В Android 9 и выше StrictMode обнаруживает нарушения сети, вызванные поиском сетевых адресов, которые требуют разрешения имен.

Вы не должны отправлять свои приложения с включенной StrictMode . Если вы это сделаете, то ваши приложения могут испытывать исключения, такие как NetworkOnMainThreadException при использовании методов detectNetwork() или detectAll() для получения политики, которая обнаруживает нарушения сети.

Решение числового IP -адреса не считается операцией блокировки. Числовое разрешение IP -адреса работает так же, как в версиях до Android 9.

Тегинг сокета

В версиях платформы ниже, чем Android 9, если сокет помечается с использованием метода setThreadStatsTag() , розетка не натмевается, когда он отправляется в другой процесс с использованием связующего IPC с контейнером ParcelFileDescriptor .

В Android 9 и выше тег сокета сохраняется, когда он отправляется в другой процесс с использованием Binder IPC. Это изменение может повлиять на статистику сетевого трафика, например, при использовании метода queryDetailsForUidTag() .

Если вы хотите сохранить поведение предыдущих версий, которые разворачивают розетку, которое отправляется в другой процесс, вы можете назвать untagSocket() перед отправкой гнезда.

Сообщаемое количество доступных байтов в розетке

Метод available() возвращает 0 при вызове после вызова метода shutdownInput() .

Более подробная отчетность о сетевых возможностях для VPN

В Android 8.1 (API -уровне 27) и ниже, класс NetworkCapabilities сообщил только о ограниченном наборе информации для VPN, такой как TRANSPORT_VPN , но опустил NET_CAPABILITY_NOT_VPN . Эта ограниченная информация затрудняет определение того, приведет ли использование VPN к пользователю приложения. Например, проверка NET_CAPABILITY_NOT_METERED не будет определять, были ли базовые сети измерены или нет.

В Android 9 и выше, когда VPN вызывает метод setUnderlyingNetworks() , система Android объединяет транспорты и возможности любых базовых сетей и возвращает результат в качестве эффективных сетевых возможностей сети VPN.

В Android 9 и выше приложения, которые уже проверяют на NET_CAPABILITY_NOT_METERED получают сетевые возможности VPN и базовых сетей.

Файлы в папке XT_QTAGUID больше не доступны для приложений

Начиная с Android 9, приложениям не разрешается иметь прямой доступ к чтению файлов в папке /proc/net/xt_qtaguid . Причина в том, чтобы обеспечить согласованность с некоторыми устройствами, у которых нет этих файлов вообще.

Общественные API, которые полагаются на эти файлы, TrafficStats и NetworkStatsManager , продолжают работать в соответствии с задумами. Тем не менее, неподдерживаемые функции Cutils , такие как qtaguid_tagSocket() , могут не работать, как и ожидалось или вообще - на разных устройствах.

FLAG_ACTIVITION_NEW_TASK теперь применяется

С помощью Android 9 вы не можете начать деятельность из контекста неактивности, если вы не пройдете на FLAG FLAG FLAG_ACTIVITY_NEW_TASK . Если вы пытаетесь запустить деятельность, не проходя этот флаг, деятельность не запускается, и система печатает сообщение в журнал.

Вращение экрана меняется

Начиная с Android 9, существуют значительные изменения в режиме вращения портрета . В Android 8.0 (API-уровне 26) пользователи могут переключаться между режимами автоматического ротации и портрета , используя настройки QuickSettings Tile или дисплея. Портретный режим был переименован в блокировку вращения , и он активен, когда автоматическое переключение переключено. В режиме автоматического режима нет изменений.

Когда устройство находится в режиме блокировки вращения, пользователи могут заблокировать свой экран на любое вращение, поддерживаемое верхней, видимой активностью. Деятельность не должна предполагать, что оно всегда будет отображаться в портрете. Если верхняя активность может быть отображена в нескольких вращениях в режиме автоматического перехода, те же параметры должны быть доступны в режиме блокировки вращения, за некоторыми исключениями на основе настройки screenOrientation активности (см. Таблицу ниже).

Действия, которые запрашивают конкретную ориентацию (например, screenOrientation=landscape ) игнорируют предпочтения блокировки пользователя и ведут себя так же, как в Android 8.0.

Предпочтение ориентации экрана может быть установлено на уровне активности в манифесте Android или программно с SetRequestOrientation () .

Режим блокировки вращения работает, установив предпочтения вращения пользователя, которое использует Windowmanager при обращении с вращением активности. The user rotation preference might be changed in the following cases. Note that there is a bias to return to the device's natural rotation, which is normally portrait for phone form factor devices:

  • When the user accepts a rotation suggestion the rotation preference changes to the suggestion.
  • When the user switches to a forced portrait app (including the lock screen or the launcher) the rotation preference changes to portrait.

The following table summarizes rotation behavior for the common screen orientations:

Screen Orientation Поведение
unspecified, user In auto-rotate and rotation lock the Activity can be rendered in portrait or landscape (and the reverse). Expect to support both portrait and landscape layouts.
userLandscape In auto-rotate and rotation lock the Activity can be rendered in either landscape or reverse landscape. Expect to support only landscape layouts.
userPortrait In auto-rotate and rotation lock the Activity can be rendered in either portrait or reverse portrait. Expect to support only portrait layouts.
fullUser In auto-rotate and rotation lock the Activity can be rendered in portrait or landscape (and the reverse). Expect to support both portrait and landscape layouts.

Rotation lock users will be given the option to lock to reverse portrait, often 180º.
sensor, fullSensor, sensorPortrait, sensorLandscape The rotation lock mode preference is ignored and is treated as if auto-rotate is active. Only use this in exceptional circumstances with very careful UX consideration.

Apache HTTP client deprecation affects apps with non-standard ClassLoader

With Android 6.0, we removed support for the Apache HTTP client . This change has no effect on the great majority of apps that do not target Android 9 or higher. However, the change can affect certain apps that use a nonstandard ClassLoader structure, even if the apps do not target Android 9 or higher.

An app can be affected if it uses a non-standard ClassLoader that explicitly delegates to the system ClassLoader . These apps need to delegate to the app ClassLoader instead when looking for classes in org.apache.http.* . If they delegate to the system ClassLoader , the apps will fail on Android 9 or higher with a NoClassDefFoundError , because those classes are no longer known to the system ClassLoader . To prevent similar problems in the future, apps should in general load classes through the app ClassLoader rather than accessing the system ClassLoader directly.

Enumerating cameras

Apps running on Android 9 devices can discover every available camera by calling getCameraIdList() . An app should not assume that the device has only a single back camera or only a single front camera.

For example, if your app has a button to switch between the front and back cameras, there may be more than one front or back camera to choose from. You should walk the camera list, examine each camera's characteristics, and decide which cameras to expose to the user.

,

Android 9 (API level 28) introduces a number of changes to the Android system. The following behavior changes apply to all apps when they run on the Android 9 platform, regardless of the API level that they are targeting. All developers should review these changes and modify their apps to support them properly, where applicable to the app.

For changes that only affect apps that target API level 28 or higher, see Behavior changes: apps targeting API Level 28+ .

Power management

Android 9 introduces new features to improve device power management. These changes, along with features that were already present before Android 9, help to ensure that system resources are made available to the apps that need them the most.

For details, see Power management .

Privacy changes

To enhance user privacy, Android 9 introduces several behavior changes, such as limiting background apps' access to device sensors, restricting information retrieved from Wi-Fi scans, and new permission rules and permission groups related to phone calls, phone state, and Wi-Fi scans.

These changes affect all apps running on Android 9, regardless of target SDK version.

Limited access to sensors in background

Android 9 limits the ability for background apps to access user input and sensor data. If your app is running in the background on a device running Android 9, the system applies the following restrictions to your app:

  • Your app cannot access the microphone or camera.
  • Sensors that use the continuous reporting mode, such as accelerometers and gyroscopes, don't receive events.
  • Sensors that use the on-change or one-shot reporting modes don't receive events.

If your app needs to detect sensor events on devices running Android 9, use a foreground service .

Restricted access to call logs

Android 9 introduces the CALL_LOG permission group and moves the READ_CALL_LOG , WRITE_CALL_LOG , and PROCESS_OUTGOING_CALLS permissions into this group. In previous versions of Android, these permissions were located in the PHONE permission group.

This CALL_LOG permission group gives users better control and visibility to apps that need access to sensitive information about phone calls, such as reading phone call records and identifying phone numbers.

If your app requires access to call logs or needs to process outgoing calls, you must explicitly request these permissions from the CALL_LOG permission group. Otherwise, a SecurityException occurs.

Note: Because these permissions have changed groups and are granted at runtime, it's possible for the user to deny your app access to phone call logs information. In this case, your app should be able to handle the lack of access to information gracefully.

If your app is already following runtime permissions best practices , it can handle the change in permission group.

Restricted access to phone numbers

Apps running on Android 9 cannot read phone numbers or phone state without first acquiring the READ_CALL_LOG permission, in addition to the other permissions that your app's use cases require.

Phone numbers associated with incoming and outgoing calls are visible in the phone state broadcast , such as for incoming and outgoing calls and are accessible from the PhoneStateListener class. Without the READ_CALL_LOG permission, however, the phone number field that's provided in PHONE_STATE_CHANGED broadcasts and through PhoneStateListener is empty.

To read phone numbers from phone state, update your app to request the necessary permissions based on your use case:

Restricted access to Wi-Fi location and connection information

In Android 9, the permission requirements for an app to perform Wi-Fi scans are more strict than in previous versions. For details, see Wi-Fi scanning restrictions .

Similar restrictions also apply to the getConnectionInfo() method, which returns a WifiInfo object describing the current Wi-Fi connection. You can only use this object's methods to retrieve SSID and BSSID values if the calling app has the following permissions:

  • ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

Retrieving the SSID or BSSID also requires location services to be enabled on the device (under Settings > Location ).

Information removed from Wi-Fi service methods

In Android 9, the following events and broadcasts don't receive information about the user's location or personally identifiable data:

The NETWORK_STATE_CHANGED_ACTION system broadcast from Wi-Fi no longer contains SSID (previously EXTRA_SSID), BSSID (previously EXTRA_BSSID), or connection information (previously EXTRA_NETWORK_INFO). If your app needs this information, call getConnectionInfo() instead.

Telephony information now relies on device location setting

If the user has disabled device location on a device running Android 9, the following methods don't provide results:

Restrictions on use of non-SDK interfaces

To help ensure app stability and compatibility, the platform restricts the use of some non-SDK methods and fields; these restrictions apply whether you attempt to access these methods and fields directly, via reflection, or using JNI. In Android 9, your app can continue to access these restricted interfaces; the platform uses toasts and log entries to bring them to your attention. If your app shows such a toast, it is important that you pursue an implementation strategy other than the restricted interface. If you feel that no alternative strategy is feasible, you may file a bug to request reconsideration of the restriction.

Restrictions on Non-SDK Interfaces contains further important information. You should review it to ensure that your app continues to function properly.

Security behavior changes

Device security changes

Android 9 adds several capabilities that improve your app's security, regardless of which version your app targets.

TLS implementation changes

The system's TLS implementation has undergone several changes in Android 9:

To learn more about making secure web requests in an Android app, see An HTTPS example .

Stricter SECCOMP filter

Android 9 further restricts the system calls that are available to apps. This behavior is an extension of the SECCOMP filter that Android 8.0 (API level 26) includes .

Cryptographic changes

Android 9 introduces several changes to the implementation and handling of cryptographic algorithms.

Conscrypt implementations of parameters and algorithms

Android 9 provides additional implementations of algorithm parameters in Conscrypt . These parameters include: AES, DESEDE, OAEP, and EC. The Bouncy Castle versions of these parameters and many algorithms have been deprecated as of Android 9.

If your app targets Android 8.1 (API level 27) or lower, you receive a warning when requesting the Bouncy Castle implementation of one of these deprecated algorithms. If you target Android 9, however, these requests each throw a NoSuchAlgorithmException .

Other changes

Android 9 introduces several other changes related to cryptography:

  • When using PBE keys, if Bouncy Castle is expecting an initialization vector (IV) and your app doesn't supply one, you receive a warning.
  • The Conscrypt implementation of the ARC4 cipher allows you to specify either ARC4/ECB/NoPadding or ARC4/NONE/NoPadding .
  • The Crypto Java Cryptography Architecture (JCA) provider has been removed. As a result, if your app calls SecureRandom.getInstance("SHA1PRNG", "Crypto") , a NoSuchProviderException occurs.
  • If your app parses RSA keys from buffers that are larger than the key structure, an exception no longer occurs.

To learn more about using Android's cryptographic capabilities, see Cryptography .

Android secure encrypted files are no longer supported

Android 9 completely removes support for Android secure encrypted files (ASECs).

In Android 2.2 (API level 8), Android introduced ASECs to support apps-on-SD-card functionality. On Android 6.0 (API level 23), the platform introduced an adoptable storage device technology that developers can use in place of ASECs.

Updates to the ICU libraries

Android 9 uses version 60 of the ICU library. Android 8.0 (API level 26) and Android 8.1 (API level 27) use ICU 58.

ICU is used to provide public APIs beneath the android.icu package and is used internally in the Android platform for internationalization support. For example, it is used to implement Android classes in java.util , java.text , and android.text.format .

The update to ICU 60 contains many small but useful changes, including Emoji 5.0 data support and improved date/time formats, as documented in the ICU 59 and ICU 60 release notes.

Notable changes in this update:

  • The way the platform handles time zones has changed.
    • The platform handles GMT and UTC better; UTC is no longer a synonym for GMT.

      ICU now provides translated zone names for GMT and UTC. This change affects android.icu formatting and parsing behavior for zones like "GMT", "Etc/GMT", "UTC", "Etc/UTC", and "Zulu".

    • java.text.SimpleDateFormat now uses ICU to provide display names for UTC /GMT, meaning:
      • Formatting zzzz generates a long localized string for many locales. Previously, it produced "UTC" for UTC and strings like "GMT+00:00" for GMT.
      • Parsing zzzz recognizes strings like "Universal Coordinated Time", and "Greenwich Mean Time".
      • Apps may encounter compatibility problems if they assume that "UTC" or "GMT+00:00" are output for zzzz in all languages.
    • The behavior of java.text.DateFormatSymbols.getZoneStrings() has changed:
      • As with SimpleDateFormat , UTC and GMT now have long names. DST variants of time zone names for the UTC zone, such as "UTC", "Etc/UTC", and "Zulu", become GMT+00:00, which is the standard fallback when there are no names available, rather than the hard-coded string UTC .
      • Some zone IDs are correctly recognized as synonyms for other zones, so that Android finds strings for archaic zone IDs, such as Eire , that previously could not be resolved.
    • Asia/Hanoi is no longer a recognized zone. For this reason java.util.TimeZones.getAvailableIds() does not return this value, and java.util.TimeZone.getTimeZone() does not recognize it. This behavior is consistent with the existing android.icu behavior.
  • The android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) method may throw a ParseException even when parsing legitimate currency text. Avoid this problem by using NumberFormat.parseCurrency , available since Android 7.0 (API level 24), for PLURALCURRENCYSTYLE -style currency text.

Android Test changes

Android 9 introduces several changes to the Android Test framework's library and class structure. These changes help developers use framework-supported, public APIs, but the changes also allow for more flexibility in building and running tests using third-party libraries or custom logic.

Libraries removed from framework

Android 9 reorganizes the JUnit-based classes into three libraries: android.test.base , android.test.runner , and android.test.mock . This change allows you to run tests against a version of JUnit that works best with your project's dependencies. This version of JUnit might be different than the one that android.jar provides.

To learn more about how the JUnit-based classes are organized into these libraries, as well as how to prepare your app's project for writing and running tests, see Set up project for Android Test .

Test suite build changes

The addRequirements() method in the TestSuiteBuilder class has been removed, and the TestSuiteBuilder class itself been deprecated. The addRequirements() method had required developers to supply arguments whose types are hidden APIs, making the API invalid.

Java UTF decoder

UTF-8 is the default charset in Android. A UTF-8 byte sequence can be decoded by a String constructor, such as String(byte[] bytes) .

The UTF-8 decoder in Android 9 follows the Unicode standards more strictly than in previous versions. The changes include the following:

  • The non-shortest form of UTF-8, such as <C0, AF> , is treated as ill-formed.
  • The surrogate form of UTF-8, such as U+D800 .. U+DFFF , is treated as ill-formed.
  • The maximal subpart is replaced by a single U+FFFD . For example, in the byte sequence " 41 C0 AF 41 F4 80 80 41 ," the maximal subparts are " C0 ," " AF ," and " F4 80 80 ." " F4 80 80 " can be the initial subsequence of " F4 80 80 80 ", but " C0 " can't be the initial subsequence of any well-formed code unit sequence. Thus, the output should be " A\ufffd\ufffdA\ufffdA ."
  • To decode a modified UTF-8 / CESU-8 sequence in Android 9 or higher, use the DataInputStream.readUTF() method or the NewStringUTF() JNI method.

Hostname verification using a certificate

RFC 2818 describes two methods to match a domain name against a certificate—using the available names within the subjectAltName ( SAN ) extension, or in the absence of a SAN extension, falling back to the commonName ( CN ).

However, the fallback to the CN was deprecated in RFC 2818. For this reason, Android no longer falls back to using the CN . To verify a hostname, the server must present a certificate with a matching SAN . Certificates that don't contain a SAN matching the hostname are no longer trusted.

Network address lookups can cause network violations

Network address lookups that require name resolution can involve network I/O and are therefore considered blocking operations. Blocking operations on the main thread can cause pauses or jank.

The StrictMode class is a development tool that helps developers to detect problems in their code.

In Android 9 and higher, StrictMode detects network violations caused by network address lookups that require name resolution.

You should not ship your apps with StrictMode enabled. If you do, then your apps can experience exceptions, such as NetworkOnMainThreadException when using the detectNetwork() or detectAll() methods to get a policy that detects network violations.

Resolving a numeric IP address isn't considered a blocking operation. Numeric IP address resolution works the same as in versions before Android 9.

Socket tagging

In platform versions lower than Android 9, if a socket is tagged using the setThreadStatsTag() method, the socket is untagged when it's sent to another process using binder IPC with a ParcelFileDescriptor container.

In Android 9 and higher, the socket tag is kept when it's sent to another process using binder IPC. This change can affect network traffic statistics, for example, when using the queryDetailsForUidTag() method.

If you want to retain the behavior of the previous versions, which untags a socket that is sent to another process, you can call untagSocket() before sending the socket.

Reported amount of available bytes in socket

The available() method returns 0 when it's called after invoking the shutdownInput() method.

More detailed network capabilities reporting for VPNs

In Android 8.1 (API level 27) and lower, the NetworkCapabilities class only reported a limited set of information for VPNs, such as TRANSPORT_VPN , but omitting NET_CAPABILITY_NOT_VPN . This limited information made it difficult to determine if using a VPN would result in charges to the app's user. For example, checking NET_CAPABILITY_NOT_METERED would not determine whether the underlying networks were metered or not.

In Android 9 and higher, when a VPN calls the setUnderlyingNetworks() method, the Android system merges the transports and capabilities of any underlying networks and returns the result as the effective network capabilities of the VPN network.

In Android 9 and higher, apps that already check for NET_CAPABILITY_NOT_METERED receive the network capabilities of the VPN and the underlying networks.

Files in xt_qtaguid folder are no longer available to apps

Beginning with Android 9, apps are not allowed to have direct read access to files in the /proc/net/xt_qtaguid folder. The reason is to ensure consistency with some devices that don't have these files at all.

The public APIs that rely on these files, TrafficStats and NetworkStatsManager , continue to work as intended. However, the unsupported cutils functions, such as qtaguid_tagSocket() , may not work as expected—or at all— on different devices.

FLAG_ACTIVITY_NEW_TASK requirement is now enforced

With Android 9, you cannot start an activity from a non-activity context unless you pass the intent flag FLAG_ACTIVITY_NEW_TASK . If you attempt to start an activity without passing this flag, the activity does not start, and the system prints a message to the log.

Screen rotation changes

Beginning with Android 9, there are significant changes to the portrait rotation mode. In Android 8.0 (API level 26), users could toggle between auto-rotate and portrait rotation modes using a Quicksettings tile or Display settings. The portrait mode has been renamed rotation lock and it is active when auto-rotate is toggled off. There are no changes to auto-rotate mode.

When the device is in rotation lock mode, users can lock their screen to any rotation supported by the top, visible Activity. An Activity should not assume it will always be rendered in portrait. If the top Activity can be rendered in multiple rotations in auto-rotate mode, the same options should be available in rotation locked mode, with some exceptions based on the Activity's screenOrientation setting (see the table below).

Activities that request a specific orientation (for example, screenOrientation=landscape ) ignore the user lock preference and behave the same way as in Android 8.0.

The screen orientation preference can be set at the Activity level in the Android Manifest , or programmatically with setRequestedOrientation() .

The rotation lock mode works by setting the user rotation preference which the WindowManager uses when handling Activity rotation. The user rotation preference might be changed in the following cases. Note that there is a bias to return to the device's natural rotation, which is normally portrait for phone form factor devices:

  • When the user accepts a rotation suggestion the rotation preference changes to the suggestion.
  • When the user switches to a forced portrait app (including the lock screen or the launcher) the rotation preference changes to portrait.

The following table summarizes rotation behavior for the common screen orientations:

Screen Orientation Поведение
unspecified, user In auto-rotate and rotation lock the Activity can be rendered in portrait or landscape (and the reverse). Expect to support both portrait and landscape layouts.
userLandscape In auto-rotate and rotation lock the Activity can be rendered in either landscape or reverse landscape. Expect to support only landscape layouts.
userPortrait In auto-rotate and rotation lock the Activity can be rendered in either portrait or reverse portrait. Expect to support only portrait layouts.
fullUser In auto-rotate and rotation lock the Activity can be rendered in portrait or landscape (and the reverse). Expect to support both portrait and landscape layouts.

Rotation lock users will be given the option to lock to reverse portrait, often 180º.
sensor, fullSensor, sensorPortrait, sensorLandscape The rotation lock mode preference is ignored and is treated as if auto-rotate is active. Only use this in exceptional circumstances with very careful UX consideration.

Apache HTTP client deprecation affects apps with non-standard ClassLoader

With Android 6.0, we removed support for the Apache HTTP client . This change has no effect on the great majority of apps that do not target Android 9 or higher. However, the change can affect certain apps that use a nonstandard ClassLoader structure, even if the apps do not target Android 9 or higher.

An app can be affected if it uses a non-standard ClassLoader that explicitly delegates to the system ClassLoader . These apps need to delegate to the app ClassLoader instead when looking for classes in org.apache.http.* . If they delegate to the system ClassLoader , the apps will fail on Android 9 or higher with a NoClassDefFoundError , because those classes are no longer known to the system ClassLoader . To prevent similar problems in the future, apps should in general load classes through the app ClassLoader rather than accessing the system ClassLoader directly.

Enumerating cameras

Apps running on Android 9 devices can discover every available camera by calling getCameraIdList() . An app should not assume that the device has only a single back camera or only a single front camera.

For example, if your app has a button to switch between the front and back cameras, there may be more than one front or back camera to choose from. You should walk the camera list, examine each camera's characteristics, and decide which cameras to expose to the user.