Cómo agregamos compatibilidad con Harmony OS a la aplicación inDriver para Android

Todo comenzó con el hecho de que el Departamento de Comercio de EE. UU. Incluyó a Huawei en la lista de empresas con las que está prohibido realizar negocios con empresas estadounidenses . La respuesta de Huawei fue el sistema operativo Harmony OS para sus teléfonos inteligentes y la negativa a utilizar los servicios de Google en él. Y para no perder parte del mercado, integramos su soporte en inDriver. Aunque la "integración del sistema operativo" suena fuerte: nuestra aplicación, como cualquier otra escrita para Android, se ejecutará en Harmony, pero para el trabajo completo es necesario reemplazar los servicios de Google por otros similares de Huawei.



En inDriver, utilizamos los servicios de Google para 3 propósitos:

  • Envío de notificaciones push;
  • Definición de ubicación;
  • Mapas de Google.

Push Kit: envía notificaciones push


Para empezar, Huawei tiene bastante buena documentación . Pero para comenzar rápidamente, solo use el tutorial paso a paso .

No volveré a contar lo que está escrito allí, me detendré solo en algunos puntos, ya que aquí se necesitan comentarios.

Habilitación del servicio

Se le pedirá que configure la ubicación de almacenamiento de datos. Tenga en cuenta que no puede cambiarlo más tarde . La ubicación no afecta la operación directa del envío, pero es solo un lugar para almacenar y procesar datos sobre ellos.

Integrando el SDK de HMS

Después de completar la integración, probablemente tendrá problemas para construir el proyecto. En cualquier caso, este fue el caso en nuestro servidor de compilación Ubuntu 16.04.5 LTS (GNU / Linux 4.4.0-174-generic x86_64), mientras que localmente en el Mac mini (finales de 2018, Mojave) todo funcionó bien. Puede arreglar esto si agrega

Execution failed for task ':app:processIndriverReleaseManifest'. org.gradle.api.GradleException: ERROR: no manifest file found



agcp {
   manifest false
}

al final del archivo build.gradleen el nivel de aplicación para deshabilitar el manifiesto agcp. El problema aquí es más bien que está agcpbuscando un archivo de manifiesto, pero no puede encontrarlo y cargarlo, lo que probablemente sea un problema agconnect. Al menos así es como nos respondió el soporte técnico oficial de Huawei.

Configuración de AndroidManifest.xml

No sé por qué, pero no dice sobre la inicialización automática, que se describe en la sección 2.6 Inicialización automática de la documentación completa. Esto es necesario si envía un token al servidor en el método

public void onNewToken(String token) {}

Envío de mensajes: HUAWEI Push Kit Console.

Con él, puede verificar el funcionamiento del empuje. Un hecho interesante: si selecciona en la consolaType: Notification Message, seonMessageReceived(RemoteMessage message)mostrarán inmediatamente en el teléfono sinpasar por el controlador.

Cuando configuré el push, a menudo tenía que usar la consola. Tanto ella como los mensajes enviados desde el servidor tuvieron retrasos de hasta 30 minutos. Espero que estas hayan sido dificultades temporales que los desarrolladores ya han enfrentado.

Ahora tenemos dos servicios push en nuestro teléfono, pero ¿cómo podemos organizar su trabajo conjunto? Primero debe determinar qué servicios están disponibles en el teléfono. En nuestro lugar, decidimos que los servicios de Google serían una prioridad para nosotros. Suponga que si los servicios de Google y Huawei están disponibles en el teléfono, trabajamos con Google.

Enviamos el indicador de estado de los servicios al servidor con posibles valores:

- UNKNOWN
- GOOGLE
- HUAWEI

fun checkServices(context: Context): PlayServicesState {
   val googleAPI = GoogleApiAvailability.getInstance()
   when (googleAPI.isGooglePlayServicesAvailable(context)) {
       ConnectionResult.SUCCESS,
       ConnectionResult.SERVICE_MISSING,
       ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED,
       ConnectionResult.SERVICE_DISABLED -> return PlayServicesState.GOOGLE
   }
   val huaweiAPI = HuaweiApiAvailability.getInstance()
   when (huaweiAPI.isHuaweiMobileNoticeAvailable(context)) {
       com.huawei.hms.api.ConnectionResult.SUCCESS,
       com.huawei.hms.api.ConnectionResult.SERVICE_MISSING,
       com.huawei.hms.api.ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED,
       com.huawei.hms.api.ConnectionResult.SERVICE_DISABLED -> return PlayServicesState.HUAWEI
   }
   return PlayServicesState.UNKNOWN
}

Dependiendo del valor recibido, el servidor enviará notificaciones push al servicio correspondiente.

Organizar su trabajo es una cuestión de tecnología. Yo solo hice eso.

Manejo de eventos para FCM:

class AppFcmListenerService : FirebaseMessagingService() {
   private val cloudMessageHandler: CloudMessageHandler = GoogleMessageHandler(this)
   override fun onMessageReceived(message: RemoteMessage) {
       cloudMessageHandler.onMessageReceived(message)
   }
}

y HCM:

class AppHmsListenerService : HmsMessageService() {
   private val cloudMessageHandler: CloudMessageHandler = HuaweiMessageHandler(this)
   override fun onMessageReceived(message: RemoteMessage) {
       cloudMessageHandler.onMessageReceived(message)
   }
}

delegado a la clase abstracta:

abstract class CloudMessageHandler { 
fun onMessageReceived(message: Any) {
   val data = getData(message)
   onMessageReceived(data)
}
private fun onMessageReceived(data: Map<String, String>) {
   //   
}
abstract fun getData(message: Any) :  Map<String, String> {
}

que tiene dos implementaciones:

para FCM:

class FirebaseMessageHandler(override val context: Context) : CloudMessageHandler(context) {
   override fun getData(message: Any): Map<String, String> {
       return (message as RemoteMessage).data
   }
}

para HCM:

class HuaweiMessageHandler(override val context: Context) : CloudMessageHandler(context) {
   override fun getData(message: Any): Map<String, String> {
       return (message as RemoteMessage).dataOfMap
   }
}

Las clases de Huawei tienen una interfaz casi similar con los servicios de Google. Este "casi" He manifestado personalmente en el hecho de que RemoteMessagefuera com.google.firebase.messagingpara Map<String, String>que desea llamar RemoteMessage.getData(), y por RemoteMessagefuera com.huawei.hms.push- getDataOfMap().

Kit de ubicación - determinación de ubicación


Se pueden gestionar ubicaciones LOCATION_SERVICE, que están disponibles sin los servicios de Google y Huawei. Pero para el servicio de transporte de pasajeros, la determinación precisa de la ubicación es un parámetro importante. Afortunadamente, las interfaces de las clases del Kit de ubicación no fueron diferentes de las del mismo nombre para los servicios de Google, por lo que su aplicación en el código no fue diferente. Sin embargo, los servicios de Huawei fueron menos precisos en la operación. Espero que este sea un problema temporal.
También encontramos el hecho de que la solicitud de geolocalización se envía a través del HMS Core, lo que significa que para un funcionamiento correcto es necesario establecer los derechos de geolocalización como "Permitir siempre".

ubicación

Sustitución de Google Maps


En el CIS, utilizamos un motor OSM con mosaicos 2GIS. En la primera etapa de integración, decidimos no trabajar con el Kit de mapas de HUAWEI, sino simplemente usar el motor OSM con mosaicos OSM. Todo es simple

Antes del lanzamiento


Aconsejo a todos que presten atención a las causas comunes de falla antes de iniciar su aplicación en AppGallery.

Por ejemplo, el equipo de lanzamiento de Huawei nos informó de las siguientes violaciones.

La presentación no estándar de Hong Kong y Macao

China es escrupulosa acerca de la soberanía de sus regiones administrativas autónomas y les pide que se les llame "región". Esto nos obligó a cambiar todos los títulos que mencionan el país para mencionar el país o la región.



Información sobre productos de la competencia de terceros en los detalles de la aplicación

No olvide calificar la aplicación enviando al usuario a la página en la Galería de aplicaciones, no a Google Play Store :)

En general, los servicios de Huawei son similares a los servicios de Google y su apoyo directo en el código no causa dificultades. Las preguntas solo pueden hacerse al "ecosistema" de Huawei en su conjunto, pero pueden atribuirse a su juventud y con una alta probabilidad de que todo mejore con el tiempo.

All Articles