Как объединить мобильные сервисы Google и Huawei в одной кодовой базе

Управление библиотеками HMS и GMS в Android-приложении со временем может стать довольно сложным. Поговорим о том, как легко выйти из этой ситуации.

Введение

Сегодня речь пойдет об использовании библиотек HMS и GMS в одной кодовой базе. В качестве примера рассмотрим применение Google Maps и Huawei Map Kit в одном проекте.

Прежде всего, добавим зависимости в проект.

dependencies {
...

// GMS
implementation 'com.google.android.gms:play-services-base:18.2.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-maps:18.1.0'

// HMS ( https://developer.huawei.com/consumer/en/doc/development/hmscore-common-Guides/integrate-sdk-0000001167185652 )
implementation 'com.huawei.hms:hmscoreinstaller:6.6.0.300'
implementation 'com.huawei.hms:hwid:5.0.1.301'
implementation 'com.huawei.agconnect:agconnect-core:1.7.2.300'
implementation 'com.huawei.hms:maps:5.0.5.301'

}

apply plugin: 'com.huawei.agconnect'

Теперь создадим соответствующие функции, которые проверяют, активны ли сервисы GMS и HMS на нашем телефоне.

// Функция, контролирующая, используются ли сервисы Google.
fun isGooglePlayServicesAvailable(context: Context): Boolean {
val googleApiAvailability = GoogleApiAvailability.getInstance()
val resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context)
return resultCode == ConnectionResult.SUCCESS
}
// Функция, проверяющая, используются ли сервисы Huawei.
fun isHuaweiMobileServicesAvailable(context: Context): Boolean {
val huaweiApiAvailability = HuaweiApiAvailability.getInstance()
val resultCode = huaweiApiAvailability.isHuaweiMobileServicesAvailable(context)
return resultCode == com.huawei.hms.api.ConnectionResult.SUCCESS
}

По значениям true и false, возвращаемым из вышеуказанных функций, определяем, какие сервисы будут работать на нашем телефоне, а какие нет. После этого попробуем эти функции на телефонах только с сервисами Google и только с сервисами Huawei.

Результаты испытаний на телефоне только с Google-сервисами: Google-сервис вернул true, а Huawei-сервис — false (в качестве телефона использовался Pixel 3)
Результаты испытаний на телефоне только с Huawei-сервисами: Huawei-сервис вернул true, а Google-сервис — false (в качестве телефона использовался P40 Lite)

Как видно из приведенных примеров, выполнение операций с соответствующими функциями зависит от того, какой сервис активен или неактивен в телефоне в данный момент.

После проведенных проверок можно добавить Google Maps и Huawei Map Kit в проект. Сначала подготовим все, что связано со стороной XML.

Ниже  —  определение карт Google и Huawei, которые будут отображаться на экране на стороне XML.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context=".MapsActivity"
android:visibility="gone"
android:name="com.google.android.gms.maps.SupportMapFragment" />

<com.huawei.hms.maps.MapView
android:id="@+id/huaweiMapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:uiCompass="true"
app:uiZoomControls="true" />

</androidx.constraintlayout.widget.ConstraintLayout>

Теперь добавляем OnMapReadyCallback для Google Maps и Huawei Map в класс в соответствующей Activity. Кроме того, в этот класс необходимо добавить функции onMapReady для каждого из двух картографических сервисов.

Добавление OnMapReadyCallback для Google Maps и Huawei Map в класс в соответствующей Activity
// Функция OnMapReady для Google Map
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Добавить маркер для Сиднея и подвинуть камеру
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(
MarkerOptions()
.position(sydney)
.title("Marker in Sydney")
)
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}

// Функция OnMapReady для Huawei Map Kit
override fun onMapReady(p0: HuaweiMap?) {

huaweiMap = p0!!
huaweiMap.uiSettings.isCompassEnabled = true

}

Наконец, можно использовать сервис, необходимый для вашего проекта, в зависимости от рабочего состояния соответствующих сервисов Google и Huawei на вашем телефоне.

// Создание карты Google, если доступны сервисы Google   
if (isGooglePlayServicesAvailable(this)) {

val mapFragment =
supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment!!.getMapAsync(this@MainActivity)
}

// Создание карты Huawei, если доступны сервисы Huawei
if (isHuaweiMobileServicesAvailable(this)) {
mapView = binding.huaweiMapView
var mapViewBundle: Bundle? = null
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAP_BUNDLE_KEY)
}
binding.huaweiMapView.onCreate(mapViewBundle)
binding.huaweiMapView.getMapAsync(this@MainActivity)
}

Теперь посмотрим на результаты. Сначала попробуем приложение на телефоне Pixel 3 с использованием только сервисов Google. Затем потестим его на телефоне P40 Lite, на котором работают только сервисы Huawei.

Использование Google Maps в приложении на телефоне, включающем только Google-сервисы
Использование Huawei Map Kit в том же приложении на телефоне, включающем только сервисы Huawei

Ключевые моменты

  • Не забудьте создать отдельную логику для телефонов, использующих сервисы Huawei и Google.
  • Не забудьте активировать консоль для Google Maps и Huawei Maps (Google Console для сервиса Google Map, App Gallery Connect для сервиса Huawei Map).
  • Не забудьте поместить API-ключ для Google Maps в AndroidManifest. Аналогично, не забудьте вызвать функцию MapsInitializer.setApiKey(“YOUR_API_KEY”) в Huawei Map Kit.
  • Версия Huawei Map Kit, выпущенная раньше ‘com.huawei.hms:maps:5.0.5.301’, может выдавать ошибку “map not loading” (“карта не загружается”). Убедитесь в том, что вы правильно выбрали версию.
  • При работе со значениями Google Maps и Huawei Map не забывайте импортировать значения из соответствующего класса для соответствующего сервиса. Дело в том, что большинство имен значений и функций в этих двух сервисах похожи.
  • Не забывайте добавлять значения SHA1 и SHA-256 вашего приложения в консольные части сервисов Google и Huawei. Кроме того, создайте SHA1 и SHA-256 снова для релиза, чтобы сервисы правильно работали в релиз-пакетах. (Выполните Gradle signinReport из терминала Android Studio для генерации SHA1 и SHA-256).
  • Убедитесь, что к проекту прикреплены самые актуальные версии сервисов JSON-файлов, которые вы будете загружать из консоли.

Заключение

Возможность подтвердить наличие сервисов Google и Huawei на конкретных телефонах привела к значительному скачку производительности. Эта функциональность обеспечивает гармоничную интеграцию, позволяя без труда использовать соответствующие сервисы с единой кодовой базой. Более того, она позволяет объединять сервисы Google и Huawei в приложении и выборочно их использовать по мере необходимости.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Hüseyin Özkoç: Android Google and Huawei Mobile Services in a Single Codebase

Предыдущая статьяКак реализовать feature gate в React
Следующая статьяСоздание оркестратора для событийно-ориентированного приложения с Golang и RabbitMQ