Привет, Хабр! С мая 2019 года из-за санкций США мы остались без приложений и API для Android от Google. Из-за этого нашим устройствам грозило будущее без push-уведомлений, магазина и облачных сервисов.

Естественно, мы не опустили руки, а разработали и запустили платформу Huawei Mobile Services, которая заменила сервисы Google для наших устройств. Чтобы вы с ней познакомились и интегрировали в свои приложения, мы собрали 10 самых популярных вопросов, которые возникают у разработчиков, впервые столкнувшихся с HMS.

1. Про GMS я прекрасно все знаю, а что включает платформа HMS?
Платформа HMS полностью заменяет GMS, поэтому почти на каждый сервис Google у нас есть альтернатива: браузер, голосовой помощник, магазин приложений, облачные сервисы и инструменты для разработчиков.
Так как мы разрабатывали сервисы с нуля, то сразу разделили их на группы:
  • Сервисы 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-сообщения пользователям:
2. Как мне быстро адаптировать свои приложения для работы с HMS и протестировать их без телефонов Huawei или Honor??
А вот тут мы постарались: сделали облачные сервисы тестирования и дебаггинга, которым у Google нет аналога, и конвертер для адаптации готового кода для нашей платформы.
Облачные сервисы для разработки и тестирования доступны на главном экране консоли сразу после регистрации на платформе и подтверждения доступа. С их помощью можно из веб-интерфейса запускать эмулятор на серверах Huawei, чтобы не покупать ферму устройств или мощные компьютеры.
Экран с сервисами можно конфигурировать, добавляя или удаляя элементы:
В Cloud testing прямо из консоли перед релизом запускаются автотесты и отслеживаются обнаруженные баги:
В Cloud Debugging можно получить доступ к эмуляторам. Для этого нужно с помощью поиска по региону, серии, версии андроида и версии EMUI выбрать целевой телефон:
Прямо из веб-интерфейса можно загрузить приложение и покликать по нему:
В эмуляторе можно даже поиграть в китайский аналог Minecraft. Правда, прежде чем добраться до игрового экрана, придется понажимать кучу кнопок на китайском языке:
Такой способ будет удобен для разработчиков тяжеловесных приложений, так как дает возможность проводить тесты на большом количестве устройств прямо из веб-консоли.
Еще одним удобным инструментом для быстрой адаптации приложений для нашей платформы является Huawei Core ToolKit plugin для Android Studio, который конвертирует код, работающий с GMS, под нашу платформу. Установить плагин можно прямо из встроенного магазина:
После установки в трее появится пункт HMS. Чтобы начать конвертацию, нужно выбрать New Conversion:
Перед конвертацией необходимо указать директорию для резервного копирования:
И подтвердить конвертацию:
В коде проекта можно вручную отследить каждое изменение и либо применить его, либо проигнорировать. Дополнительно после конвертации в директории проекта появится отдельный модуль с README. md, где можно будет посмотреть, что делает сконвертированный код.
3. Что с аутентификацией пользователя?
По аналогии с «Sign with Google» и «Sign with Apple» у нас есть свой сервис «Sign with HUAWEI». Он является частью Account Kit и работает со всеми пользовательскими устройствами Huawei и Honor:
Сам процесс авторизации стандартный, подробную инструкцию по интеграции можно найти на сайте или в Codelab.
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>
Также есть Rewarded Ads, Interstitial Ads и реклама на сплеш-скрине — Splash Ads, обо всем этом можно прочитать в документации:
Платформа позволяет зарабатывать на встроенных покупках. Чтобы создать этот инструмент, в консоли разработчика необходимо добавить продукт:
И в самом приложении уже добавить код покупки:
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 также можно из консоли разработчика:
6. А приложение сможет одновременно работать и с HMS, и с GMS?
Да, проблем не будет. Подключение двух сервисов в приложении ничем не отличается от установки одной библиотеки. Единственное, лучше проверять и инициализировать библиотеки в зависимости от поддержки.
Для AppGallery не обязательно делать отдельную сборку. Можно загружать ту же сборку, что и в остальные маркеты, и, например, в рантайме выбирать, инициализировать ли HMS/GMS. Конечно, лучше разделить эти сборки, но концептуально у разработчика есть свобода выбора.
После добавлении библиотеки в семпл APK «прибавляет в весе» всего ~500кб. Для сравнения, GMS «съедают» чуть больше — примерно 600кб.
7. Тогда встает вопрос о работе на «родном» Android от Google. Как будет функционировать приложение с Push Kit от Huawei без HMS на устройстве?
Если на устройстве без HMS запустить HMS библиотеку, ничего страшного не случится. Например, если инициализировать Push Kit, в лог посыпятся ошибки вида Failed to find HMS apk, а пользователя встретит экран с просьбой установить HMS:
Лучше убирать запросы к 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-доступе:
Импортировать данные можно так:
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:
Также для удобного релиза приложений Huawei AppGallery поддерживает загрузку App Bundle и Split APK:
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); 
Уфф, вроде ответили. Правда, в процессе работы вопросов будет гораздо больше, но вы всегда можете найти документацию по нашим сервисам на официальном портале. Там же можно получить техническую поддержку, посмотреть обучающие видео и зарегистрировать учетную запись разработчика.


Хабр, 谢谢您的关注!

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

    +1
    Спасибо за статью.
    Некоторые мечтают отказаться от пушей гугла, но не хотят выжирания своей батареи, а open-push пока еще очень слабый — что и понятно, когда денег мало.
    Я понимаю, что у некоторых других отношение к Китаю тоже недоверчивое, но если майки и еще многие монстры не считают зашкваром свое участие в open source, то мож и ваша кампания денег подкинет этому проекту?
    Да, я наивен, но а вдруг?.. ;)
      +1
      Присоединяюсь к вопросу. Когда кто-то сталкивается с нечестной конкуренцией и попранием общественных прав, копать своё болото с блекджеком и пушами, это ну такое… очередная коропрация добра это плохой социальный ход. А вот решить проблему раз и навсегда через open-source и иметь моральное право продвигать это решение на любые платформы, вот это уже хорошо.
        +1
        Спасибо за поддержку: вот бы до китайских топов эту простейшую и имхо эффективную и эффектную мыслю донести. Такому крупному вендору явно будет не в тягость, а PR-политика даже для всего Китая опять выиграет.
        Эх, мечты!..

        Да, я понимаю, что чужие деньги в чужом кармане очень заманчивы, но а вдруг?
      +1

      А какой у Huawei браузер, на чём основан, можно ли поставить на не-Heawei устройства?

        +1
        У Huawei браузер собственной разработки, который называется Huawei Browser. Он основан на Chromium. Чтобы его скачать, можно установить его с магазина Huawei AppGallery, который возможно установить на все Android устройства.
        Вот ссылка загрузку магазина с официального сайта: consumer.huawei.com/ru/mobileservices/appgallery-russian
        0

        Как разработчику, то для меня это ещё больше кода, но иначе останусь без пользователей (коих у Huawei достаточно). Но в связи с ситуацией, то очень достойное решение проблемы.

          0
          Вот в этом и дело. Для нас в Huawei — это повод создать свою уникальную экосистему, при этом не сильно усложнив переход для разработчиков на неё. HMS продолжит своё прогрессивное развитие.
          +1
          И ещё нафига вы сделали авторизацию на час для тех, кто хочет отправлять пуши в своё приложение. Это ой как неудобно для демонов, приходится городить отдельные потоки, которые отслеживают токен и обновляют его. Посмотрите на гугл и эпл, там авторизация по сертификатам почти бесконечная.
            +5
            Остался неотвеченным главный вопрос, который интересует очень многих владельцев техники указанного бренда.
            А именно — Когда Huawei вернет возможность разблокировки загрузчика?
            В настоящий момент Huawei ограничивает права покупателя устройства, не позволяет владельцу полноценно распоряжаться смартфоном.
            Многие были бы рады «спрыгнуть» с HMS на кастомные прошивки (с GMS или без оных), но при текущей ситуации с загрузчиком разработка последних не представляется возможной.
              +1
              >очень многих владельцев
              >Многие были бы
              Ну, то есть, на самом деле, некоторые, из числа посетителей 4pda. Вы же всерьез не думаете, что вот те люди, которые в салонах мобильной связи приобретают смартфоны, мечтают разблокировать загрузчик, поставить кастомную прошивку и «полноценно распоряжаться»? Потребителя интересует возможность пользоваться устройством, а фич он ожидает от производителя.
                0
                Я ребёнку вместо хуавея купил леново. Ровно по причине рута.
                а кастомы… на работе даже у швей и грузчиков не такая редкость.
                0
                Я вот ухватил одну из последних моделей с открытым загрузчиком. И делать с ним нечего. Разработчикам кастомных прошивок нет мотивации работать с Kirin, у которого слишком маленькая собственная аудитория, из-за чего есть две с половиной неофициальные прошивки с неработающими функциями, а работающие root-приложения можно пересчитать по пальцам одной руки опытного фрезировщика, потому что разработчикам малочисленная аудитория с телефонами Huawei не окупит затраты времени для написания версии под Kirin. Так что с разблокированным загрузчиком можно максимум убрать рекламу из приложений, да и то не везде срабатывает даже это.
                  0

                  Аудитории у Хуавей хватает. Портируют всякое и при меньшей аудитории (тот же gcam на redmi note 8 pro на МТК). Но т.к 95% устройств huawei огорожено, аудитория ничем воспользоваться не может => и портировать смысла нет.


                  А так — возможность вкатать бы кастомную прошивку со всем гугловским добром (иди чисто гугловское добро) отдельно + возможность анлокнуть camera2api и норм было бы.


                  P.S. всё время было интересно — что мешало по примеру сяоми/мейзу для CN-рынка вместо запрещенных гугло-сервисов выкатить в собственный магазин приложение для установки этих сервисов в юзерспейс. И санкции соблюдены (прошивка чиста, софт уже конечные юзеры сами накатили), и лишних фоновых троянов гугла в системе нет, и маркет гугловый работает.

                    +1
                    Вот я тоже раньше постоянно возился с установкой кастомов, разблокировкой загрузчика, даже портированием ядер и прошивок, так как часто неглючных прошивок от вендора не было.

                    Потом случайно купил себе телефон с нормальной прошивкой изначально, у которой не было багов — батарея держала двое суток активного пользования при 8 часах экранного времени, камера снимала отлично без всяких гуглокамер и рекламы в строенных приложениях не было.

                    В течение последующих двух лет я несколько раз пытался пересесть на «кастом» с более высокой версией андроида и тут начиналось: проигрывание видео иногда крашится, камера снимает темное видео, батарея садится на глазах, даже когда им не пользуешься. Единственное, wifi5 работал на полной скорости. И каждый раз по итогу я возвращался на сток.

                    Спустя 2,5 года я поменял тот телефон на Honor 20 — и опять, прошивка отличная, менять ее на что-то не собираюсь (если конечно при обновлении какая-нибудь бяка не прилетит).

                    Мораль сей басни такова, что если устройство нормальное изначально, то большей части пользователей эти кастомы не нужны. Да, было бы неплохо иметь рут-доступ для модификации файла hosts, но с uBlock origin в мобильном firefox'e и так нормально. А для любителей тонкой настройки «под себя» лучшим выбором будут пиксели.

                    С другой стороны, я покупаю устройство и было бы здорово иметь возможность модифицировать ПО, как мне захочется (при условии, что всю ответственность я беру на себя, проходя процедуру разблокировки загрузчика).
                      0
                      В AppGallery есть Firefox?
                        0
                        Пока нет, но мы активно работаем над помощью разработчикам в переходе на HMS и заливке приложений в AppGallery :)
                  0
                  Спасибо за статью.

                  Паритет по функциям, это, безусловно, круто. Но в чём смысл смены шила на мыло для пользователя? Заигрывание с пользователем нулевое. Был один большой брат, присматривающий за тобой, стал другой большой брат, присматривающий за тобой.

                  Аппараты у Huawei привлекают характеристиками (например, планшеты), но по факту — не покупая устройства в интернете даже не пошариться по магазину, веб-версия AppGallery крайне скромная.

                  Вот что ты такое?

                  В результате получается не особо интересный вендор с большим вендорлоком.
                    0
                    По отношению к телефону я пользователь а не программист — как на новых Huawei мне пользоваться гугл почтой и хромом с гуглаккаунтом? Если без второго можно прожить, то без gmailа мне и устройство-то не нужно.
                      0
                      Так вроде же нативное приложение «Почта» поддерживает и Гмаил, и других поставщиков почты из коробки. Поправьте, если ошибаюсь.
                        0
                        Понятия не имею — к стыду не юзал :(
                          0
                          Все верно! Наше нативное приложение «Почта» поддерживает Google и других поставщиков почты. Сервисы Google при этом не нужны ;)
                        0
                        Сделайте смартфон с возможностью установки туда произвольной операционки. Начните сотрудничать с теми, кто делает Linux для смартфонов. Сейчас этот рынок гиков никем не окучен — возьмите его себе.

                        Сделайте смартфон/планшет с подключаемой клавиатурой. Опять же для гиков, которым надо работать.

                        Сделайте смартфон, который можно разбирать и собирать из разных деталей. Например, хорошо бы сделать так, чтобы в одинаковом корпусе можно было поставить на выбор:
                        1. одну из нескольких плат, различающихся мощностью процессора и количеством памяти (некоторые платы должны позволять ставить в них дополнительные Flash-карты и организовывать RAID-массив);
                        2. один из нескольких экранов, различающихся разрешением и, возможно, типом (резистивный, ёмкостной).
                        И всё это д.б. совместимо между собой.

                        Хорошо бы сделать возможность соединения устройств между собой в единую вычислительную систему. Примерно так: «смартфон в руках, планшет в сумке, смартфон показывает фильм, хранящийся на планшете». Соединение — как по радио, так и по кабелю.
                        Среди устройств, допускающих такое соединение — д.б. пауэрбанка с возможностью втыкания туда флешек. Это расширяет сразу и автономность по питанию, и ёмкость накопителя.
                          0
                          Спасибо за статью.
                          Было бы круто если бы в HMS Core ещё появилась функционал по чтению кодов из смс аналогичный SMS User Consent API от Google. Там не надо в саму СМС дбавлять ни #, ни хэш ключа подписи.
                          Когда приходит СМС, сервис спрашивает юзера: разрешить приложению прочитать смс и если юзер нажимает разрешить код отдаётся приложению.

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