Comment nous avons ajouté la prise en charge Harmony OS à l'application inDriver Android

Tout a commencé avec le fait que le département américain du Commerce a inclus Huawei dans la liste des sociétés avec lesquelles il est interdit de faire des affaires avec des sociétés américaines . La réponse de Huawei a été le système d'exploitation Harmony OS pour ses smartphones et le refus d'utiliser les services Google. Et pour ne pas perdre une partie du marché, nous avons intégré son support dans inDriver. Bien que «l'intégration du système d'exploitation» semble forte - notre application, comme toute autre écrite pour Android, fonctionnera sur Harmony, mais pour le travail complet, il est nécessaire de remplacer les services Google par des services Huawei similaires.



Dans inDriver, nous utilisons les services Google à 3 fins:

  • Envoi de notifications push;
  • Définition de l'emplacement;
  • Google Maps.

Push Kit - envoyer des notifications push


Pour commencer, Huawei a une assez bonne documentation . Mais pour un démarrage rapide, utilisez simplement le didacticiel étape par étape .

Je ne reviendrai pas sur ce qui y est écrit, je ne m'attarderai que sur certains points, car des commentaires s'imposent ici.

Activation du service

Il vous sera demandé de configurer l'emplacement de stockage des données. Notez que vous ne pouvez pas le modifier ultérieurement . L'emplacement n'affecte pas le fonctionnement direct du push, mais n'est qu'un lieu de stockage et de traitement des données les concernant.

Intégration du SDK HMS

Une fois l'intégration terminée, vous aurez probablement des problèmes pour créer le projet. Dans tous les cas, c'était le cas sur notre serveur de construction Ubuntu 16.04.5 LTS (GNU / Linux 4.4.0-174-generic x86_64), tandis que localement sur le Mac mini fonctionnant (fin 2018, Mojave), tout fonctionnait bien. Vous pouvez résoudre ce problème si vous ajoutez

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



agcp {
   manifest false
}

à la fin du fichier build.gradleau niveau de l'application pour désactiver le manifeste pour agcp. Le problème ici est plutôt qu'il agcprecherche un fichier manifeste, mais ne peut pas le trouver et le charger, ce qui est très probablement un problème agconnect. C'est du moins ainsi que le support technique officiel de Huawei nous a répondu.

Configuration d'AndroidManifest.xml

Je ne sais pas pourquoi, mais cela ne dit rien sur l'initialisation automatique, qui est décrite dans la section 2.6 Initialisation automatique de la documentation complète. Cela est nécessaire si vous envoyez un jeton au serveur dans la méthode

public void onNewToken(String token) {}

Envoi de messages: HUAWEI Push Kit Console.

Avec lui, vous pouvez vérifier le fonctionnement de la poussée. Un fait intéressant: si vous sélectionnez dans la consoleType: Notification Message, ilsonMessageReceived(RemoteMessage message)seront immédiatement affichés sur le téléphone encontournant le gestionnaire.

Lorsque j'ai configuré le push, j'ai souvent dû utiliser la console. Elle et les poussées envoyées par le serveur ont eu des retards allant jusqu'à 30 minutes. J'espère que ce sont des difficultés temporaires que les développeurs ont déjà rencontrées.

Nous avons maintenant deux services push sur notre téléphone, mais comment organiser leur travail commun? Vous devez d'abord déterminer quels services sont disponibles sur le téléphone. Chez nous, nous avons décidé que les services Google seraient une priorité pour nous. Supposons que les services Google et Huawei soient disponibles sur le téléphone, nous travaillons avec Google.

Nous envoyons le drapeau d'état des services au serveur avec des valeurs possibles:

- 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
}

En fonction de la valeur reçue, le serveur enverra des notifications push au service correspondant.

L'organisation de leur travail est une question de technologie. J'ai fait juste ça.

Gestion des événements pour FCM:

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

et HCM:

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

délégué à la classe abstraite:

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> {
}

qui a deux implémentations:

pour FCM:

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

pour HCM:

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

Les classes Huawei ont une interface presque similaire avec les services Google. Ce « presque » Je l' ai personnellement manifesté dans le fait que RemoteMessagesur com.google.firebase.messagingpour que Map<String, String>vous voulez appeler RemoteMessage.getData(), et pour RemoteMessagesortir com.huawei.hms.push- getDataOfMap().

Kit de localisation - détermination de l'emplacement


Les emplacements peuvent être traités LOCATION_SERVICE, ce qui est disponible sans les services Google et Huawei. Mais pour le service de transport de passagers, la détermination précise de l'emplacement est un paramètre important. Heureusement, les interfaces des classes Location Kit n'étaient pas différentes de celles du même nom pour les services Google, de sorte que leur application dans le code ne différait pas. Cependant, les services Huawei étaient moins précis en fonctionnement. J'espère que c'est un problème temporaire.
Nous avons également rencontré le fait que la demande de géolocalisation est envoyée via le HMS Core, ce qui signifie que pour un fonctionnement correct, il est nécessaire de définir les droits de géolocalisation sur «Toujours autoriser».

emplacement

Remplacement de Google Maps


Dans le CIS, nous avons utilisé un moteur OSM avec des tuiles 2GIS. Lors de la première étape de l'intégration, nous avons décidé de ne pas travailler avec le Map Kit de HUAWEI, mais simplement d'utiliser le moteur OSM avec des tuiles OSM. Tout est simple.

Avant la sortie


Je conseille à tous de faire attention aux causes courantes d'échec avant de lancer votre application dans AppGallery.

Par exemple, l'équipe de publication de Huawei nous a informés des violations suivantes.

Présentation atypique de Hong Kong et Macao La

Chine scrupule la souveraineté de ses régions administratives autonomes et demande qu'elles soient appelées "région". Cela nous a obligés à changer toutes les rubriques qui mentionnent le pays pour mentionner le pays ou la région.



Informations sur les produits concurrents tiers dans les détails de l'application

N'oubliez pas de noter l'application en envoyant l'utilisateur à la page de la galerie d'applications, pas au Google Play Store :)

En général, les services Huawei sont similaires aux services Google et les soutenir directement dans le code ne pose pas de difficultés. Les questions ne peuvent concerner que l'écosystème de Huawei dans son ensemble, mais elles peuvent être attribuées à sa jeunesse et, avec une forte probabilité, tout ira mieux avec le temps.

All Articles