Подготовка приложения к Android Q. Часть 1
Мы находимся на 10-м году разработки Android (Android Q должен быть версией 10.0). В соответствии с Beta 4, официально у Android Q 29-й уровень API. Несмотря на то что уже есть Beta 5 и ожидается Beta 6, API был помечен как окончательный, и сейчас самое время посмотреть, как Android Q повлияет на приложения и какие изменения нужно внести, чтобы полностью поддерживать Android Q.
Важные изменения (не все), представленные в Android Q, можно разделить на две категории: а) Конфиденциальность и безопасность, б) User Experience.
От переводчика: «Мы разделили перевод на две части, соответствующие данным категориям. Соответственно, в первой части поговорим о конфиденциальности и безопасности».
Конфиденциальность и безопасность
1) Запуск фоновых Activity
Больше нельзя запустить Activity, когда ваше приложение находится в фоновом режиме.
На что влияет: Все приложения, работающие на Q (независимо от целевого SDK). Если Android Q — целевая версия приложения, то будет генерироваться исключение. Если же Android Q — не целевая версия SDK для приложения, но оно работает на устройстве с Android Q, то Activity просто не запустится.
Исключения: Привязанные службы (bound services), такие как специальные возможности, автозаполнение и т. д. Если приложение получает PendingIntent
от системы, мы можем использовать его для запуска Activity. Если у приложения есть разрешение SYSTEM_ALERT_WINDOW
(удалено в Android GO) или приложение недавно вызывало finish()
для Activity (не рекомендуется на это полагаться – «недавно» может быть очень неоднозначным), то ваше приложение свободно от этого ограничения.
Рекомендуемый подход: Уведомление, запускающее Activity
val fullScreenIntent = Intent(this, CallActivity::class.java) val fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .... .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_CALL) .setFullScreenIntent(fullScreenPendingIntent, true)
Добавьте Fullscreen PendingIntent
к уведомлению. Теперь, когда уведомление сработает, система запустит полноэкранный Intent.
Поэтому, если хотите запустить Activity из фонового режима, сначала создайте уведомление, которое будет показываться пользователю. В уведомлении добавьте Fullscreen PendingIntent
. А также укажите разрешение USE_FULL_SCREEN_INTENT
в манифесте. Теперь, когда уведомление сработает, система запустит полноэкранный Intent.
Подводные камни: Система решает, когда показывать уведомление и когда показывать Activity. Если пользователь активно использует устройство, то отображается всплывающее уведомление. Если устройство в состоянии покоя или когда пользователь взаимодействует с уведомлением, запускается полноэкранное Activity. Например, как при получении телефонного звонка (всплывающие уведомления во время использования телефона, в противном случае полноэкранное Activity).
2) Аппаратные идентификаторы
Доступ к несбрасываемым идентификаторам устройства был отменен в Android Q.
На что влияет: Все приложения, работающие на Q (независимо от целевого SDK). Если Q — это целевое SDK, то генерируется исключение. Если целевое SDK меньше Q, то возвращается null
.
Избегайте: Mac-адрес теперь рандомизирован, а IMEI (TelephonyManager.getDeviceId()
) и серийный номер больше не доступны. Теперь они являются «привилегированными разрешениями» и доступны только для приложений операторов.
Рекомендуемый подход: используйте сбрасываемые идентификаторы, такие как Advertising ID, Instance ID или Globally-unique ID (GUID). См. Best practices for unique identifiers (Лучшие практики по использованию уникальных идентификаторов) для получения дополнительной информации о том, какой идентификатор использовать в каком случае.
3) Определение локации в фоновом режиме
Начиная с Android Q, система будет различать запросы местоположения, сделанные на переднем плане и в фоне.
Запрос на разрешение доступа к местоположению теперь будет иметь 3 варианта: Разрешать все время, Разрешать только при использовании приложения (доступ только на переднем плане) и Запретить (нет доступа).
На что влияет: Это зависит от целевого SDK. Если Q — это целевое SDK для приложения, то вам нужно запросить новое разрешение на определение местоположения в фоновом режиме. Если у приложения другое целевое SDK, оно автоматически получит это разрешение, если уже имело права доступа к местоположению.
Изображение взято из документации для разработчиков Android
Рекомендуемый подход: Если приложению требуется однократный доступ к местоположению пользователя для выполнения некоторых задач, используйте службу переднего плана с параметром foregroundServiceType, заданным как location
в файле манифеста приложения.
<service android:name="MyNavigationService" android:foregroundServiceType="location" ... />
Если приложению необходим постоянный доступ к местоположению устройства, например, для геозонирования, то оно может настроить запрос на разрешение доступа к местоположению в фоновом режиме. Другие аспекты приложения (например, как местоположение извлекается и используется) менять не нужно. Чтобы запросить доступ к местоположению в фоновом режиме, добавьте в манифест разрешение ACCESS_BACKGROUND_LOCATION
:
<manifest> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> ... </manifest>
//Request for the permission like any other permission request: ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION), your-permission-request-code )
Напоминание, показываемое системой, о доступе к местоположению в фоновом режиме
Подводные камни:
Несколько важных вещей, о которых следует помнить: пользователь может получить напоминание после предоставления приложению доступа к местоположению устройства в фоновом режиме, и, как и любое другое разрешение, пользователь может отозвать разрешение на него. Это особенно важно для приложений, у которых Q не является целевым SDK, но работающих на устройствах с Android Q, поскольку оно получило бы фоновое разрешение по умолчанию, если бы у него было разрешение на определение местоположения. Убедитесь, что приложение изящно обрабатывает такие сценарии. По этой причине всякий раз, когда приложение запускает службу или запрашивает местоположение, проверьте, позволяет ли пользователь по-прежнему получать приложению доступ к информации о местоположении.
На этом первая часть статьи подошла к концу. А о User Experiences, как и обещали, поговорим во второй части.