Среди многообразия инструментов, анонсированных на Android Dev Summit, особое внимание хочется уделить механизму обновления приложения In-App Updates (IAUs), который помогает разработчикам ускорить добавление новых фич, баг-фиксов и улучшений производительности. Поскольку эта функциональность была опубликована после Google I/O 2019, в этой статье я подробно расскажу об IAUs, опишу рекомендованные схемы реализации и приведу некоторые примеры кода. Также я расскажу о нашем опыте интеграции IAUs в Pandao, приложение для заказа товаров из Китая.
Новый API позволяет разработчикам инициировать обновление приложения до последней доступной в Google Play версии. Таким образом IAUs дополняет уже существующий механизм автоматического обновления Google Play. IAUs содержит несколько схем реализации, которые принципиально различаются с точки зрения взаимодействия с пользователем.
Как исправить приложение Google Play Store/Chrome, которое не обновляется!
-
Flexible Flow предлагает пользователям скачать обновление в фоновом режиме и установить в удобное для пользователя время. Он предназначен для случаев, когда пользователи всё ещё могут использовать старую версию, но уже доступна новая.
Immediate Flow требует от пользователей скачать и установить обновление, прежде чем продолжить использование приложения. Он предназначен для случаев, когда для разработчиков критически важно обновить приложение.
Поскольку второй вариант не так важен и меньше подходит для приложения Pandao, разберём подробнее сценарий Flexible Flow.
Интеграция IAUs Flexible Flow
Варианты использования
Процесс обновления с помощью IAUs состоит из нескольких шагов.
- Приложение с помощью библиотеки Play Core, которая проверяет в Google Play, есть ли доступные обновления.
- Если они есть, то приложение просит Google Play показать диалог IAUs. Google Play показывает пользователю диалог с предложением обновиться.
- Если пользователь соглашается, Google Play в фоновом режиме скачивает обновление, показывая пользователю в статус-баре прогресс скачивания.
- Если скачивание завершилось, когда приложение работает в фоновом режиме, Google Play автоматически завершает установку. Если же приложение в этот момент активно, то для таких случаев нужно определять собственную логику завершения установки. Рассмотрим следующие сценарии.
- Приложение запускает процесс установки, показав пользователю диалог Google Play с индикатором прогресса. После завершения установки запускается обновленная версия приложения. В этом случае рекомендуется отобразить дополнительный диалог, который позволит пользователю подтвердить, что он готов сейчас перезапустить приложение. Это рекомендуемая схема реализации.
- Приложение ждёт, пока оно окажется в фоновом режиме, и после этого завершает обновление. С одной стороны, это менее навязчивое поведение с точки зрения UX, так как взаимодействие пользователя с приложением не прерывается. Но с другой — оно требует от разработчика реализовать логику для определения того, находится ли приложение в фоновом режиме.
Google Play: как устроен магазин приложений?
Основные требования к тестированию
Чтобы вручную выполнить весь процесс обновления на тестовом устройстве, нужно иметь как минимум две версии приложения с разными номерами сборок: исходная и целевая.
- Исходная версия с более высоким номером должна быть опубликована в Google Play, она будет идентифицирована Google Play как доступное обновление. Целевая версия с более низким номером сборки и интегрированным IAUs должна быть установлена на устройстве, её мы будем обновлять. Суть в том, что когда приложение попросит Google Play проверить наличие обновления, он сравнит номера сборок у установленной и доступной версии. Так что IAUs будет запущено только в том случае, если номер сборки в Google Play выше, чем у текущей версии на устройстве.
- Исходная и целевая версии должны иметь одинаковые имена пакета и должны быть подписаны одинаковым релизным сертификатом.
- Android 5.0 (API level 21) или выше.
- Библиотека Play Core 1.5.0 или выше.
Пример кода
Здесь мы рассмотрим пример кода для использования IAUs Flexible Flow, который также можно найти в официальной документации. Для начала необходимо добавить библиотеку Play Core в build.gradle файл на уровне модуля.
dependencies
Затем создадим экземпляр AppUpdateManager и добавим функцию обратного вызова к AppUpdateInfo , в которой будет возвращаться информация о доступности обновления, объект для запуска обновления (если оно доступно) и текущий прогресс скачивания, если оно уже началось.
// Create instance of the IAUs manager. val appUpdateManager = AppUpdateManagerFactory.create(context) // Add state listener to app update info task. appUpdateManager.appUpdateInfo.addOnSuccessListener < appUpdateInfo ->// If there is an update available, prepare to promote it. if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) < // . >// If the process of downloading is finished, start the completion flow. if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) < // . >> .addOnFailureListener < e ->// Handle the error. >
Чтобы показать диалог для запроса обновления из Google Play, необходимо передать полученный объект AppUpdateInfo в метод startIntentSenderForResult .
appUpdateManager.startUpdateFlowForResult( // Pass the intent that is returned by ‘getAppUpdateInfo()’. appUpdateInfo, // Or ‘AppUpdateType.IMMEDIATE for immediate updates. AppUpdateType.FLEXIBLE, // The current activity. activity, REQUEST_CODE )
Для отслеживания состояния обновления можно добавить в менеджер IAUs слушатель событий InstallStateUpdatedListener .
// Create a listener to track downloading state updates. val listener = InstallStateUpdatedListener < state ->// Update progress indicator, request user to approve app reload, etc. > // At some point before starting an update, register a listener for updates. appUpdateManager.registerListener(listener) // . // At some point when status updates are no longer needed, unregister the listener. appUpdateManager.unregisterListener(listener)
Как только обновление будет скачано (статус DOWNLOADED ), нужно перезапустить приложение, чтобы завершить обновление. Перезапуск можно инициировать с помощью вызова appUpdateManager.completeUpdate() , но перед этим рекомендуется показать диалоговое окно, чтобы пользователь явно подтвердил свою готовность к перезапуску приложения.
Snackbar.make( rootView, «An update has just been downloaded from Google Play», Snackbar.LENGTH_INDEFINITE ).apply < setAction(«RELOAD») < appUpdateManager.completeUpdate() >show() >
Ошибка «Update is Not Available»
Во-первых, перепроверьте соответствие требованиям, перечисленным в разделе «Basic Implementation Requirements». Если вы все выполнили, однако обновление согласно вызову onSuccess , всё же недоступно, то проблема может быть в кэшировании.
Вполне вероятно, что приложение Google Play не знает о доступном обновлении из-за внутреннего механизма кэширования. Чтобы избежать этого при ручном тестировании, вы можете принудительно сбросить кэш, зайдя на страницу «Мои приложения и игры» в Google Play. Или можете просто очистить кэш в настройках приложения Google Play. Обратите внимание, что эта проблема возникает только в ходе тестирования, она не должна влиять на конечных пользователей, поскольку у них кэш всё равно обновляется ежедневно.
IAUs Flexible Flow в приложении Pandao
Мы участвовали в программе раннего доступа и интегрировали IAUs Flexible Flow (рекомендованная реализация) в приложение Pandao — платформу, на которой производители и вендоры могут торговать китайскими товарами. Диалог IAUs отображался на главном экране, так что с ним могло взаимодействовать максимальное количество пользователей. Изначально мы хотели показывать диалог не чаще раза в день, чтобы не отвлекать людей от взаимодействия с приложением.
Поскольку A/B-тестирование играет ключевую роль в жизненном цикле любой новой фичи, мы решили оценить эффект от IAUs в нашем приложении. Мы случайным образом разделили пользователей на две непересекающиеся группы. Первая была контрольной, без использования IAUs, а вторая группа была тестовой, этим пользователям мы показывали диалог IAUs.
A/B-тест IAUs Flexible Flow в приложении Pandao.
В течение последних нескольких релизов мы измерили долю активных пользователей каждой версии приложения. Оказалось, что среди активных пользователей с последней доступной на тот момент версией основную часть составляли участники из группы B, то есть с функцией IAU. Фиолетовая линия на графике показывает, что в первые дни после публикации версии 1.29.1 количество активных пользователей с IAUs превысило количество пользователей без этой функции. Поэтому можно утверждать, что пользователи с IAUs быстрее обновляют приложение.
Диалог IAUs Flexible Flow в приложении Pandao.
Согласно нашим данным (см. график выше), пользователи больше всего кликают на кнопку подтверждения в диалоге IAUs в первые дни после релиза, а затем конверсия постоянно снижается вплоть до публикации следующей версии приложения. То же самое наблюдается с кнопкой установки в диалоговом окне, которая инициирует установку скачанного обновления. Следовательно, можно сказать, что среднее значение конверсии в обоих случаях прямо пропорционально частоте релизов. В Pandao средняя конверсия в течение одного месяца достигает 35 % для клика на кнопку подтверждения и 7 % для клика на кнопку установки.
Мы предполагаем, что уменьшение доли подтверждений с течением времени — лишь проблема пользовательского опыта, потому что люди, которым интересна новая версия, будут обновляться довольно быстро, а те, кто не интересуются обновлением, так и не станут интересоваться. Исходя из этого предположения, мы решили не беспокоить тех, кому не интересно обновление, и не спрашивать их каждый день. Хорошей практикой будет использование другой логики запросов, которая основывается на «устаревании», то есть чтобы не беспокоить пользователей, мы оцениваем, насколько старые версии стоят у них и как часто мы уже предлагали им обновиться.
В целом IAUs продемонстрировала хорошие результаты в ходе A/B-тестирования, так что мы раскатили IAUs для всех пользователей.
Благодарности
Благодарю за помощь в написании статьи Марину Плешкову Maryna_Pliashkova, Александра Черного alexchernyy, Илью Назарова RolaRko, Глеба Бодячевского, Даниила Полозова jokerdab, Анастасию Кулик, Владислава Бреуса и Владислава Голдина Vladiskus.
- android development
- разработка мобильных приложений
- google play
- программирование
Источник: habr.com
Android In-App Updates. Обновляем приложение на лету.
Чтобы эффективно удерживать пользователей и взаимодействовать с ними необходимо предоставлять им все новые функции и исправления. У одних пользователей Google Play автоматическое обновление включено, у других – нет. Некоторые из них редко подключаются к качественному Wi-Fi, из-за чего их приложения подолгу не обновляются.
Google создали API, который позволяет определять наличие новых версий и функций и интегрировать настраиваемый встроенный процесс обновления, который выглядит как часть приложения. При обнаружении обновления можно уведомить о нем пользователя, предложив обновить приложение сразу или в удобное время. Теперь вы прямо в приложении можете проверить доступность обновления и спросить у пользователя хочет ли он получить новую версию прямо сейчас или позже. Звучит круто, давайте разбираться.
Android In-App Updates работает на девайсах с Android 5.0 (API level 21) и выше, и требуется использовать Play Core library версии 1.5.0 или выше. Если ваше приложение соблюдает данные требование, то вам доступно 2 сценария использования In-App Updates:
Сценарий Flexible.
Суть такого сценария в том, что пользователь может использовать ваше приложение, в то время, как скачивается обновление. После скачивания файлов – вы получите уведомление о том, что процесс загрузки завершен и пользователь может запустить обновление приложения. Это удобно для фичей, которые не меняют core-функционал приложения и не влияют на базовый сценарий использования приложения.
Сценарий Immediate (Немедленный)
Процесс обновления запускается сразу и блокирует использование приложения до окончания обновления. Как только пользователь разрешит запуск приложения Google Play запустит процесс скачивания и установки обновления, после того, как обновление установится, приложение будет перезапущено. Такой сценарий подходит для фичей, которым необходимо изменение базового сценария использования приложения, когда пользователь не может пользоваться приложением если не обновить его.
Имейте ввиду. Когда публикуете ваше приложение в виде Android App Bundle, максимальный размер сжатого приложения, поддерживаемого in-app updates не должен превышать 150MB. In-app updates не совместимы с приложениями использующими APK expansion files ( .obb files).
Для того, чтобы использовать in app updates, необходимо добавить следующую зависимость
dependencies
Внедрение in-app updates достаточно просто. Например, на первой странице вашего приложения вам необходимо оповестить пользователя о том, что доступно обновление для приложения. Для этого в методе onCreate() вашей Activity необходимо добавить следующую проверку:
class MainActivity : AppCompatActivity() < private lateinit var appUpdateManager: AppUpdateManager override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) appUpdateManager = AppUpdateManagerFactory.create(this) appUpdateManager.appUpdateInfo.addOnSuccessListener < if (it.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE it.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) < // check for the type of update flow you want requestUpdate() >> >
Класс AppUpdateManager из библиотеки Play Core library используется для получения объекта AppUpdateInfo , который содержит информацию о наличии обновления, доступной версии и статусе обновления. Если обновление доступно, то здесь же содержится Intent для старта обновления. Если in-app update уже запущено то, то вернется статус обновления. Так как процесс получения информации о доступном обновлении происходит асинхронно – то используя callback addOnSuccessListener мы можем получить добавить метод, который после получения информации запустить intent для обновления
private fun requestUpdate(appUpdateInfo: AppUpdateInfo?) < appUpdateManager.startUpdateFlowForResult( appUpdateInfo, AppUpdateType.FLEXIBLE, // HERE specify the type of update flow you want this, // the instance of an activity REQUEST_CODE_FLEXIBLE_UPDATE ) >
Ответ пользователя мы получим в методе onActivityResult(). Код ответа может быть одним из: Activity.RESULT_OK , Activity.RESULT_CANCELED , ActivityResult.RESULT_IN_APP_UPDATE_FAILED . Последний статус вернется из Play core библиотеки и возвращается, если обновление прервано по каким-то причинам.
companion object < private const val REQUEST_CODE_FLEXI_UPDATE = 17362 >override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) < super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE_FLEXI_UPDATE) < when (resultCode) < Activity.RESULT_OK -> < // handle user’s approval >Activity.RESULT_CANCELED -> < // handle user’s rejection >ActivityResult.RESULT_IN_APP_UPDATE_FAILED -> < // handle update failure >> > >
Дальше все зависит от того, какой тип обновления вы выбрали.
Сценарий Immediate (Немедленный)
В этом случае после вызова метода appUpdateManager.startUpdateFlowForResult() Google Play запустить процесс обновления и пользователь не сможет использовать приложение до окончания установки приложения. Однако, следует обработать кейс, если приложение в фоне. Для этого
override fun onResume() < super.onResume() appUpdateManager.appUpdateInfo.addOnSuccessListener < if (it.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) < appUpdateManager.startUpdateFlowForResult( it, AppUpdateType.IMMEDIATE, this, REQUEST_CODE_FLEXI_UPDATE ) >> >
Флаг UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS значит, что обновление уже было запущено и процесс установки продолжается. Запуск startUpdateFlowForResult запусит блокирующий экран Google Play с обновлением. После окончания установки обновления Google Play перезапустит приложение.
Сценарий Flexible
В случае, если вы запустили in-app update в режиме Flexible, то как только пользователь согласился обновить приложение, он может продолжить использовать приложение: листать ленту с котятами, лайкать фото друзей и т.д. О том, что обновление скачивается, пользователь заметит по progress bar который находится на панели уведомлений. Вы же, как разработчик можете подписаться на InstallStateUpdatedListener и получать статус обновления (или ошибку)
class MainActivity : AppCompatActivity(), InstallStateUpdatedListener < override fun onStateUpdate(installState: InstallState) < if (installState.installStatus() == InstallStatus.DOWNLOADED) < notifyUser() >> override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) appUpdateManager = AppUpdateManagerFactory.create(this) appUpdateManager.registerListener(this) appUpdateManager.appUpdateInfo.addOnSuccessListener < if (it.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE it.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) < // check for the type of update flow you want requestUpdate() >> override fun onDestroy() < super.onDestroy() appUpdateManager.unregisterListener(this) >private fun notifyUser() < Snackbar .make(appVersionTextView, R.string.restart_to_update, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.action_restart) < appUpdateManager.completeUpdate() appUpdateManager.unregisterListener(this) >.show() > >
Флаг InstallStatus.DOWNLOADED значит, что загрузка завершена и можно уведомить об этом полльзователя (показать snackbar/toast/dialog). Чтобы закончить обновление, необходимо вызвать метод appUpdateManager.completeUpdate() и отписаться от Listener’a. Как и в случае с режимом Immediate, при закрытии приложения, процесс установки приложения не закончится, поэтому пользователя необходимо уведомить о статусе, когда он вернется. Опять же, метод onResume() неплохое место для этого.
override fun onResume() < super.onResume() appUpdateManager.appUpdateInfo.addOnSuccessListener < if (it.installStatus() == InstallStatus.DOWNLOADED) < notifyUser() >> >
Вот собственно и все! Резюмируя еще раз подчеркну.
Немедленное обновление необходимо в критических случаях, например для исправлений, касающихся безопасности или конфиденциальности. Когда пользователь соглашается на такое обновление, оно скачивается и активируется при перезапуске приложения. Гибкие обновления после согласия пользователя скачиваются в фоновом режиме.
После скачивания вы можете предложить пользователю перезапустить приложение, или же обновление может примениться при переходе приложения в фоновый режим. Если планируете интегрировать данную фичу в ваше приложение, рекомендую ознакомиться с документацией и дополнительными источниками. А здесь как приложение Pandao внедряло данную фичу у себя.
Источник: androidschool.ru
How to Update Apps on Android
This article was co-authored by wikiHow Staff. Our trained team of editors and researchers validate articles for accuracy and comprehensiveness. wikiHow’s Content Management Team carefully monitors the work from our editorial staff to ensure that each article is backed by trusted research and meets our high quality standards.
The wikiHow Tech Team also followed the article’s instructions and verified that they work.
This article has been viewed 90,184 times.
This wikiHow teaches you how to install app updates on your Android device by updating the apps that have new versions available, or by turning on automatic updates.
Method 1 of 2:
Manual Updates
Fair Use (screenshot)
n»>