Wie wir der inDriver Android-Anwendung Harmony OS-Unterstützung hinzugefügt haben

Alles begann damit, dass das US-Handelsministerium Huawei in die Liste der Unternehmen aufgenommen hat, mit denen es verboten ist, Geschäfte mit amerikanischen Unternehmen zu tätigen . Die Antwort von Huawei war das Betriebssystem Harmony OS für seine Smartphones und die Weigerung, Google-Dienste darin zu verwenden. Und um nicht einen Teil des Marktes zu verlieren, haben wir seine Unterstützung in inDriver integriert. Die "OS-Integration" klingt zwar laut - unsere Anwendung läuft wie jede andere für Android geschriebene auf Harmony, aber für die volle Arbeit ist es notwendig, Google-Dienste durch ähnliche Huawei-Dienste zu ersetzen.



In inDriver verwenden wir Google-Dienste für drei Zwecke:

  • Senden von Push-Benachrichtigungen;
  • Definition des Ortes;
  • Google Maps.

Push Kit - Push-Benachrichtigungen senden


Für den Anfang hat Huawei einige ziemlich gute Dokumentationen . Verwenden Sie für einen schnellen Start einfach das Schritt-für-Schritt-Tutorial .

Ich werde nicht nacherzählen, was dort geschrieben steht, ich werde nur auf einige Punkte eingehen, da hier Kommentare benötigt werden.

Aktivieren des Dienstes

Sie werden aufgefordert, den Datenspeicherort einzurichten. Beachten Sie, dass Sie es später nicht mehr ändern können . Der Speicherort wirkt sich nicht auf den direkten Betrieb des Push aus, sondern ist nur ein Speicherort und die Verarbeitung von Daten über diesen Push.

Integration des HMS SDK

Nach Abschluss der Integration haben Sie wahrscheinlich Probleme beim Erstellen des Projekts. Auf jeden Fall war dies auf unserem Ubuntu 16.04.5 LTS-Build-Server (GNU / Linux 4.4.0-174-generic x86_64) der Fall, während lokal auf dem funktionierenden Mac mini (Ende 2018, Mojave) alles einwandfrei funktionierte. Sie können dies beheben, wenn Sie hinzufügen

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



agcp {
   manifest false
}

am Ende der Datei build.gradleauf Anwendungsebene, um das Manifest für zu deaktivieren agcp. Das Problem hierbei ist vielmehr, dass agcpnach einer Manifestdatei gesucht wird, diese jedoch nicht gefunden und geladen werden kann, was höchstwahrscheinlich ein Problem darstellt agconnect. Zumindest hat uns der offizielle technische Support von Huawei so geantwortet.

Konfigurieren von AndroidManifest.xml

Ich weiß nicht warum, aber es geht nicht um die automatische Initialisierung, die in Abschnitt 2.6 Automatische Initialisierung der vollständigen Dokumentation beschrieben wird. Dies ist erforderlich, wenn Sie in der Methode ein Token an den Server senden

public void onNewToken(String token) {}

Senden von Nachrichten: HUAWEI Push Kit Console.

Damit können Sie die Funktion des Pushs überprüfen. Eine interessante Tatsache: Wenn Sie in der Konsole auswählenType: Notification Message, werden sieonMessageReceived(RemoteMessage message)sofort unterUmgehung des Handlersauf dem Telefon angezeigt.

Wenn ich den Push einrichtete, musste ich oft die Konsole benutzen. Sowohl sie als auch die vom Server gesendeten Pushs hatten Verzögerungen von bis zu 30 Minuten. Ich hoffe, dies waren vorübergehende Schwierigkeiten, mit denen sich die Entwickler bereits befasst haben.

Jetzt haben wir zwei Push-Dienste auf unserem Telefon, aber wie können wir ihre gemeinsame Arbeit organisieren? Zuerst müssen Sie feststellen, welche Dienste auf dem Telefon verfügbar sind. Bei uns haben wir beschlossen, dass Google-Dienste für uns Priorität haben. Angenommen, wenn sowohl Google- als auch Huawei-Dienste auf dem Telefon verfügbar sind, arbeiten wir mit Google zusammen.

Wir senden das Statusflag der Dienste mit möglichen Werten an den Server:

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

Abhängig vom empfangenen Wert sendet der Server Push-Benachrichtigungen an den entsprechenden Dienst.

Die Organisation ihrer Arbeit ist eine Frage der Technologie. Ich habe genau das getan.

Ereignisbehandlung für FCM:

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

und HCM:

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

an die abstrakte Klasse delegiert:

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

welches zwei Implementierungen hat:

für FCM:

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

für HCM:

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

Huawei-Klassen haben eine fast ähnliche Oberfläche mit Google-Diensten. Dieses "fast" habe ich persönlich in der Tatsache manifestiert, dass RemoteMessageout com.google.firebase.messagingfür Map<String, String>Sie anrufen möchte RemoteMessage.getData(), und für RemoteMessageout com.huawei.hms.push- getDataOfMap().

Location Kit - Standortbestimmung


Standorte können bearbeitet werden LOCATION_SERVICE, die ohne Google- und Huawei-Dienste verfügbar sind. Für den Personenverkehr ist jedoch eine genaue Standortbestimmung ein wichtiger Parameter. Glücklicherweise unterschieden sich die Schnittstellen der Location Kit-Klassen nicht von denen mit demselben Namen für Google-Dienste, sodass sich ihre Anwendung im Code nicht unterschied. Huawei-Dienste waren jedoch im Betrieb weniger genau. Hoffe, dies ist ein vorübergehendes Problem.
Wir haben auch festgestellt, dass die Geolokalisierungsanforderung über den HMS Core gesendet wird. Für einen korrekten Betrieb müssen die Rechte für die Geolokalisierung auf "Immer zulassen" festgelegt werden.

Standort

Google Maps ersetzen


In der GUS verwendeten wir eine OSM-Engine mit 2GIS-Kacheln. In der ersten Phase der Integration haben wir uns entschieden, nicht mit dem Map Kit von HUAWEI zu arbeiten, sondern einfach die OSM-Engine mit OSM-Kacheln zu verwenden. Alles ist einfach.

Vor der Veröffentlichung


Ich rate jedem, die häufigsten Fehlerursachen zu beachten, bevor Sie Ihre Anwendung in AppGallery starten.

Das Huawei-Release-Team hat uns beispielsweise über die folgenden Verstöße informiert.

Die nicht standardmäßige Darstellung von Hongkong und Macau

China ist hinsichtlich der Souveränität seiner autonomen Verwaltungsregionen gewissenhaft und fordert sie auf, als "Region" bezeichnet zu werden. Dies zwang uns, alle Überschriften, in denen das Land erwähnt wird, zu ändern, um das Land oder die Region zu erwähnen.



Informationen zu konkurrierenden Produkten von Drittanbietern in App-Details

Vergessen Sie nicht, die Anwendung zu bewerten, indem Sie den Benutzer an die Seite in der App-Galerie senden, nicht an den Google Play Store :)

Im Allgemeinen ähneln die Huawei-Dienste den Google-Diensten, und die direkte Unterstützung im Code verursacht keine Schwierigkeiten. Fragen können nur das gesamte „Ökosystem“ von Huawei betreffen, sie können jedoch seiner Jugend zugeschrieben werden, und mit hoher Wahrscheinlichkeit wird mit der Zeit alles besser.

All Articles