Подготовка приложения к Android Q. Часть 1

Автор оригинала: Saurabh Arora
  • Перевод
Перевод статьи подготовлен специально для студентов курса «Android-разработчик. Базовый курс». Также напоминаем о том, что мы продолжаем набор на расширенный курс «Специализация Android-разработчик»





Мы находимся на 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 — целевая версия приложения; и Activity просто не запустится, если Android Q — не целевая версия SDK для приложения, но оно работает на устройстве с Android Q.
  • Исключения: Привязанные службы, такие как специальные возможности, автозаполнение и т. д. Если приложение получает 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).

б) Аппаратные идентификаторы


Доступ к несбрасываемым идентификаторам устройства был отменен в Android Q.

  • На что влияет: Все приложения, работающие на Q (независимо от целевого SDK). Генерируется исключение, если Q — это целевое SDK; и возвращается null, если целевое SDK меньше Q
  • Избегайте: Mac-адрес теперь рандомизирован, а IMEI (TelephonyManager.getDeviceId()) и серийный номер больше не доступны. Теперь они являются «привилегированными разрешениями» и доступны только для приложений операторов.
  • Рекомендуемый подход: используйте сбрасываемые идентификаторы, такие как Advertising ID, Instance ID или Globally-unique ID (GUID). См. Best practices for unique identifiers (Лучшие практики по использованию уникальных идентификаторов) для получения дополнительной информации о том, какой идентификатор использовать в каком случае.

в) Фоновое определение локации


Начиная с 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, как и обещали, поговорим во второй части.
  • +15
  • 5,1k
  • 9
OTUS. Онлайн-образование
807,00
Цифровые навыки от ведущих экспертов
Поделиться публикацией

Похожие публикации

Комментарии 9

    0
    Гугл слишком часто выпускает новые версии, ломающие уже существующий софт.
      0
      Все же ему еще очень далеко до WindowsPhone :)
        0

        Да наоборот, слишком редко. Они тормозят из-за этого с развитием ОС. Бич андроида это легаси код и обратная совместимость. iOS к счастью таким мало страдает.

          0
          Особой совместимости нет. Недавно пробовал софт выпущенный для второй версии — падает на андроиде 7 и 8.
          Могли бы выпускать ОС раз в 5 лет без обратной совместимости. В промежутках между этими большими обновлениями выпускать версиями для прогона новых функций на существующем железе.
            0

            есть параметр от которого зависит, будет ли работать приложение в режиме совместимости: targetSDKVersion. Если targetSDKVersion < OS API level, то андроид не будет применять все новые ограничения к приложению. Вангую у вас была ошибка с сервисами после того как перешли на targetSDKVersion 26 или выше :)

              0
              Одно из приложений просто игра Monster Zuma/ Системные требования: Android 1.6+

              Второе приложение ставится как сервис, сначала сыпет ошибками, но потом работает.

              P.S. Более свежий пример из 2016 года habr.com/ru/post/312516/#comment_20554613
        +6
        Самое печальное, что вся эта битва с фоновой работой приложений, от плодов которой Android разработчики страдают не один год, абсолютно бессмысленна, потому что главный пожиратель батареи — Google Play Servies — свободен от любых ограничений, более того, эти службы даже сам пользователь не может отключить. И координаты она собирает, кстати, когда ей вздумается
          0

          Конечно вина сервисов тоже есть. Но есть и другая сторона медали. Google services предоставляют апи приложениям. Очень много приложений используют сервисы для разных нужд. Например, следить за локацией, получать пуши, иметь доступ к firebase и тд. Все взаимодействие происходит через IPC. Андроид видит что сервисы что-то делают, но он не знает что за этим стоят приложения, которые используют апи для получения данных от гугл сервисов.

          0
          Вот с запуском активностей из фона это конечно печаль-беда. Они видимо решили пойти по стопам Apple. Поясняю задачу: есть сипофон и при входящем звонке естественно нужно быть заметным, чтобы пользователь не пропустил звонок. У нас сейчас всплывает активность с кнопками принять/отклонить вызов и имя контакта из системы (похожа по общему принципу на системную звонилку, но заметно от неё отличается — понятно, но не спутаешь). В таком случае отправлять уведомление вместо звонка — сомнительное удовольствие. Особенно, если телефон просто лежит или же наоборот пользователь находится в полноэкранном режиме.

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

          Самое читаемое