Комментарии 20
Не до конца понятно, это у вас билды под разные типы - HMS, gms?
С проблемой инкременальной сборки в agconnect решения нет у вас часом?(там deprecated с 8 Gradle сборка, а флаг который можно использовать хоть и работает, но в экспериментальном статусе)
Привет! Да, билды разные) Чтобы в стор не попадать с сервисами Хуавея
Про инкрементальную сборку, ты про кэширование артефактов? Если да, то мы на CI холодную собираем для сторов всегда, чтобы проблем не было
Возможно просто не сталкивались с твоим кейсом, поэтому не сразу понял
После if на предмет наличия хуавейских или гугловских сервисов на душе стало грустно и печально.
А как же все эти вот SOLID, дизайн паттерны с их адаптерами, интерфейсы скрывающие реализации и другие штуки, позволяющие не плодить лапшу из if'ов?
Вообще странно, через flawors это делаться должно, тем более в стор с Хуавей сервисами выложить не получится...
Привет! if'ы тут для упрощения
Основная задача, которую вкладывал в статью - что делать, когда менеджер пришел и сказал "Адаптируйте-ка под Huawei". Тут скорее не про то, как красиво написать, а про то, что вообще юзать из HMS в разных кейсах. Архитектура у всех проектах своя и встраивает туда фичи кто как хочет
Но спасибо за коммент! В следующем посте учту
if (context.areGoogleServicesAvailable()) {
GoogleFusedLocation(
com.google.android.gms.location.LocationServices.getFusedLocationProviderClient(context)
)
} else {
HuaweiFusedLocation(
com.huawei.hms.location.LocationServices.getFusedLocationProviderClient(context)
)
}
Хосспаде, хотя бы typealias используйте, дети же могут увидеть.
object : Thread() {
override fun run() {
<dies from cringe>
Thread принимает runnable на входе
Thread {
println("Look ma no hands")
}
Ну и да, запускать треды из метода, который вызывается из корутин — это что-то из разряда постиронии.
Вот как мы открываем магазин в Android:
Эх, вот если бы был какой-то способ подставлять разные строки в зависимости от build flavor.
За статью пять, за качество кода два. Вся задача — классическая иллюстрация того, для чего нужны абстракции и IoD, и вы умудрились везде напихать ифов.
P.S. За такое нужно советские деревянные прищепки на соски цеплять.
catch (e: ApiException) {
}
Привет! Спасибо за коммент, учту в следующих постах. В целом статья про то, как в целом завести HMS у себя и максимально просто показать, что как у них работает, импортится и тд. Да, код в статье можно улучшать, но посыл тут скорее про то, что делать, когда к тебе с такой задачкой пришли, в какую сторону копать, куда смотреть
P.S. Про деревянные прищепки поржал - топ))
На самом деле в Хуавей молодцы, они хорошо подготовились и многие (очень) штуки скопировали у Гугла. В некоторых местах вообще достаточно чуть ли не изменить название зависимости и всё сразу заводится.
Но вот с Хуавей Айс беда ) Когда мы внедряли её в свои игры было такое ощущение что кроме нас никто больше этого не делал. Серверная верификация не работала, потому что китайцы присылали данные которые оформлены не по спецификации итд. Хорошо что с их стороны были выделены люди которые работали передастами за великую стену. В итоге получилось, но профита который ожидался нет)
Привет! С AAB у них вроде все норм, там небольшие махинации с подписью и готово. У них прям в доке есть как выложить -https://developer.huawei.com/consumer/en/doc/distribution/app/agc-help-releasebundle-0000001100316672
Практика показала, что тестерам удобнее жить с APK, поэтому собираем их
Про PWA - топовая тема, как-то пилили на нем приложение, но они не все поддерживают пока. Хороший ресурс, где регулярно апдейтят, че может PWA - https://whatpwacando.today/
Но тут вопрос, почему бы Flutter не завести, потому что в целом, не можешь что-то его средствами сделать - затаскиваешь нативный кусок кода и всё живет, да еще и google тему протаскивает, и в веб в целом завернуть эту историю можно


Я требую пояснительную бригаду!
P.S.: А в проде так же пишете? А если это кто-то скопипастит?
Для автоматизации публикаий сборок в Huawei AppGallery можно использовать Gradle плагин https://github.com/cianru/huawei-appgallery-publish-gradle-plugin
можно по другому
делаем отдельные модули для google и huawei
в проекте gradle
2 flavor
и импорт можно так
"googleImplementation"(project(mapOf("path" to ":di:google")))
// === HUAWEI ===
"huaweiImplementation"(project(mapOf("path" to ":di:huawei")))
Оборачиваем сервисы интерфейсами и работаем в приложении как обычно
а уже на уровне DI подставляются разные реализации в зависимости от сборки
Расскажу еще один вариант решение зависимостей.
Вводные:
Существует RuStore, из-за которого непонятно на какое устройство с каками Mobile Services будет установлено приложение
Google Play не рад, что в него льют приложение с HMS зависимостями (может быть это уже закончилось, но инцидент был и еще раз наступать на эти грабли не хочется)
В нашей частной реализации, если на устройстве есть GPS и HMS, то мы предпочтение отдаем GPS и хотели бы, чтобы пользователь использовал их.
поэтому нужна еще универсальная реализация, которая умеет в runtime делегировать работу GPS или HMS.

Т.о. обернули GPS и HMS в отдельные модули mobile-services-google-impl
и mobile-services-huawei-impl
с реализацией своих собственных общих интерфейсов из модуля mobile-services-api
. Создали дополнительный модуль mobile-services-universal-impl
, который так же реализует интерфейсы mobile-services-api
, но под капотом через DI делегирует всю работу одной из имплиментаций моделей mobile-services-google-impl
или mobile-services-huawei-impl
, в зависимости от того, что доступно. В фичевые модули, где нужны Mobile Services, подключается только mobile-services-api
, а нужная имплиментация пройвадится через DI.
Теперь при сборке приложения можно указать через Flavors или -Pgradle флаг что нужно собрать подключив только модуль с GPS реализацией или универсальной реализацией.
if (isNeedHuaweiMobileServices) {
implementation(project(':mobile-services-universal-impl'))
} else {
implementation(project(':mobile-services-google-impl'))
}
Первый вариант можно катить в Google Play, а второй в Huawei AppGallery и RuStore.
@miwas07 Спасибо за статью, пригодилась. Однако у меня остался один вопрос: каким образом вы определяете какой из ПУШ-сервисов добавлять в манифест? Следуя вашим примерам, у меня сейчас 2 вида проверок в приложении: в коде с помощью areGoogleServicesAvailable и второй в build.gradle, где я просто определил manifestPlaceholders чтобы "включать" или "выключать" тот или иной сервис, отвечающий за обработку входящих ПУШей
Как адаптировать Android-приложение под Huawei