Дисклеймер: я не связан с Google Play, Chrome или любой упомянутой компанией. Это не официальное заявление. Логотип и названия используются только для иллюстрации.
В Chrome 72 для Android реализована долгожданная функция Trusted Web Activity. Это означает, что теперь мы можем распространять PWA через каталог Google Play и запускать Chrome без UI в автономном режиме для нативных пакетов! Я некоторое время поигрался с этой функцией, копаясь в API, а здесь расскажу, о чём речь, чего ожидать и что доступно уже сегодня.
PWA в каталоге Play Store
Chrome 72 для Android теперь доступен для всех пользователей, и в этой версии реализована система Trusted Web Activity (TWA). Если вкратце, запуск Chrome осуществляется в автономном режиме (без панели инструментов и UI) для нативных Android-пакетов.
Начнём с того, что публикация в каталоге — не такая простая процедура, какой она должна быть (например, ввести URL в Google Play — и приложение запустится). Кроме того, нельзя использовать доступный WebAPK и опубликовать приложение в каталоге. Здесь используется Java API, который через сервисы взаимодействует с Chrome и, кажется, находится на ранней стадии разработки. Поэтому придётся многое сделать вручную.
Я рассматриваю это как первый шаг. Наверняка вскоре появится лучший инструментарий (возможно, от сообщества) с поддержкой всех доступных API и запуском в один щелчок. Но на нынешнем API можно опубликовать в каталоге лаунчер PWA. Я поделюсь своим опытом, как это делается.
По какой-то причине эта функция ещё не появилась в Chrome Platform Status, и документация до сих пор не обновилась (она вообще не обновлялась более 15 месяцев).
Обновление от 5 февраля. Блог Chromium опубликовал короткую заметку о поддержке TWA и некоторые технические детали, упомянутые в этой статье.
Обновление от 1 февраля. Пол Кинлан, ведущий разработчик Chrome в Google, подтвердил выпуск функции TWA и что документация задерживается: причина задержки в том, что разрешение на новую функцию Chrome 72 было принято в последнюю минуту.
Видео от Пита Ле Пейджа годичной давности с объяснением TWA
Зачем публиковать PWA в каталоге?
Это веб-платформа, Карл! Зачем использовать каталог?
Ну, это долгий разговор, но я много лет консультирую большой и малый бизнес, и когда мы рассматриваем разработку PWA, постоянно упоминается каталог приложений: «Наши пользователи будут там искать приложение», «У нас уже есть собственное приложение, и мы не хотим терять пользователей», «Нам нужен доступ к собственному API» или «Я хочу монетизировать PWA».
Отныне стала возможной публикация PWA в каталоге, а также работа из браузера. Конечно, это отдельная операция. Play Store не эмулирует Microsoft Store: ваше PWA не появится в магазине, если вы не скомпилируете APK и не опубликуете его.
Преимущества перед стандартными PWA
Кроме нового механизма распространения и новых пользователей из каталога (и даже из поиска Google в разделе «Приложения»), появляются и другие преимущества:
- Возможность разместить виджет на главном экране.
- Ярлыки приложений (при долгом нажатии на значок приложения) и другие глубокие интеграции с ОС.
- Работа с «компаньоном» на носимых устройствах или расширением Android Auto.
- Повторная установка после жёсткого сброса или резервного восстановления на новом телефоне.
- Фоновые службы, которые обращаются к собственным функциям (связь с PWA всё ещё ограничена — подробнее ниже).
- Монетизация (пока ограничена, подробнее ниже).
- Некоторые нативные экраны, смешанные с контентом PWA.
- Распространение более одной иконки PWA в лаунчере и/или на начальном экране, указывающих на разные URL (в пределах одного хоста).
- Лучшая поддержка интернационализации.
В чём инновация?
В каталоге уже были некоторые PWA, но теперь их гораздо легче подготовить и опубликовать
В Google Play Store уже есть некоторые PWA, такие как Google Maps Go, Instagram Lite и Twitter Lite. Первое приложение использует некую частную версию pre-TWA, а последние два — WebView, это был хоть не идеальный, но единственный способ сделать что-то подобное до появления TWA. В приложениях много машинного кода для некоторых вещей, таких как уведомления. Мы хотим опубликовать PWA как веб-разработчики и не хотим писать много кода Java.
TWA — специальный режим на базе кастомных вкладок Chrome, которые с версии Chrome 45 позволяют запустить встроенный в приложение браузер.
Является ли TWA гибридным фреймворком, похожим на Cordova?
Нет. С Cordova и другими гибридными решениями вы обычно поставляете ресурсы (HTML, JS, CSS и т. д.). в пакете APK. Кроме того, там отличается движок, он изолирован от пользовательского браузера, поэтому не поддерживает сеансы или совместное использование кэша.
Вот как выглядит PWA с Trusted Web Activity. Я пока не вижу реализации цветовых схем
С помощью Trusted Web Activity не нужно упаковывать файлы ресурсов (только нативные компоненты, если они нужны); все ресурсы загружаются и обновляются на лету через сервис-воркера. Ваш PWA всегда рендерится установленной версией Chrome, с её хранилищем, кэшем и сеансами. Таким образом, если пользователь открыл сеанс на веб-сайте, а потом установил приложение из Play Store, он будет уже авторизован в системе.
Требования Play Store
URL-адрес, используемый для доверенной веб-операции, должен соответствовать следующим требованиям:
- Передача PWA Criteria (HTTPS, сервис-воркер с обработчиком событий fetch, манифест веб-приложения со значком 512px, background_color и осноным набором других свойств).
- Рейтинг производительности минимум 80/100 в Lighthouse (доступен в инструментах разработчика Chrome или как NPM CLI).
- Все текущие правила Play Store.
Согласно сообщению в блоге Chromium, «приложениям, которые не соответствуют требованиям качества TWA или правилам Play Store, может быть отказано в приёме или они могут быть исключены».
Я пока не уверен, что команда Play Store QA проверяет все эти требования при публикации приложения.
Модель безопасности PWA в Play Store
Ваше PWA будет подчиняться модели безопасности браузера, а не нативного приложения, пока вы не добавите нативный код непосредственно в APK. Поскольку всё под контролем браузера, пользователь должен знать, что даже если он только что установил приложение, у него появятся данные сеанса, локальные хранилища и разрешения, уже установленные для этого хоста в браузере. Вот почему при первом запуске ему показывают мини-сообщение «Работает в Chrome»:
Кроме того, когда пользователь удалит приложение, то получит предупреждение, что состояние и данные приложения по-прежнему доступны в Chrome, поэтому при необходимости следует очистить кэш. Среди таких следов, например, разрешение Web Push: даже если пользователь удалит приложение, он всё равно продолжит получать push-уведомления. Сообщение было замечено Генри Лимом:
О необходимости таких уведомлений рассказал Пол Кинлан из команды Chrome.
Способы разработки
Для создания пакета с TWA сначала понадобится Android Studio. Пока что все варианты экспериментальные и описаны только примерами кода в репозитории Chrome на GitHub.
Варианты разработки приложений с TWA:
- Использование высокоуровневой библиотеки Java Support Library от команды Chrome: в этом случае не нужно писать собственный код Java или Kotlin. Создаёте проект Android Studio (или клонируете пример), настраиваете некоторые метаданные в AndroidManifest.xml из манифеста веб-приложения — и готово.
Фреймворк обеспечит соединение с TWA и дополнительные возможности для создания записи Settings в Android-устройстве, а также сделает доступными пуш-уведомления. Сейчас библиотека лежит во временном репозитории Jitpack. Думаю, в будущем она переместится в другое место.
- Работа с Trusted Web Activity вручную. Если у вас есть опыт разработки Android-приложений на Java или Kotlin, вы можете просто вручную подключить PWA. Так вы можете оставить некоторые нативные действия, открывая Trusted Web Activity только в нужный момент. В этом случае я предлагают изучить библиотеку поддержки и понять, как из проекта подключиться к Chrome.
Обновление от 5 февраля: теперь на сайте Android доступна документация по TrustedWebUtils, хелперу TWA.
Распространение манифеста
PWA в App Store не примет манифест веб-приложения; требуется вручную скопировать некоторые значения. Значки берутся из папки “res”, как в любом нативном Android-приложении, блокировку ориентации следует определить в записи активности AndroidManifest и т. д.
При использовании библиотеки поддержки экран-заставка создаётся автоматически, но другие свойства манифеста не будут использоваться. На самом деле, в моём тестировании я не смог применить цветную тему, когда на экране открывалось PWA.
Валидация URL
TWA будет работать только после цифрового рукопожатия домена с приложением. Механизм известен как Digital Assets Links. Он создаёт доверительные отношения между вашим хостом и APK, доказывая, что вы являетесь владельцем PWA и что вы не будете публиковать в Play Store приложения, которые вам не принадлежат. Он также устанавливает цифровой канал между сайтом и нативным приложением, который теоретически может позволить им обмениваться частными данными (но, похоже, это невозможно с сегодняшним TWA API).
С Digital Assets Links вы должны выложить на своём домене файл <your-domain>/.well-known/assetlinks.json. Этот JSON-файл содержит информацию о пакете Android (например, идентификатор пакета) и хэш сертификата вашего приложения, который вы можете узнать командой в консоли. У Android-пакета будет двойник на URL хоста. Есть онлайн-валидатор для проверки, что всё в порядке.
Если вы не провели рукопожатие, TWA не активируется, и ваше приложение будет просто использовать обычные Chrome Custom Tabs с минимальным интерфейсом Chrome, как если в PWA включить display: minimal-ui. Я не совсем уверен, но наверное Play Store может отклонить приложения, которые просто указывают на обычные вкладки без валидации TWA. Я пока точно не знаю, в какой момент Chrome выполняет проверку Digital Asset Link; если при каждом доступе к приложению, это может стать проблемой производительности. Думаю, возможно кэширование, а также Play Store может делать проверку перед одобрением приложения во время приёма в каталог. Посмотрим, что будет написано в документации.
Существует (не очень простой) механизм обхода процесса сертификации Digital Asset Link для целей разработки, описанный ниже.
Публикация приложения
Чтобы опубликовать ярлык PWA с помощью TWA, нужно следовать всем правилам Play Store. Дополнительную информацию см. в Developer Policy Center. Также понадобится создать аккаунт издателя с одноразовой платой в размере $25, метаданные, скриншоты и маркетинговые материалы для приложения.
Деплой
Когда вы закончите разработку в Android Studio и у вас есть аккаунт к консоли разработчика, нужно создать APK для продакшна и подписать его ключом, созданным в Android Studio. Можете обратиться к сервису App Signing by Google Play, чтобы в будущем упростить процесс.
Консоль Google Play
Для загрузки этих приложений нет никаких особых правил или процессов, но отдел Revision может обнаружить, что вы используете TWA, и проверит, что: 1) Digital Assets Link рабоатет; 2) URL передаёт критерии PWA (в основном, для обработчика событий fetch в сервис-воркере).
Для публикации в Play Store придётся указать много метаданных и графических ресурсов
Обновление приложения
Если вы измените контент, то не нужно заново загружать приложение, если только вы не измените приложение полностью (в соответствии с правилами каталога). Продолжаете обновлять его через сервис-воркеры и обновления на сервере. Новый APK придётся загрузить только если вы захотите изменить метаданные, нативный код или иконки.
Ограничения
Сейчас у платформы есть определённые ограничения, но это только начало. Надеюсь, со временем они будут сняты.
PWA в подпапках
Если вы публикуете свой PWA в подпапке хоста, то возникает несколько проблем.
- Digital Asset Link подключает весь домен, а не только папку.
- Текущая библиотека поддержки, кажется, обрабатывает как Intent (Link Capturing) весь хост, даже если PWA находится в подпапке.
Нет внутренних приложений
Это ограничение самого Play Store (вы не можете публиковать приложения для локальной сети или приложения, предназначенные только для вас и вашей компании). Вы можете использовать TWA и создавать apk, которые будут развёртываться за пределами магазина.
Digital Asset Link работает только с общедоступными URL, потому что Chrome должен проверить, что мы владеем доменом, а это невозможно с внутренними URL.
Первая загрузка
При первом открытии недавно установленного приложения на устройстве ещё нет файлов приложения (Service Worker ещё не зарегистрирован, если пользователь не открывал PWA раньше), поэтому в автономном режиме пользователь увидит пустой белый экран. Думаю, в будущих версиях полезно бы реализовать некую подкачку через Chrome после установки приложения. Если вы используете TWA API вместо библиотеки поддержки, то обнаружите такую ситуацию и правильно проинформируете пользователя через нативные API.
Вызов нативного кода
Уже есть двунаправленный канал между сервером TWA (Chrome) и клиентом TWA (наш APK). Этот канал в настоящее время используется только для отправки пуш-уведомлений и их отображения в нативном приложении, а не в Chrome.
Здесь есть определённый потенциал в простом соединении нативного кода и JavaScript, предоставив PWA доступ к нативному коду, аналогично механизму APPX/PWA в Microsoft Store.
Возможно, в будущем появится возможность регистрации классов Java/Kotlin в клиенте TWA, чтобы мы могли фактически вызывать их с помощью JavaScript API, когда наш PWA визуализируется в режиме TWA.
Сегодня единственный способ выполнить нативный код — использовать Intents для открытия других нативных действий и затем повторного открытия TWA, отправляя и получая аргументы через параметры URI.
Кроме того, вы можете создать в нативном коде какой-то веб-сервер или сервер WebSocket, и направить на него PWA, но это странно, сложно и, возможно, будет излишне расходовать батарею. Но перед нами целый новый мир возможностей. Посмотрим, что придумает сообщество!
Монетизация с Play Store
Если у вас платное приложение, то нельзя легко проверить, что пользователь действительно за него заплатил (в конце концов, контент — это всего лишь URL-адрес). Кроме того, если вы хотите продать какие-то цифровые ресурсы или подписки с помощью кошелька Play Store, то сложно реализовать такую схему без фактического моста с нативным кодом.
Отладка
Я не уверен, это баг или какая-то проблема моей IDE, но удалённая отладка сервис-воркеров из TWA не работает. Я могу проверить контекст окна, но не сервис-воркера.
Другие движки
Сейчас TWA работает только на Chrome, но в будущем другие браузеры могут клонировать API: например, Samsung Internet, Edge или Firefox.
Обновление от 4 февраля: TWA работает по протоколу Android Custom Tab, который в настоящее время внедряют другие браузеры. Поэтому если в системе установлен другой браузер по умолчанию, он может открыть TWA с содержимым PWA. Впрочем, требуется дополнительное тестирование, чтобы понять, как это работает.
Что произойдёт, если у пользователя более старая версия Chrome и он установит приложение из Play Store? В этом случае PWA отобразится как настраиваемая вкладка Chrome, а не в полностью автономном режиме.
Google Maps Go в Play Store уже использовал что-то похожее на TWA, а Chrome указан как обязательное требование для работы
Что произойдёт, если у пользователя вообще нет Chrome? На сегодняшний день при использовании библиотеки поддержки приложение не будет работать вообще (если нет другого браузера с поддержкой протокола Custom Tabs). Если вы используете TWA API в нативном коде Java/Kotlin, то можете проверить доступность браузера и загрузить альтернативное решение, такое как WebView, или открыть браузер.
Хотя Android-устройства без Chrome редки, но на некоторых он не установлен умолчанию, в том числе на всех новых устройствах в Европе.
Другие платформы
PWA не работает на носимых ОС (часы), но я не совсем уверен, что происходит на других Android-платформах. Вероятно, поддержки ещё нет, но нужно это проверить. Я говорю об Android TV или хромбуках с Play Store. Если вы не протестировали эти платформы, есть смысл отключить их в списке каталога.
Конфликт с WebAPK
Если вы установили PWA из Chrome, то у вас уже есть APK для этого URL, подписанный Play Store, но каталог всё равно оставит приложение в списке и позволит пользователю установить его тоже. И наоборот: установка приложения из каталога не помешает Chrome предложить пользователю «добавить» его из браузера. Думаю, этого можно избежать, если WebAPK тоже получит Digital Asset Link или мы сможем как-то сопоставить идентификатор приложения WebAPK, но вряд ли это произойдёт в ближайшее время. Посмотрим.
Два приложения Starbucks, работающие одновременно: WebAPK и наш собственный APK
Вы можете заблокировать предложение Chrome установить WebAPK и вместо него показать своё приложение из каталога, используя атрибут related_applications и атрибуты prefer_related_applications манифеста веб-приложения. Get Installed Related Apps API может в будущем помочь разрешить этот конфликт.
Создание первого PWApk
Знаю, я только что изобрёл слово PWApk, но звучит неплохо, верно?
Несколько лет назад я сделал видеокурс по нативным веб-приложениям Android. Хотя это не совсем относится к PWA, но поможет понять экосистему Android.
Самый простой способ сделать APK на основе TWA — это клонировать образец репозитория SVGOMG из репозитория ChromeLabs на GitHub
Можете клонировать репозиторий git или запустить новый проект. В нашем случае мы начинаем новый проект только для того, чтобы лучше разобраться в теме.
Создайте новый проект в Android Studio и выберите No Activity: будем использовать только Trusted Web Activity из библиотеки поддержки.
Начнём с пустого проекта
Заполните данные, выберите название проекта (мы его позже изменим) и имя пакета: это будет идентификатор нашего приложения в Android, а также в каталоге. Рекомендую использовать имя хоста в обратном порядке и произвольное название в конце. Например, если у вас хост mypwa.com/calculator, то пакет можно назвать com.mypwa.calculator.
В качестве базы подойдёт API 19 (Android 4.4). Похоже на то, что скоро это будет минимальная версия, необходимая для Chrome. Некоторые функции TWA будут работать только с API 23 (Android 6.0), но об этом позаботится библиотека поддержки.
Обновление от 5 февраля: Chrome официально объявил, что TWA работает только с Android 4.4 KitKat. Таким образом, эта функция недоступна примерно 5% активных пользователей Android: их откатит на версию с кастомной вкладкой и адресной строкой.
Выбор минимального уровня API ограничит список устройств, для которых PWA будет предлагаться в каталоге Play Store
Добавление зависимости
Следующий шаг — добавление библиотеки поддержки TWA в качестве зависимости, поэтому откроем два файла с названием build.gradle:
Два файла конфигурации: для проекта и для Android-приложения
Начнём с файла проекта. Добавим в секции allprojects > repositories следующую строку:
maven { url "https://jitpack.io" }
На следующем шаге мы открываем build.gradle модуля и добавляем в зависимости:
implementation 'com.github.GoogleChrome:custom-tabs-client:e446d08014'
Настройка TWA
Следующий шаг — установить в файле модуля параметры PWA для Trusted Web Activity, добавляем в секцию defaultConfig:
manifestPlaceholders = [
hostName: "app.starbucks.com",
defaultUrl: "https://app.starbucks.com",
launcherName: "Starbucks",
assetStatements: '[{ "relation": ["delegate_permission/common.handle_all_urls"], ' +
'"target": {"namespace": "web", "site": "https://app.starbucks.com"}}]'
]
Тут в качестве примера я буду использовать Starbucks PWA. Информация из процесса Digital Asset Link понадобится ключу assetStatements. Мы пока пропустим эту часть. Свойство с названием launcherName должно совпадать с short_name в манифесте веб-приложения.
Настройка манифеста
У приложений Android собственный манифест, они не примут манифест веб-приложения. Нужный файл находится в разделе app > manifests и называется AndroidManifest.xml. Там вы найдёте самозакрывающийся элемент Application XML.
Файл Android-манифеста по умолчанию
Там изменяем значение android:label на ${launcherName}, которое мы установили ранее в метаданных, так что у нас будет единственный источник истины для названия приложения.
Следующий шаг — настройка этого файла, начиная с тега <application>, чтобы добавить в него дочерние элементы, которые будут выглядеть следующим образом:
<meta-data
android:name="asset_statements"
android:value="${assetStatements}" />
<activity android:name="android.support.customtabs.trusted.LauncherActivity"
android:label="${launcherName}">
<meta-data android:name="android.support.customtabs.trusted.DEFAULT_URL"
android:value="${defaultUrl}" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"
android:host="${hostName}"/>
</intent-filter>
</activity>
Приведённый ниже код настроит TWA с помощью библиотеки поддержки и Intent Filter, чтобы приложение получило ссылки на PWA и Digital Asset Link. Я пропущу подробности, что происходит с точки зрения Android-приложения.
Пришло время для синхронизации
На этом этапе нужно скомандовать Android Studio принять все ваши изменения, нажав Sync Now. Если всё сделано правильно, то не выскочит никаких ошибок.
Замена иконок
В данный момент приложение использует только иконку Android по умолчанию, поэтому нужно заменить все файлы в app>res>mipmap в разных подпапках для разной плотности пикселей. Есть две версии: квадратные и закруглённые иконки. Закруглённые появились в Android 7.1, и если хотите их игнорировать, то удалите ссылку android:roundIcon ссылку в AndroidManifest.xml.
Нужно взять значки из манифеста и скопировать их во вложенные папки mipmap с соответствующими именами
Настройка темы
Наконец, нужно открыть app/res/values/styles.xml и внести некоторые изменения в тему, чтобы она выглядела как PWA:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
Вы можете изменить цвета из app/res/values/colors.xml, но я пока не видел, чтобы это работало в TWA.
Если вы ограничиваете ориентацию в манифесте, то можете добавить это ограничение в элемент <activity> в AndroidManifest.xml.
Готовы к тестированию?
Мы готовы протестировать наш PWApk, но перед этим нужно настроить режим разработки TWA для Chrome на тестовом устройстве Android или в эмуляторе (с Chrome 72+).
Настройка Chrome
Убедитесь, что у вас Chrome стабильной версии 72 и откройте chrome://flags. Найдите опцию Enable command line on non-rooted devices и поставьте флаг. Перезапустите браузер.
Затем нужно настроить Chrome для обхода Digital Asset Link для хоста, который мы хотим протестировать, в нашем примере это app.starbucks.com.
Чтобы изменить параметры командной строки для Chrome под Android нужно записать текстовый файл в файловую систему Android. Самый простой способ сделать это — через adb (android debug bridge), который должен быть прописан в path (погуглите, если что), и запустить команду:
adb shell cat /data/local/tmp/chrome-command-line _ - disable-digital-asset-link-verification-for-url="https://app.starbucks.com"
Можно использовать простой bash-скрипт от Google.
Нужно остановить Chrome, чтобы он при запуске принял новые настройки
И перезапустить Chrome. Но не просто убрать приложение из списка задач, а из настроек принудительно завершить весь процесс (Force Stop). Мне пришлось сделать это пару раз, прежде чем всё сработало.
Предупреждение о том, что флаг включен и всё прошло удачно
Если всё сделано, то каждый раз при открытии Chrome вы увидите предупреждение о неподдерживаемом флаге. Если запустить приложение из Android Studio, ваше PWA наконец-то запустится и заработает в автономном режиме под значком и названием вашего APK.
Заключение
Возможность публикации PWA в каталоге Google Play реально меняет правила игры. Кажется, сейчас у нас очень ранняя версия API и определённо требуется доработка. Я действительно хочу, чтобы можно было ввести URL нашего PWA и получить с него файл APK. Это не очень просто из-за системы верификации Digital Asset Link. Только Play Store может это сделать, используя тот же WebAPK, который они генерируют.
Я раньше задавался вопросом, одобряет Google приложения PWA или ведёт с ними войну. Но теперь они сняли с себя подозрения, по крайней мере, в части TWA.
Будем надеяться, что TWA в Chrome 72 — это первый шаг в долгом путешествии!