Изменения Android 6.0

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

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

Разрешения во время выполнения

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

В ваших приложениях, предназначенных для Android 6.0 (уровень API 23) или выше, обязательно проверяйте и запрашивайте разрешения во время выполнения. Чтобы определить, предоставлено ли вашему приложению разрешение, вызовите новый метод checkSelfPermission() . Чтобы запросить разрешение, вызовите новый метод requestPermissions() . Даже если ваше приложение не предназначено для Android 6.0 (уровень API 23), вам следует протестировать свое приложение с использованием новой модели разрешений.

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

Режим сна и режим ожидания приложения

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

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

Дополнительные сведения об этих изменениях в области энергосбережения см. в разделе Оптимизация режима сна и режима ожидания приложений .

Удаление HTTP-клиента Apache

В выпуске Android 6.0 удалена поддержка HTTP-клиента Apache. Если ваше приложение использует этот клиент и предназначено для Android 2.3 (уровень API 9) или более поздней версии, вместо этого используйте класс HttpURLConnection . Этот API более эффективен, поскольку сокращает использование сети за счет прозрачного сжатия и кэширования ответов, а также минимизирует энергопотребление. Чтобы продолжить использование HTTP API Apache, вы должны сначала объявить следующую зависимость времени компиляции в файле build.gradle :

android {
    useLibrary 'org.apache.http.legacy'
}

скучныйSSL

Android переходит от OpenSSL к библиотеке BoringSSL . Если вы используете Android NDK в своем приложении, не связывайтесь с криптографическими библиотеками, которые не являются частью API NDK, такими как libcrypto.so и libssl.so . Эти библиотеки не являются общедоступными API и могут изменяться или ломаться без предварительного уведомления в разных выпусках и устройствах. Кроме того, вы можете подвергнуть себя уязвимостям безопасности. Вместо этого измените свой собственный код, чтобы он вызывал API-интерфейсы шифрования Java через JNI или статически связывался с выбранной вами библиотекой шифрования.

Доступ к идентификатору оборудования

Чтобы обеспечить пользователям более высокий уровень защиты данных, начиная с этого выпуска Android удаляет программный доступ к локальному идентификатору оборудования устройства для приложений, использующих API Wi-Fi и Bluetooth. Методы WifiInfo.getMacAddress() и BluetoothAdapter.getAddress() теперь возвращают постоянное значение 02:00:00:00:00:00 .

Чтобы получить доступ к идентификаторам оборудования ближайших внешних устройств посредством сканирования Bluetooth и Wi-Fi, ваше приложение теперь должно иметь разрешения ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION :

Примечание . Когда устройство под управлением Android 6.0 (уровень API 23) инициирует фоновое сканирование Wi-Fi или Bluetooth, эта операция видна внешним устройствам как исходящая со случайного MAC-адреса.

Уведомления

В этом выпуске удален метод Notification.setLatestEventInfo() . Вместо этого используйте класс Notification.Builder для создания уведомлений. Чтобы неоднократно обновлять уведомление, повторно используйте экземпляр Notification.Builder . Вызовите метод build() , чтобы получить обновленные экземпляры Notification .

Команда adb shell dumpsys notification больше не распечатывает текст вашего уведомления. Вместо этого используйте команду adb shell dumpsys notification --noredact чтобы распечатать текст в объекте уведомления.

Изменения АудиоМенеджера

Установка громкости напрямую или отключение звука определенных потоков через класс AudioManager больше не поддерживается. Метод setStreamSolo() устарел, и вместо него следует вызвать метод requestAudioFocus() . Аналогично, метод setStreamMute() устарел; вместо этого вызовите метод adjustStreamVolume() и передайте значение направления ADJUST_MUTE или ADJUST_UNMUTE .

Выбор текста

Экран, демонстрирующий новые функции выделения текста на плавающей панели инструментов.

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

Чтобы реализовать плавающую панель инструментов для выделения текста, внесите следующие изменения в существующие приложения:

  1. В объекте View или Activity измените вызовы ActionMode с startActionMode(Callback) на startActionMode(Callback, ActionMode.TYPE_FLOATING) .
  2. Возьмите существующую реализацию ActionMode.Callback и вместо этого сделайте ее расширением ActionMode.Callback2 .
  3. Переопределите метод onGetContentRect() , чтобы предоставить координаты объекта Rect содержимого (например, прямоугольника выделения текста) в представлении.
  4. Если расположение прямоугольника больше недопустимо и это единственный элемент, который должен быть признан недействительным, вызовите метод invalidateContentRect() .

Если вы используете библиотеку поддержки Android версии 22.2, имейте в виду, что плавающие панели инструментов не имеют обратной совместимости, и appcompat по умолчанию берет на себя управление объектами ActionMode . Это предотвращает отображение плавающих панелей инструментов. Чтобы включить поддержку ActionMode в AppCompatActivity , вызовите getDelegate() , затем вызовите setHandleNativeActionModesEnabled() для возвращенного объекта AppCompatDelegate и установите для входного параметра значение false . Этот вызов возвращает управление объектами ActionMode в платформу. На устройствах под управлением Android 6.0 (уровень API 23) это позволяет платформе поддерживать режимы ActionBar или плавающей панели инструментов, а на устройствах под управлением Android 5.1 (уровень API 22) или ниже поддерживаются только режимы ActionBar .

Изменения закладок браузера

В этом выпуске удалена поддержка глобальных закладок. Методы android.provider.Browser.getAllBookmarks() и android.provider.Browser.saveBookmark() теперь удалены. Аналогичным образом удаляются разрешения READ_HISTORY_BOOKMARKS и WRITE_HISTORY_BOOKMARKS . Если ваше приложение предназначено для Android 6.0 (уровень API 23) или выше, не получайте доступ к закладкам глобального поставщика и не используйте разрешения для закладок. Вместо этого ваше приложение должно хранить данные закладок внутри себя.

Изменения в хранилище ключей Android

В этом выпуске поставщик хранилища ключей Android больше не поддерживает DSA. ECDSA по-прежнему поддерживается.

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

Изменения в Wi-Fi и сети

В этом выпуске представлены следующие изменения в поведении Wi-Fi и сетевых API.

  • Ваши приложения теперь могут изменять состояние объектов WifiConfiguration , только если вы создали эти объекты. Вам не разрешено изменять или удалять объекты WifiConfiguration , созданные пользователем или другими приложениями.
  • Раньше, если приложение заставляло устройство подключаться к определенной сети Wi-Fi с помощью enableNetwork() с настройкой disableAllOthers=true , устройство отключалось от других сетей, например, для передачи сотовых данных. В этом выпуске устройство больше не отключается от других сетей. Если targetSdkVersion вашего приложения имеет значение “20” или ниже, оно закрепляется за выбранной сетью Wi-Fi. Если targetSdkVersion вашего приложения имеет значение “21” или выше, используйте мультисетевые API (такие как openConnection() , bindSocket() и новый bindProcessToNetwork() ), чтобы гарантировать, что его сетевой трафик отправляется в выбранную сеть.

Изменения в сервисе камеры

В этом выпуске модель доступа к общим ресурсам в службе камеры была изменена с предыдущей модели доступа «первым пришел — первым обслужен» на модель доступа, в которой предпочтение отдается процессам с высоким приоритетом. Изменения в поведении службы включают в себя:

  • Доступ к ресурсам подсистемы камеры, включая открытие и настройку устройства камеры, предоставляется на основании «приоритета» процесса клиентского приложения. Прикладным процессам с действиями, видимыми пользователем или на переднем плане, обычно уделяется более высокий приоритет, что делает получение и использование ресурсов камеры более надежным.
  • Клиенты активной камеры для приложений с более низким приоритетом могут быть «выселены», когда приложение с более высоким приоритетом пытается использовать камеру. В устаревшем API Camera это приводит к вызову onError() для выселенного клиента. В API Camera2 это приводит к вызову onDisconnected() для выселенного клиента.
  • На устройствах с соответствующим аппаратным обеспечением камеры отдельные процессы приложений могут независимо открывать и одновременно использовать отдельные устройства камеры. Однако случаи использования нескольких процессов, когда одновременный доступ приводит к значительному снижению производительности или возможностей любого из открытых устройств камеры, теперь обнаруживаются и запрещаются службой камеры. Это изменение может привести к «вытеснению» клиентов с более низким приоритетом, даже если никакое другое приложение не пытается напрямую получить доступ к тому же устройству камеры.
  • Изменение текущего пользователя приводит к удалению активных клиентов камеры в приложениях, принадлежащих предыдущей учетной записи пользователя. Доступ к камере ограничен профилями пользователей, принадлежащими текущему пользователю устройства. На практике это означает, что учетная запись «Гость», например, не сможет покинуть запущенные процессы, использующие подсистему камеры, когда пользователь переключился на другую учетную запись.

Время выполнения

Среда выполнения ART теперь правильно реализует правила доступа для метода newInstance() . Это изменение устраняет проблему, из-за которой Dalvik неправильно проверял правила доступа в предыдущих версиях. Если ваше приложение использует метод newInstance() и вы хотите переопределить проверки доступа, вызовите метод setAccessible() с входным параметром, установленным в значение true . Если ваше приложение использует библиотеку appcompat v7 или библиотеку recyclerview v7 , вам необходимо обновить свое приложение, чтобы использовать последние версии этих библиотек. В противном случае убедитесь, что все пользовательские классы, на которые есть ссылки из XML, обновлены, чтобы их конструкторы классов были доступны.

В этом выпуске обновлено поведение динамического компоновщика. Динамический компоновщик теперь понимает разницу между soname библиотеки и ее путем ( публичная ошибка 6670 ), и теперь реализован поиск по soname . Работавшие ранее приложения с неверными записями DT_NEEDED (обычно абсолютные пути в файловой системе машины сборки) могут завершиться сбоем при загрузке.

Флаг dlopen(3) RTLD_LOCAL теперь реализован правильно. Обратите внимание, что RTLD_LOCAL используется по умолчанию, поэтому вызовы dlopen(3) , которые не использовали явно RTLD_LOCAL будут затронуты (если только ваше приложение явно не использовало RTLD_GLOBAL ). При использовании RTLD_LOCAL символы не будут доступны библиотекам, загруженным последующими вызовами dlopen(3) (в отличие от ссылок на записи DT_NEEDED ).

В предыдущих версиях Android, если ваше приложение запрашивало систему загрузку общей библиотеки с перемещением текста, система отображала предупреждение, но все равно разрешала загрузку библиотеки. Начиная с этого выпуска, система отклоняет эту библиотеку, если целевая версия SDK вашего приложения — 23 или выше. Чтобы помочь вам определить, не удалось ли загрузить библиотеку, ваше приложение должно зарегистрировать сбой dlopen(3) и включить текст описания проблемы, который возвращает вызов dlerror(3) . Дополнительные сведения об обработке перемещений текста см. в этом руководстве .

Проверка APK

Платформа теперь выполняет более строгую проверку APK. APK считается поврежденным, если файл объявлен в манифесте, но отсутствует в самом APK. APK необходимо повторно подписать, если какое-либо содержимое будет удалено.

USB-соединение

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

Изменения в Android для работы

Этот выпуск включает следующие изменения в поведении Android for Work:

  • Рабочие контакты в личном контексте. Журнал вызовов Google Dialer теперь отображает рабочие контакты, когда пользователь просматривает прошлые вызовы. Установка setCrossProfileCallerIdDisabled() значения true скрывает контакты рабочего профиля в журнале вызовов Google Dialer. Рабочие контакты могут отображаться вместе с личными контактами на устройствах через Bluetooth, только если вы установили для setBluetoothContactSharingDisabled() значение false . По умолчанию установлено значение true .
  • Удаление конфигурации Wi-Fi: конфигурации Wi-Fi, добавленные владельцем профиля (например, посредством вызовов метода addNetwork() ), теперь удаляются, если этот рабочий профиль удаляется.
  • Блокировка конфигурации Wi-Fi. Любая конфигурация Wi-Fi, созданная активным владельцем устройства, больше не может быть изменена или удалена пользователем, если WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN не равно нулю. Пользователь по-прежнему может создавать и изменять свои собственные конфигурации Wi-Fi. Владельцы активных устройств имеют право редактировать или удалять любые конфигурации Wi-Fi, в том числе созданные не ими.
  • Загрузите контроллер политики устройства через добавление учетной записи Google. Когда учетная запись Google, требующая управления через приложение контроллера политики устройства (DPC), добавляется к устройству вне управляемого контекста, поток добавления учетной записи теперь предлагает пользователю установить соответствующий WPC. Такое поведение также применимо к учетным записям, добавленным через «Настройки» > «Учетные записи» и в мастере начальной настройки устройства.
  • Изменения в конкретном поведении API DevicePolicyManager :
    • Вызов метода setCameraDisabled() влияет на камеру только вызывающего пользователя; вызов его из управляемого профиля не влияет на приложения камеры, работающие у основного пользователя.
    • Кроме того, метод setKeyguardDisabledFeatures() теперь доступен владельцам профилей, а также владельцам устройств.
    • Владелец профиля может установить следующие ограничения для клавиатуры:
    • Методы DevicePolicyManager.createAndInitializeUser() и DevicePolicyManager.createUser() устарели.
    • Метод setScreenCaptureDisabled() теперь также блокирует вспомогательную структуру, когда приложение данного пользователя находится на переднем плане.
    • EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM теперь по умолчанию имеет значение SHA-256. SHA-1 по-прежнему поддерживается для обратной совместимости, но в будущем он будет удален. EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM теперь принимает только SHA-256.
    • API-интерфейсы инициализатора устройства, существовавшие в Android 6.0 (уровень API 23), теперь удалены.
    • EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS удален, поэтому подготовка NFC не может программно разблокировать устройство, защищенное сбросом настроек.
    • Теперь вы можете использовать дополнительную опцию EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE для передачи данных в приложение владельца устройства во время подготовки NFC управляемого устройства.
    • API-интерфейсы Android for Work оптимизированы для разрешений среды выполнения M, включая рабочие профили, вспомогательный уровень и другие. Новые API-интерфейсы разрешений DevicePolicyManager не влияют на приложения pre-M.
    • Когда пользователи выходят из синхронной части потока настройки, инициированной посредством намерения ACTION_PROVISION_MANAGED_PROFILE или ACTION_PROVISION_MANAGED_DEVICE , система теперь возвращает код результата RESULT_CANCELED .
  • Изменения в других API :
    • Использование данных: класс android.app.usage.NetworkUsageStats был переименован NetworkStats .
  • Изменения в глобальных настройках :
    • Эти настройки больше нельзя установить с помощью setGlobalSettings() :
      • BLUETOOTH_ON
      • DEVELOPMENT_SETTINGS_ENABLED
      • MODE_RINGER
      • NETWORK_PREFERENCE
      • WIFI_ON
    • Эти глобальные настройки теперь можно установить с помощью setGlobalSettings() :