Привет, Хабр! С мая 2019 года из-за санкций США мы остались без приложений и API для Android от Google. Из-за этого нашим устройствам грозило будущее без push-уведомлений, магазина и облачных сервисов.
Естественно, мы не опустили руки, а разработали и запустили платформу Huawei Mobile Services, которая заменила сервисы Google для наших устройств. Чтобы вы с ней познакомились и интегрировали в свои приложения, мы собрали 10 самых популярных вопросов, которые возникают у разработчиков, впервые столкнувшихся с HMS.
1. Про GMS я прекрасно все знаю, а что включает платформа HMS?
Платформа HMS полностью заменяет GMS, поэтому почти на каждый сервис Google у нас есть альтернатива: браузер, голосовой помощник, магазин приложений, облачные сервисы и инструменты для разработчиков.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3338-6261-4131-a564-393566383262__scheme.png)
Так как мы разрабатывали сервисы с нуля, то сразу разделили их на группы:
- Сервисы AppGallery Connect позволяют загружать в облако Huawei темы, контент, распространять приложения и собирать статистику и отчеты об их использовании и падениях.
- Сервисы HMS Core включают 14 инструментов, которые обеспечивают базовые функции телефона и взаимодействие с пользователями: push-сообщения, рекламу, авторизацию, аналитику и обмен сообщениями.
- Инструменты для специальных возможностей, как и у Google, включают в себя платформы для работы с VR, AR и enterprise-разработки, например, для AI и IoT.
- Инструменты для разработчиков — это собственный плагин для Android Studio (DevEco Studio) и сервисы облачного тестирования. Также для удобства разработки есть конвертер, который преобразует для работы с HMS код, связанный с GMS. Конвертер полностью поддерживает миграцию push-сообщений, рекламы и частично — кода для inapp-покупок.
Лучше всего начать знакомство с сервисов HMS Core, так как именно с ними будет взаимодействовать большинство приложений. С их помощью можно своевременно узнавать о сбоях в приложении, отслеживать продуктовые метрики и общаться с пользователями. Например, Push Kit отсылает push-сообщения пользователям:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6534-3964-4661-b564-313536316263__image7.png)
2. Как мне быстро адаптировать свои приложения для работы с HMS и протестировать их без телефонов Huawei или Honor??
А вот тут мы постарались: сделали облачные сервисы тестирования и дебаггинга, которым у Google нет аналога, и конвертер для адаптации готового кода для нашей платформы.
Облачные сервисы для разработки и тестирования доступны на главном экране консоли сразу после регистрации на платформе и подтверждения доступа. С их помощью можно из веб-интерфейса запускать эмулятор на серверах Huawei, чтобы не покупать ферму устройств или мощные компьютеры.
Экран с сервисами можно конфигурировать, добавляя или удаляя элементы:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3530-6364-4633-b633-353837643238__image10.png)
В Cloud testing прямо из консоли перед релизом запускаются автотесты и отслеживаются обнаруженные баги:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6339-3333-4530-a665-383339306535__image14.png)
В Cloud Debugging можно получить доступ к эмуляторам. Для этого нужно с помощью поиска по региону, серии, версии андроида и версии EMUI выбрать целевой телефон:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6135-3833-4965-b236-616136636236__image17.png)
Прямо из веб-интерфейса можно загрузить приложение и покликать по нему:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6237-6535-4961-b364-343335616430__image20.png)
В эмуляторе можно даже поиграть в китайский аналог Minecraft. Правда, прежде чем добраться до игрового экрана, придется понажимать кучу кнопок на китайском языке:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3866-3265-4233-b566-613266663764__image3.png)
Такой способ будет удобен для разработчиков тяжеловесных приложений, так как дает возможность проводить тесты на большом количестве устройств прямо из веб-консоли.
Еще одним удобным инструментом для быстрой адаптации приложений для нашей платформы является Huawei Core ToolKit plugin для Android Studio, который конвертирует код, работающий с GMS, под нашу платформу. Установить плагин можно прямо из встроенного магазина:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3965-6434-4233-b864-366265316364__image15.png)
После установки в трее появится пункт HMS. Чтобы начать конвертацию, нужно выбрать New Conversion:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3138-6235-4835-a430-396633613038__image23.png)
Перед конвертацией необходимо указать директорию для резервного копирования:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3234-6633-4961-a136-386538363765__image25.png)
И подтвердить конвертацию:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6535-3232-4661-a165-613636323638__image12.png)
В коде проекта можно вручную отследить каждое изменение и либо применить его, либо проигнорировать. Дополнительно после конвертации в директории проекта появится отдельный модуль с README. md, где можно будет посмотреть, что делает сконвертированный код.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3136-3235-4634-b338-626434376139__image6.jpg)
3. Что с аутентификацией пользователя?
По аналогии с «Sign with Google» и «Sign with Apple» у нас есть свой сервис «Sign with HUAWEI». Он является частью Account Kit и работает со всеми пользовательскими устройствами Huawei и Honor:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3661-6264-4161-b366-383162643530__image1.png)
4. С пользователем понятно, а как идентифицировать телефон?
Мы поддерживаем работу с Android id, а для верификации по номеру телефона в Account Kit у нас есть аналог SMSRetriever. Эта функция активируется на 5 минут командой:
val task = ReadSmsManager.start(this@MainActivity) task.addOnCompleteListener { if (task.isSuccessful) { // The service is enabled successfully. Continue with the process. Toast.makeText(this, "ReadSms service has been enabled.", Toast.LENGTH_LONG).show() } else { Toast.makeText(this, "The service failed to be enabled.", Toast.LENGTH_LONG).show() } }
Также должен быть включен Broadcast Receiver с фильтром на READ_SMS_BROADCAST_ACTION:
val intentFilter = IntentFilter(READ_SMS_BROADCAST_ACTION) registerReceiver(MyBroadcastReceiver(), intentFilter)
Чтобы Account Kit увидел СМС, оно должно выглядеть так:
prefix_flag short message verification code is XXXXXX hash_value
prefix_flag — это префикс сообщения. Account Kit распознает <#>, [#] и невидимые Unicode символы, например, \u200b.
short message verification code is XXXXXX — текст для пользователя.
hash_value — хеш от имени пакета.
Пользователь получит сообщение «<#> Habratest: 458329 — Just test code qkASxAkMJOE».
5. В моем приложении есть реклама. Я могу ее показывать с помощью HMS?
Пока рекламная платформа доступна только для корпоративных аккаунтов, но скоро её смогут внедрить в свои приложения все разработчики. Для этого у нас уже готов свой Ads Kit. В нем можно создавать баннеры и интегрировать их в приложение. Баннеры представляют собой объекты View в Android. Добавить их можно так:
<com.huawei.hms.ads.banner.BannerView android:id="@+id/hw_banner_view" android:layout_width="match_parent" android:layout_height="wrap_content" hwads:adId="testw6vs28auh3" hwads:bannerSize="BANNER_SIZE_360_57"/>
Кроме банерной рекламы, есть Native Ads, которые встраиваются через верстку:
<com.huawei.hms.ads.nativead.NativeView xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" ... > <RelativeLayout ... > <com.huawei.hms.ads.nativead.MediaView android:id="@+id/ad_media" ... /> <RelativeLayout ... > <TextView android:id="@+id/ad_title" ... /> // Other assets. ... </RelativeLayout> // Other assets. ... </RelativeLayout> </com.huawei.hms.ads.nativead.NativeView>
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3638-6264-4138-b135-633962653034__image13.png)
Также есть Rewarded Ads, Interstitial Ads и реклама на сплеш-скрине — Splash Ads, обо всем этом можно прочитать в документации:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3030-6665-4763-a666-356464303866__image8.png)
Платформа позволяет зарабатывать на встроенных покупках. Чтобы создать этот инструмент, в консоли разработчика необходимо добавить продукт:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3736-3034-4631-b364-623734616432__image11.png)
И в самом приложении уже добавить код покупки:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) { String productId = (String) products.get(pos).get(DemoActivity.this.item_productId); gotoPay(DemoActivity.this, productId, IapClient.PriceType.INAPP_CONSUMABLE); } });
Если приложение использует свою систему оплаты, то будет полезно прочитать про Wallet Kit. Этот SDK позволяет хранить безопасно данные банковских, подарочных и скидочных карт, купонов и билетов на транспорт или мероприятия. Включить функции Wallet Kit также можно из консоли разработчика:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6232-3264-4461-b966-396337333235__image24.png)
6. А приложение сможет одновременно работать и с HMS, и с GMS?
Да, проблем не будет. Подключение двух сервисов в приложении ничем не отличается от установки одной библиотеки. Единственное, лучше проверять и инициализировать библиотеки в зависимости от поддержки.
Для AppGallery не обязательно делать отдельную сборку. Можно загружать ту же сборку, что и в остальные маркеты, и, например, в рантайме выбирать, инициализировать ли HMS/GMS. Конечно, лучше разделить эти сборки, но концептуально у разработчика есть свобода выбора.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6333-6336-4562-a535-616235386464__image5.png)
После добавлении библиотеки в семпл APK «прибавляет в весе» всего ~500кб. Для сравнения, GMS «съедают» чуть больше — примерно 600кб.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3233-6263-4533-b764-393064653839__image16.jpg)
7. Тогда встает вопрос о работе на «родном» Android от Google. Как будет функционировать приложение с Push Kit от Huawei без HMS на устройстве?
Если на устройстве без HMS запустить HMS библиотеку, ничего страшного не случится. Например, если инициализировать Push Kit, в лог посыпятся ошибки вида Failed to find HMS apk, а пользователя встретит экран с просьбой установить HMS:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6538-6336-4165-a337-383466313138__image4.png)
Лучше убирать запросы к HMS под if’ы. Например, так можно проверить, есть ли на устройстве HMS:
fun isHmsAvailable(context: Context): Boolean { val result = HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context) val isAvailable = ConnectionResult.SUCCESS == result Log.i(TAG, "isHmsAvailable: " + isAvailable); return isAvailable; }
Обратная ситуация (когда GMS нет) тоже возможна:
fun isGmsAvailable(context: Context): Boolean { val result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) val isAvailable = ConnectionResult.SUCCESS == result Log.i(TAG, "isGmsAvailable: " + isAvailable); return isAvailable; }
8. Давайте поговорим про аналоги сервисов Google. Чем можно заменить firebase database?
На данный момент существует сервис, очень похожий на Firebase Database — Cloud DB, который находится в Beta-доступе:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6535-6136-4330-a230-376334353861__image9.png)
Импортировать данные можно так:
CloudDBZoneTask<Integer> upsertTask = mCloudDBZone.executeUpsert(bookInfo); if (mUiCallBack == null) { return; } upsertTask.addOnSuccessListener(new OnSuccessListener<Integer>() { @Override public void onSuccess(Integer cloudDBZoneResult) { Log.w(TAG, "upsert " + cloudDBZoneResult + " records"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { mUiCallBack.updateUiOnError("Insert book info failed"); } });
Экспортировать чуть сложнее из-за особенности облачной базы данных. После регистрации слушателя устройство будет оповещено об изменении данных на сервере и обновит их у себя локально:
private OnSnapshotListener<BookInfo> mSnapshotListener = new OnSnapshotListener<BookInfo>() { @Override public void onSnapshot(CloudDBZoneSnapshot<BookInfo> cloudDBZoneSnapshot, AGConnectCloudDBException e) { if (e != null) { Log.w(TAG, "onSnapshot: " + e.getMessage()); return; } CloudDBZoneObjectList<BookInfo> snapshotObjects = cloudDBZoneSnapshot.getSnapshotObjects(); List<BookInfo> bookInfos = new ArrayList<>(); ...
9. Ок, заинтересовали. А что у вас с магазином приложений? Как идет ревью, можно ли добавлять бета-тестировщиков в Huawei AppGallery?
Правила публикации не сильно отличаются от правил в Google Play и Apple AppStore, а сама проверка приложения занимает два рабочих дня. Правда, для рынка КНР потребуются дополнительные документы, такие как сертификат об авторском праве.
Функция бета-теста в AppGallery есть. Можно настроить ранний доступ или ограничивать установку приложения, например, по моделям Huawei/Honor:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild6161-3661-4965-a136-623733356464__image18.png)
Также для удобного релиза приложений Huawei AppGallery поддерживает загрузку App Bundle и Split APK:
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/11811578/tild3538-3064-4162-a665-353462353130__image21.png)
10. Можно ли настроить автодеплой в Huawei AppGallery?
Да, это легко можно сделать через Publishing API AppGallery. Для начала нужно получить Upload URL:
HttpGet get = new HttpGet("https://connect-api.cloud.huawei.com/api/publish/v2/upload-url?appId=" + appId + "&suffix=" + suffix); get.setHeader("Authorization", "Bearer " + token); get.setHeader("client_id", clientId);
Затем загрузить файл:
HttpEntity reqEntity = MultipartEntityBuilder.create() .addPart("file", bin) .addTextBody("authCode", authCode) // Obtain the authentication code. .addTextBody("fileCount", "1") .addTextBody("parseType","1") .build();
И финально обновить информацию о сборке:
HttpPut put = new HttpPut(domain + "/publish/v2/app-info?appId=" + appId); put.setHeader("Authorization", "Bearer " + token); put.setHeader("client_id", clientId); JSONObject keyString = new JSONObject(); //Request Body keyString.put("defaultLang", "zh-CN"); keyString.put("isFree", 0); keyString.put("childType", 15); keyString.put("grandChildType", 10043);
Уфф, вроде ответили. Правда, в процессе работы вопросов будет гораздо больше, но вы всегда можете найти документацию по нашим сервисам на официальном портале. Там же можно получить техническую поддержку, посмотреть обучающие видео и зарегистрировать учетную запись разработчика.
Хабр, 谢谢您的关注!
ссылка на оригинал статьи https://habr.com/ru/articles/505102/
Добавить комментарий