Android Q Beta 1 — Обзор изменений для разработчиков
Хотите узнать больше интересных новостей из мира Android разработки — подписывайтесь на Telegram канал Android Broadcast
13 марта 2019 Google представил первую beta версию Android Q. Всего планируется 6 beta версий перед релизом, который состоится в 3-м квартале 2019. Как всегда, самое сладкое нас будет ждать в Beta 3, которую представят с открытием Google I/O 2019.
Вектор изменений в новой версии Android направлен на улучшение безопасности: обновление системы разрешений, ограничение доступа к файлам на внешнем хранилище, больше возможностей пользователю для контроля доступа приложений к различным данным и выполнению операций. Одно из нововведений — поддержка сгибаемых смартфонов, но его не представляется возможным проверить из-за отсутствия устройства или эмулятора.
Уже сейчас обладатели Pixel любого поколения могут установить бета версию, причем в этом году ее уже можно получить по воздуху. Для этого вам надо вступить в Android Beta Program.
Не рекомендую ставить эту версию Android на свое личное устройство, так как прошивка имеет известные проблемы и не готова для повседневного использования.
Давайте подробнее рассмотрим, что изменится для разработчиков при адаптации приложения для Android Q.
Безопасность
Доступ к файлам
Изменения затрагивают способы чтения/записи файлов на внешнем хранилище и безопасность данных:
- Разрешения READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE deprecated и заменены новыми группами разрешений, которые касаются отдельных местоположений в памяти.
- Для файлов приложений на внешнем хранилище теперь создается изолированная папка, к которой может иметь доступ только ваше приложение (раньше любое приложение с наличием разрешения READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE имело доступ к ней). Чтобы получить эту директорию разработчикам нужно использовать Context.getExternalFilesDir(String).
- Изменен способ доступа к пользовательским данным из общих коллекций (shared collections). Shared collections— это фото, видео, музыка и загрузки пользователя. Для файлов, созданных вашим приложением ничего не поменялось, вы также можете считывать/записывать, но есть вы хотите иметь доступ к файлам из общей коллекции, созданными другими приложениями, то вам нужно запрашивать специальные разрешения: READ_MEDIA_IMAGES, READ_MEDIA_VIDEOS, READ_MEDIA_AUDIO либо вашему приложению должна быть задана соотвествующая роль (о новом механизме ролей будет рассказано далее).
- Разрешение READ_MEDIA_DOWNLOADS нет. Приложение может получить доступ только к своим загруженным файлам, к прочим файлам доступ получить можно через системный провайдер файлов.
- Файлы, которые не попали в категории описаные выше могут быть получены с помощью ContentResolver и специального разрешения для доступа к этим данным либо с помощью Storage Access Framework.
- Доступ к местоположению в Exif информации фотографий теперь ограничен. Чтобы получить доступ к ней теперь надо запросить разрешение ACCESS_MEDIA_LOCATION и вызывать MediaStore.setRequireOriginal(Uri).
Для навигации по файлам используйте системный файловый менеджер, который можно открыть с помощью ACTION_OPEN_DOCUMENT_TREE.
Ограничения запуска Activity из фона
Чтобы не мешать пользователю, в новой версии Android теперь нельзя простым вызовом startActivity(Intent) запустить новую Activity. Приложение в Android Q может запустить Activity в случае если:
- Приложение имеет видимое окно, например Activity с которой взаимодействует пользователь.
- Другое приложение, с которым сейчас взаимодействует пользователь отправляет PendingIntent, относящийся к вашему приложению.
- Система отправляет PendingIntent, относящийся к вашему приложению, например, нажатие на уведомление в системной панели.
- Система отправляет broadcast вашему приложению, например ACTION_SECRET_CODE. В исключение попадают только те broadcast, которые потенциально могут запустить UI (список их я не нашел).
Замечание: приложение не считается видимым, если не имеет видимых Activity и имеет только Foreground Service.
Ограничения применяются для всех приложений, независимо от targetSdk вашего приложения. Вместо запуска Activity предлагается показывать уведомления со всей необходимой информацией для пользователя.
Ограничения доступа приложений к местоположению пользователя
- Больше контроля за местоположением у пользователя. Теперь пользователь может разрешать доступ к геопозиции только в то время, когда приложение находится на экране.
- Для получения местоположения приложением в фоне необходимо запрашивать специальное разрешение ACCESS_BACKGROUND_LOCATION в дополнение к ACCESS_FINE_LOCATION. Новое разрешение относится к группе dangerous поэтому, пользователь сможет в любой момент отозвать разрешение на получение геопозиции приложением в фоне.
- Запрос к геопозиции пользователя в фоне теперь отличается в зависимости от сценария: продолжение действий, инициарованных пользователем, или периодический доступ к геопозиции. При первом способе вам надо запускать Foreground Service и задать foregroundServiceType=”location” в манифесте при его регистрации. Если же вам не нужно гарантировать выполнения действий и отправки геопозиции, тогда вы можете использовать обычный Service, но должны учитывать, что пользователь может в любой момент отозвать разрешение и запросы к местоположению в фоне будут безуспешны.
Изменения в данных и идентификаторах
Изменения в данной категории касаются всех приложений, независимо от targetSdk≤ 28.
- Не сохраняются данные о использовании контактов пользователя. Как результат теперь при поиске контактов они больше не отсортированы по частоте использования.
- Случайная генерация MAC адреса. Устройста на Android Q передают MAC адрес, который случайно генерируется для каждой Wi-Fi сети.
- Закрыт доступ к информации о состоянии сети в /proc/net. Изменения коснутся VPN приложений, теперь им надо пользоваться NetworkStatsManager и ConnectivityManager.
- Ограничения доступа к неизменяемым идентификаторам устройства (IMEI, серийный номер и пр). Чтобы получить доступ к ним теперь вам надо иметь разрешение READ_PRIVILEGED_PHONE_STATE.
- Ограничение доступа к буферу обмена. Приложение может получить доступ к данным в буфере обмена только если оно является IME (клавиатурой) по умолчанию или сейчас находится в фокусе.
Прочие ограничения
- Ограничение получаемой информации о характеристиках камеры. CameraManager.getCameraCharacteristics() теперь не будет возвращать все данные о харатеристиках камеры, которые содержат информацию об устройстве. Чтобы получить все данные о камерах устройства, вам неоходимо получить разрешение CAMERA. Полный список полей, к которым был ограничен доступ, можно найти здесь.
- В Android Q нельзя программно включить/выключить Wi-Fi. На замену WifiManager.setWifiEnabled() пришла панель настроек, которая может отображать приложение (подробнее о ней читайте далее).
- Часть методов связанных с телефонией, Wi-FI и Bluetooth теперь требуют разрешние ACCESS_FINE_LOCATION. Полный список методов можно найти здесь.
- Возможность настройки списка Wi-Fi сетей теперь есть только у системных приложений.
Изменения в системных разрешениях
- Ограничение на доступ к данным с экрана (напр. получить текущее изображение на экране). Разрешения READ_FRAME_BUFFER, CAPTURE_VIDEO_OUTPUT и CAPTURE_SECURE_VIDEO_OUTPUT, которые раньше использовались для получения данных с экрана, теперь стали signature-access. Записать видео получится только у системных приложений, поэтому необходимо мигрировать на MediaProjection API, которое запрашивает разрешение пользователя.
- Для приложений с targetSdk≤22 теперь можно отозвать разрешение. Также при первом запуске приложение с таким targetSdk, пользователь увидит диалог с предупреждением о том, что приложение написано под старую версию Android.
- Для доступа к физической активности пользователя необходимо получить новое разрешение ACTIVITY_RECOGNITION. Данные о физической активности — это ваша активность: ходьба, бег, велотренировках и пр. Это дает возможность пользователю знать о том, какие приложения имеет доступе к сенсорам устройства.
- Для показа полноэкранных уведомлений (например, как при входящем звонке) теперь необходимо разрешение USE_FULL_SCREEN_INTENT. Без этого разрешения показ уведомления будет проигнорирован системой.
Новые функции и API в Android Q
Безопасность
- Можно настраивать необходимо ли подтверждение после биометрической авторизации. Например, это полезно перед тем как совершить покупку.
- Возможность задать способ альтернативной авторизации, если биометрическая не сработала, например ввод кода или пароли.
- Запуск вложенных DEX файлов напрямую из APK. Это помогает в предотвращении атаки на ваше устройство в случае, когда злоумышленник смог изменить локальный скомпилированный код на устройстве.
- Поддержка TLS 1.3.
- Публичный Conscrypt API.
Wi-Fi и Bluetooth
- Peer-to-peer connection API, позволяющий запросить пользователя сменить точку доступа.
- Wi-Fi network suggestion API, позволяющее предлагать пользователю из вашего приложения к какой точке доступа Wi-Fi лучше подключиться.
- Улучшения в Wi-Fi high-performance и low-latency режимах.
- Поддержка Wi-Fi Easy Connect, позволяющее подключаться к точкам доступа по Uri или QR коду. Не все устройства будут поддерживать эту функцию, перед ее использованием вызовите проверку WifiManager.isEasyConnectSupported().
- Wi-Fi Direct connection API. Обновление API касается быстрого подключения к Wi-Fi Direct на основе заранее заданной информации (имя сети, пароля и пр.).
- Поддержка Bluetooth LE Connection oriented Channels (CoC).
Телефония
- Сбор информации о качестве исходящих IP Multimedia Subsystem (IMS) звонков.
- Проверка вызовов и идентификация звонящего.
- API для переадресации исходящих вызовов. Например, с помощью CallRedirectionService, сторонние приложения могут отменять исходящий звонок и переадресовывать его через VoIP.
Медиа и графика
- Native MIDI API.
- Возможность получения новых данных о медиакодеках, доступных на устройстве, с помощью MediaCodecInfo. Теперь возможно узнать поддерживается ли аппаратное ускорение кодеком, предоставляется он производителем устройства либо является часть Android. Также появилась возможность получить performance point из кодека, который представляет собой информацию о размере кадра и частоте, которую может обработать кодек.
- Улучшение поддержки мононохромной камеры.
- Поддержка формата Dynamic Depth для камер. Начиная с Android Q, камера может записывать данные о глубине для изображения в отдельном файле. Это поможет приложению делать постобработку фотографий лучше, например делать размытие (blur).
- Поддерка Vulkan 1.1.
- Поддержка ANGLE — проект в Chrome который реализует ES слой поверх Vulkan. Подробнее смотрите ANGLE.
- Добавлена поддержка open source кодека AV1 и Opus. AV1 позволяет предоставлять трансляцию видео высокого качества на Android устройствах, используя меньшую пропускную способность.
Opus — это кодек, оптимизированный для речи и стриминга музыки. Также Opus включает поддержку HRD10+ для видео с расширенным динамическим диапазоном на устройствах.
Settings Panels
Новое API в Android Q — Settings Panel, которое позволяет показывать настройки пользователю в контексте вашего приложения. Это убирает необходимость выхода пользователя из вашего приложения, чтобы включить NFC или подключиться к точке доступа.
Сейчас в настройках можно сконфигурировать подключение к интернету, NFC и громкость. Кастомизировать диалог нельзя, он системный.
Роли (Roles)
В Android Q представлено стандартное средство — роли. Механизм позволяет задавать в системе приложение по умолчанию для определенной функции — роли. Это позволяет ОС предоставлять приложению расширенный доступ к системным функциям, основываясь на распространненых сценариях использования приложения. Каждая роль представляет собой один сценарий, например проигрывание музыки, просмотр фотографий в галерее или отправку SMS сообщений.
В Android Q Beta 1 есть следующие роли:
Внимание: список ролей и функций, соответствующих им, может измениться в будущих Beta версиях
Для того, чтобы получить роль, приложение должно соответствовать опеределенным требованиям. Если приложение потеряет свою роль, это вызовет потерю соответствующего доступа.
Больше подробностей читайте здесь.
Улучшения в Sharing
Sharing Shortcuts API
Механизм Direct Share API заменён новым Sharing Shortcuts API. Sharing Shortcut API позволяет вместо получения результатов по запросу публиковать их заранее, работая по аналогии с ShortcutManager. Это решает проблему низкой скорости Direct Share, так как старый механизм работал по принципу Pull, а новый — по Push.
Sharing Shortcut API очень похож по работе с ShortcutManager, поэтому авторы API просто расширили ShortcutInfo чтобы упростить работу с этими API.
Больше подробностей о Sharing Shirtcuts API можно найти здесь.
Direct Share останется работать, но будет иметь более низкий приоритет, чем Sharing Shortcuts.
Android Runtime (ART)
- Улучшение в производительности ART, которое позволяет ускорить запуск приложений и потреблять меньше памяти, без необходимости модификации чего либо со стороны разработчиков.
- Агрегированные ART профили, которые загружаются вместе с APK из Google Play. В отличие от работы на предыдущих версиях ОС, теперь собирается анонимная информация с нескольких устройств, а не только с одного.
- ART больше не позволяет выполнять dex2oat из процесса приложения, теперь только система может генерировать oat файлы.
- Скорость запуска процесса Zygote стала быстрее.
- Образ Heap-а приложения содержит больше данных, позволяющих ускорить загрузку образа.
- Добавлен Generation Garbage Collection в ART Concurrent Copying (CC) Garbage Collector. Generational CC более эффективный, так как собирает объекты young-generation отдельно, что делает стоимость очистки памяти более низкой по сравнению с full-heap GC.
Прочие изменения
- Ограничение доступа к интерфейсам не из SDK: новая порция в Q. В Android P уже были введены ограничения к непубличному API Android SDK через рефлексию, в Android Q пришла новая порция API.
- Все для Kotlin — больше Nullability аннотаций в SDK.
- Обновление Accessibility services API.
- Улучшения Autofill API.
- Обновление Android Enterprise.
- Изменения в NDK: обновление в сборке мусора JVM на основе информации из malloc() и улучшение дебага.
- SYSTEM_ALERT_WINDOW на Go устройствах теперь запрещен.
- Neural Networks API 1.2: добавлена поддержка 60+ новых операций.
- Поддержка складных смартфонов. Привет Galaxy Fold и Huawei Mate X!
Важно! Многие изменения еще не активированы, так как первая Beta предназчена только ознакомления разработчиков с изменением поведения ОС. Их можно включить через ADB либо в Developers Options.
Очень много интересных изменений происходят внутри Android SDK и не освещаются подробно. Я решил покопаться в API Diff Report и рассказать о том, что я обнаружил
Важно: информации о некоторых классах/интерфейсах очень мало и она может измениться в будущих Beta.
Новые классы
ZygotePreload
ZygotePreload — это интерфейс, который должен реализовывать класс, отвечающий за предзагрузку кода и данных приложения, которые будут доступны всем изолированным Service-ам, которые укажут в AndroidManifest android:useAppZygote=”true”.
Media API 2
В пакете android.media добавлены классы MediaPlayer2, MediaSession2, MediaController2 и пр. с версией “2” в конце имени. Суть отличий пока я найти не смог, ждем Google I/O.
RecoverableSecurityException
Новый exception RecoverableSecurityException, которые расширяет SecurityException и содержит информацию как пользователь может исправить проблему.
StatusBarManager
StatusBarManager дает возможность управлять Status Bar из приложения
Android Parcel
Добавлена поддержка boolean, ArrayMap<String, *> и List<Parcelable>
FileUtils
Файловые утилиты для копирования данных и закрытия некоторых источников, игнорируя ошибки.
android.graphics.font
Новый пакет, содержащий классы по работе со шрифтами: созданием, получением данных из них. Также появилась возможность получить системные шрифты.
Systrace
В класе Trace добавлена возможность записи выполнения асинхронных секций с помощью beginAsyncSection(String methodName, int cookie) и задание счетчика с setCounter (String counterName, long counterValue).
Deprecated
- Fragment API из Android SDK
- Loaders API
- Множество кода из android.preference
Notification
Добавлена возможность задавать системе может ли она генерировать action на основе контекста, например, для ответа на сообщение.
Одна из интересных новых API NotificationManager.setNotificationDelegate(String deleage), который позволяет задать приложение, которое может постить уведомления от имени вашего приложения. При этом запуск вашего приложения происходить не будет.
ZenPolicy
ZenPolicy определяет разрешать ли определенным уведомлениям проигрывать звуки и показывать визуальные эффекты, когда устройство находиться в “Do Not Disturb” режиме. К сожалению, я не смог найти где применяется этот класс.
Developers Options
Также произошло немного изменений в Developers Options:
- Невозможно принудительно задать темную тему. Настройка была удалена. Теперь это можно сделать только через adb
- “Allow background Activity starts” позволяющим принудительно вступить в силу новым изменениям
- “Force desktop mode”. О режиме десктопа уже ходили спойлеры, но пока от него только тумблер в настройках разработчика. Ждем Google I/O
- “Restrict SMS & call log access” включает доступ к SMS и журналу звонков только приложениям для SMS и звонков по умолчанию
- “Disable device identifiers restrictions” отключает новые ограничения по доступу к постоянным идентификаторам устройства
В заключение скажу, что обновление ОС получилось довольно интересным. Я считаю, что Google, начиная с Android 6 Marshmallow, взяла правильный курс на более строгий доступ к функционалу системы сторонними приложениями и увеличению безопасности работы пользователя, что заставляет разработчиков делать более качественный и безопасный софт. Также улучшению системы способствует то, что Google заставляет разработчиков раз в год адаптировать приложения под более новые версии ОС. Остается дождаться Google I/O 7–9 мая, чтобы узнать самые интересные анонсы, касательно Android Q и других продуктов Google.