Huawei Services, зачем, почему и как собирать проект?

Немного вводных

Huawei поставляет Android-смартфоны без сервисов Google и привычного магазина приложений Google Play, создав аналоги: Huawei Services и AppGallery.

Для нас, разработчиков, это 420 миллионов активных пользователей на 700 миллионов устройств. Для поддержки пользователей потребуется оформление документов. В статье мы поговорим только о использование сервисов.

Настройка проекта

Уверен, что вы сможете адаптировать инструкцию под вашу версию Gradle,
архитектуру проекта, Kotlin DSL.

Для настройки проекта требуется конфигурационный файл agconnect-services.json аналог google-services.json. Получаем его в консоли разработчика после регистрации проекта.

build.gradle (project)

buildscript {  
    repositories {  
        google()  
        maven { url 'https://developer.huawei.com/repo/' }  
    } 
 
    dependencies {  
	    ....
        classpath 'com.huawei.agconnect:agcp:1.4.2.301' 
    }  
}

allprojects {  
    repositories {  
        google()   
        maven { url 'https://developer.huawei.com/repo/' }  
    }  
}

build.gradle (app)

if(getGradle().getStartParameter().getTaskNames().toString().toLowerCase().contains("huawei")) {
    apply plugin: 'com.huawei.agconnect'
} else {
    //Плагины других сервисов
}

dependencies {
...
	implementation "com.huawei.agconnect:agconnect-core:1.4.1.300”
...	
}

Для ProGuard:

-ignorewarnings 
-keep class com.huawei.agconnect.**{*;}

 Для DexGuard:

-ignorewarnings
-keep class com.huawei.agconnect.** {*;} 
-keep resourcexmlelements ** 
-keep resources */*

Если есть потребность поддерживать несколько площадок(AppGallery, Google Play)
и сервисов(Huawei, Google), то надо учитывать достаточно частую смену политик маркетов.

Google в одном из обновлений запретила размещать приложения c зависимостями от Huawei Services. Лучшим решением будет разделение сборок.

Отдельные сборки Huawei и Google

Есть несколько реализаций и самый простой выглядит так.

  1. Подготовить build flavours huawei и google

    flavorDimensions "mobileServices"
    productFlavors {    
      
        google {
            dimension "mobileServices"
        }
    
        huawei {
            dimension "mobileServices"
            applicationIdSuffix ".huawei"
        }
    }
  2. Разделить все зависимости в build.gradle (app) с помощью googleImplementation
    и huaweiImplementation

    
    dependencies {
    ...
        huaweiImplementation "com.huawei.agconnect:agconnect-core:1.4.1.300”
    ...	
    }
  3. Положить agconnect-services.json в директорию src/huawei ,
    а google-services.json в директорию src/google. Так как они нужны только для определённой сборки и application package у них разные. Для публикации huawei сборки к пакету обязательно добавляется “.huawei”

  4. В директории src/main создаём интерфейс будущего сервиса, а реализацию кладём в директории src/huawei и src/google. Названия будут те, которые указаны в productFlavors. При выборе варианта сборки запустится синхронизация Gradle файлов и подставится нужная реализация.

Рассмотрим пример с MessagingService

Важно учитывать ваш подход к асинхронной/мультипоточной работе. В Google Services есть класс Task для получения callback'ов, но в Huawei Services его нет. Kotlin coroutine подходят на замену своей легковесностью. Тогда бы мы использовали suspend function. Допустим у нас жёсткими ограничениями на библиотеки и нет корутин. Тогда можно вспомнить старый добрый Thread. Прекрасное решение, но дорогое, поэтому у нас будет ThreadPoolExecutor, настроенный под наши нужды.

class MessagingServiceImpl : MessagingService {
   private var executor: ввExecutorService = ThreadPoolExecutor(
        CORE_THREAD_POOL_SIZE,
        MAX_THREAD,
        KEEP_ALIVE_THREAD_TIME,
        TimeUnit.SECONDS,
        LinkedBlockingQueue(CAPACITY_QUEUE),
        ThreadUtils().threadFactory(Process.THREAD_PRIORITY_BACKGROUND)
   )
   private val handler = HandlerCompat.createAsync(Looper.getMainLooper())

  override fun getToken(successCallback: (token: String) -> Unit) {
    val task = Callable {
      val token = instanceId.getToken(appId, tokenScope)
      if (token != null && token.isNotEmpty())
          handler.post {
              successCallback(token)
          }

    }
    
    executor.submit(task)
 }

  override fun deleteToken(successCallback: () -> Unit) { 
    val task = Callable {
        instanceId.deleteToken(appId, tokenScope)
        handler.post {
            successCallback()
        }
    }

    executor.submit(task)
  }


  companion object {
     private const val CORE_THREAD_POOL_SIZE = 0
     private const val MAX_THREAD = 1
     private const val KEEP_ALIVE_THREAD_TIME = 5L
     private const val CAPACITY_QUEUE = 1
  }
}

class ThreadUtils {

  fun threadFactory(
    priority: Int
  ): ThreadFactory = PriorityThreadFactory(priority)
}

private class PriorityThreadFactory(
    private val threadPriority: Int
) : ThreadFactory {

  override fun newThread(runnable: Runnable): Thread {
    val wrapperRunnable = Runnable {
        try {
            Process.setThreadPriority(threadPriority)
        } catch (throwable: Throwable) {
            Timber.e(throwable)
        }
        runnable.run()
    }
    
    return Thread(wrapperRunnable)
  }

}

Вуаля, мы рассмотрели замену Task'ам и подготовили проект для подключения нужных нам сервисов, которое используют идентичное Google Services api.

Tooling

Если у вас есть большой проект с сервисами Google, то плагин ide HMS Toolkit будет очень полезный.

Основные функции:

  • Анализ всех мест использования Google сервисов

  • Замена Google сервисов на Huawei

Предупреждение 1

Плагин зависит от версии Androi Studio. На последних версиях плагин в сторе плагинов внутри студии не найдёшь. Для работы отдельно можно скачать студию более низкой версии.

Предупреждение 2

Если вам пришлось скачать Android Studio более низкой версии
(Смотри предупреждение 1), после установки и открытия проекта можно получить ошибку несовместимости Gradle.

После анализа есть два варианта действий:

  1. Add HMS API. На основе существующих в проекте GMS APIs генерируется XMS adapter (как дополнительный модуль в проекте). Он представляет собой прослойку между нашим кодом и непосредственно вызовом сервисов. Это такие Extension-классы, в которых лежит код, поддерживающий HMS и GMS сервисы одновременно. Add HMS API(в скобках описывается приоритет). В runtime определяется поддерживаемый девайсом вид сервисов и вызываются соответствующие методы. Наш вариант

  1. To HMS API – полностью заменяются GMS APIs на HMS APIs.

При желании результаты анализа можно экспортировать, например, в pdf.

Debugging

Всё готово и мы ничего не пропустили. Теперь нам нужно протестировать работоспособность сервисов, но у нас может не быть нужного устройства. Тогда на помощь приходит облачная платформа DigiX Lab для дебага и тестов.

Как можно догадаться, Cloud Debugging предоставляет бесплатное решение для облачной отладки, позволяющее решать такие проблемы:

  • Недостаточное количество моделей устройств

  • Сложности в управлении устройствами

  • Невозможность воспроизвести ошибки

  • Затраты на покупку и управление устройствами

Цель Cloud Testing — это тестирование совместимости, стабильности, производительности и энергопотребления ваших приложений на мобильных устройствах Huawei, а также создание отчётов.

Непрерывная доставка

Для автоматизации сборки можно воспользоваться Publishing API 

Заключение

С этими вводными уже можно экспериментировать, делать первые сборки, используя привычное api. Многие компании, IT гиганты уже поддерживают Huawei Services и разместили свои приложения в AppGallery. Так почему бы и вам не осчастливить пользователей своим приложением?

Полезные ссылки

Комментарии (5)


  1. Getequ
    21.04.2022 19:40
    +1

    Угораздило недавно купить планшет хуавей с AppGallery. Думал что наши китайские браться с рынком миллиардной аудитории смогут, но увы. Какое же это убожество. Элементарно ютуб не установить без регистрации в хуавей. Само ютуб-приложение не нативное как у гугла, а с плашкой в верхнем правом углу, перекрывающее область уведомлений и аккаунта. Виджет поиска просто ужасен, как-будто студенты курсовую писали. Фаерфокс "магазин приложений" вовсе предложил скачать установщик с левого сайта. Что же они там делают все эти 9-9-6 часов?

    п.с. не покупайте эти поделки, даже детям. Не надо травмировать им психику


    1. r2d
      22.04.2022 10:08
      -1

      Много лет пользуюсь продукцией Huawei! Хорошая продукция у них, не надо вводить людей в заблуждение. В интернете полно инструкций как установить PlayMarket да и в самом AppGalary уже много всего есть. Вот выйдет NashStore над ним и постебаемся


      1. Getequ
        22.04.2022 14:03
        +1

        Продукт должен работать из коробки без танцев с бубном если это продукт компании уровня хуавей, а не очередной ноунейм вроде оппо, виво и иже с ними. Во всяком случае я не "линуксоид", что бы кайфовать от процесса настройки. Телефон у меня хуавей с гугл-сервисами, к нему никаких претензий не имею.


  1. dotnetfx40
    22.04.2022 10:27

    А зачем нужен AppGalary ? Если они так же как и гугл выкидывают прилагухи в угоду политики. Как мы видим при таком поведении алтернатвиой плеймаркету они не являються.


    1. AlexDeko Автор
      22.04.2022 22:00

      В этой статье AppGallery рассматривалась не как замена Google Play, а как способ привлечения новых пользователей, которые могут использовать только Huawei Services. Если у вас приложение выложено в одном маркете, то почему бы не разместить его в другом?