Apps für das Betriebssystem Android werden am häufigsten über den Google Play Store vertrieben, den vermutlich jeder Nutzer eines Android-Geräts kennt. Auch wenn der Play Store der mit Abstand am weitesten verbreitete App-Store mit der größten Auswahl an Apps ist, ist er nicht der einzige. Smartphones und Tablets von Samsung enthalten automatisch den Galaxy Store, Amazon betreibt seinen eigenen Appstore, für Liebhaber von Open-Source-Technologien gibt es F-Droid und darüber hinaus gibt es noch weitere App-Stores. Neuerdings werden immer mehr Apps über die Huawei AppGallery vertrieben, mit der wir uns bei Ackee vor Kurzem intensiv befasst haben.

Die AppGallery ist aktuell auf allen Huawei-Geräten mit Android vorinstalliert. Der Haken an der Sache: Während man früher den guten alten Play Store ebenfalls finden konnte (zumindest auf den nicht für den chinesischen Markt bestimmten Versionen), ist dies heute bei neu erschienenen Handys wie dem Mate 30 Pro nicht mehr der Fall. Das amerikanische Handelsministerium hat amerikanischen Firmen die Zusammenarbeit mit einigen chinesischen Firmen untersagt, darunter auch Huawei. Der chinesische Hersteller kann zwar weiterhin neue Produkte mit dem Android-System herausbringen, da der Quellcode mit einer uneingeschränkten Lizenz frei zugänglich ist. Den Zugriff auf alle zentralen Dienste von Google hat er allerdings verloren, einschließlich aller Apps wie dem zuvor erwähnten Play Store.

Für den chinesischen Markt hat sich nichts geändert, da der Betrieb amerikanischer Produkte aus politischen Gründen seit Langem verboten ist und China eigene, interne Klone gängiger Dienste wie Google (Baidu), Facebook (WeChat) oder Amazon (Alibaba) betreibt. Nun ist Huawei allerdings gezwungen, seine Dienste auch außerhalb von China zu vertreiben. Daher versucht das Unternehmen, das Angebot an bekannten Apps in der AppGallery aktiv zu erweitern und wendet sich mit Angeboten für günstige Konditionen an Entwickler, wenn diese ihre Apps zum Huawei-Store hinzufügen. Eine dieser Apps ist Ventusky, ein Design-technisch hochentwickelter Wetterdienst für die ganze Welt, dessen Android-Version wir hier bei Ackee betreuen.

Technische Umsetzung

Vor dem Release einer App in der Huawei AppGallery ist es erforderlich, ihre korrekte Funktionalität auch auf Geräten ohne Google-Dienste sicherzustellen. Bei einfacheren Apps, die keine Google-Dienste nutzen, sind keine besonderen Anpassungen erforderlich. Heutzutage allerdings nutzen die meisten Apps mindestens einen solchen Dienst – am häufigsten zum Beispiel Firebase Analytics, Firebase Crashlytics, Google Location Services oder andere.

Bei der App Ventusky mussten wir einen Ersatz für die beiden folgenden Tools finden:

  • Google Location Services wird verwendet, um den aktuellen Standort des Nutzers zu ermitteln, damit das örtliche Wetter angezeigt werden kann.
  • Google Play Billing Library ermöglicht Käufe in der App, um Premium-Inhalte freizuschalten (Ebene mit anderen Wettervorhersagen).

Unser Ziel war es, den aktuellen Nutzern alle Funktionen unverändert zur Verfügung zu stellen und dabei weiterhin die Google-Dienste zu nutzen, aber auch Support für die aus der AppGallery installierten Apps einzubinden. Hier stellen wir zwei Ansätze vor, wie man die genannte Dienste ersetzen kann.

Ersatz für Google Location Services

Die Unterstützung der Standortbestimmung für Huawei-Geräte war einfach. Huawei bietet das Location Kit an, dessen äußere Schnittstelle eine identische Kopie der Location Services von Google ist. Wir mussten hier lediglich die Klasse LocationProvider  aufteilen in GoogleLocationProvider mit der aktuellen Implementierung durch Google-Dienste und HuaweiLocationProvider;für die Geräte hinzufügen, die die Implementierung von Huawei verwenden. Da die Schnittstelle dieselbe ist, mussten wir nur die Importe ändern und voilà – funktionierende Ortungsdienste auf Huawei-Geräten. Das Ergebnis sieht wie folgt aus:

// LocationProvider.kt

abstract class LocationProvider {
    
    abstract fun getFusedLocation(context: Context): Single<Location>

    // Common functions for both providers
}

// GoogleLocationProvider.kt
import com.google.android.gms.location.LocationServices

class HuaweiLocationProvider : LocationProvider() {

    override fun getFusedLocation(context: Context): Single<Location> {
        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        // ...
    }
}

// HuaweiLocationProvider.kt
import com.huawei.hms.location.LocationServices

class HuaweiLocationProvider : LocationProvider() {

    override fun getFusedLocation(context: Context): Single<Location> {
        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        // ...
    }
}

Im Test auf Huawei-Geräten haben wir festgestellt, dass die Ortung nicht immer funktioniert. Damit alles klappt, muss auf dem Telefon die App HMS Core installiert sein (vergleichbar mit Google Play Services) und die Berechtigung zum Abrufen des Standorts muss erteilt sein. Dies ist in den Werkseinstellungen nicht immer der Fall, zumindest bei den von uns verwendeten Geräten. Wir haben deshalb entschieden, dass auch die Huawei-Version der App versuchen soll, sich mit Google-Diensten zu verbinden und Huawei-Dienste nur verwendet werden, wenn erstere nicht verfügbar sind. Dieses Szenario tritt häufig bei älteren Huawei-Geräten mit Google Play auf, die außerhalb von China verwendet werden. Entsprechend kann die App, auch wenn sie aus der AppGallery installiert wurde, unter diesen Bedingungen Google-Dienste uneingeschränkt nutzen. Diese Anforderung ließ sich einfach umsetzen:

val Context.isGoogleServicesAvailable: Boolean  
    get() = GoogleApiAvailability.getInstance()
                .isGooglePlayServicesAvailable(this) == GoogleConnectionResult.SUCCESS

// Koin DI library
val locationModule = module {    
    single {  
        if (androidContext().isGoogleServicesAvailable) {  
            GoogleLocationProvider(settings = get())  
        } else {  
            HuaweiLocationProvider(settings = get())  
        }  
    }
}

Der verwendete Ansatz mit zweifacher Implementierung hat allerdings einen Nachteil: Jede Änderung muss für beide Klassen vorgenommen werden. In diesem Fall ist es jedoch die einfachste Lösung, denn die Implementierung der fraglichen Klassen ist unkompliziert und es gibt nicht viele Änderungen. Die ideale Lösung wäre, die Logik nur einmal zu implementieren und lediglich die gewünschte Implementierung der Ortungsdienste auszuwählen. Leider war das in diesem Fall nicht möglich, da die Ortungsdienste von Google und Huawei keine gemeinsame interface implementieren, obwohl ihre Schnittstellen faktisch identisch sind.

Ersatz für die Google Play Billing Library

Während wir bei der Nutzung der Ortungsdienste wollten, dass die verwendete Implementierung während des Betriebs ausgewählt wird, können wir im Falle von In-App-Käufen die Implementierung bereits während der Kompilierung auswählen. Hier kann die aus der Huawei AppGallery heruntergeladene App nicht mehr auf In-App-Käufe über Google Play zugreifen. Darüber hinaus hat Huawei Einschränkungen für die App-ID von Apps eingeführt, die In-App-Käufe über die AppGallery ermöglichen: die App-ID muss auf .huawei enden, sonst funktionieren die Käufe in der App nicht.

Der erste Schritt bestand darin, die App in zwei Varianten aufzuteilen – Google und .huawei:

// app/build.gradle

flavorDimensions "market"  

productFlavors {  
    google {  
        dimension "market"  
        applicationId appProperties['google_package_name']  
    }  

    huawei {  
        dimension "market"  
        applicationId appProperties['huawei_package_name']  
    }  
}

Die Implementierung unterscheidet sich ein wenig von den Ortungsdiensten – wir erstellen auch hier eine abstrakte Basisklasse, spezifische Implementierungen werden jedoch in den spezifischen Varianten eingesetzt.

// app/src/main/java/ventusky/billing
abstract class BaseBillingManager(  
    // ...
) {  

    abstract fun getPremiumPrice(listener: PremiumPriceRetrievedListener)  
    abstract fun buyPremium(activity: Activity)

    protected fun savePremiumStatus(premiumStatus: Boolean) {  
        // ...  
    }
}

// app/src/google/ventusky/billing
class BillingManager(  
    // Google In-App dependencies
) : BaseBillingManager(/* ... */) {

    override fun getPremiumPrice(listener: PremiumPriceRetrievedListener) {
        // Google Billing implementation  
    }
    
    override fun buyPremium(activity: Activity) {
        // Google Billing implementation 
    }
}

// app/src/huawei/ventusky/billing
class BillingManager(  
    // Huawei In-App dependencies
) : BaseBillingManager(/* ... */) {

    override fun getPremiumPrice(listener: PremiumPriceRetrievedListener) {
        // Huawei Billing implementation  
    }

    override fun buyPremium(activity: Activity) {
        // Huawei Billing implementation
    }
}

Während der Ausführung der App können wir daher nicht entscheiden, ob wir die Google- oder Huawei-Implementierung verwenden möchten, da die resultierende APK nur eine bestimmte Klasse BillingManager enthält, deren Implementierung von der gewählten Variante abhängt. Dies ist jedoch ein Vorteil: Wir müssen die Verfügbarkeit der spezifischen Dienste innerhalb des Codes nicht testen und erst später entscheiden, welchen wir verwenden. Wir haben bereits die passende Implementierung zur Verfügung, und überdies enthält die kompilierte App keine zweite, unnötige Implementierung. Dadurch reduziert sich die Größe des Installationspakets.

Die Huawei-Bibliothek für In-App-Käufe ist auch keine Kopie der Google-Schnittstelle, sodass beide Versionen unabhängig voneinander aktualisiert werden können. Für Interessierte am spezifischen Aussehen der Implementierung gibt es eine Dokumentation zur Google Play Billing Library sowie zu Huawei In-App-Käufen.

Fazit

Lohnt es sich, Apps in der Huawei AppGallery zu veröffentlichen? Für Apps, die auf die ganze Welt abzielen und wirklich viele Benutzer haben, definitiv ja. Sie erreichen damit eine bedeutende Anzahl weiterer Nutzer, deren Zahl wahrscheinlich noch weiter wachsen wird. Bei kleineren Apps empfehlen wir, die potenziellen Vorteile gegen den Aufwand für die Migration von Diensten und die Pflege mehrerer Versionen der App abzuwägen. Speziell für ortsbezogene Apps, die nur innerhalb eines Landes laufen, wird der Nutzen vermutlich gering sein (es sei denn, das Land ist China. :)

Wer sich ein neues Android-Smartphone zulegen möchte, sollte aus unserer Sicht von Geräten ohne Google Play Abstand nehmen. Auch wenn das Angebot an alternativen App Stores einschließlich AppGallery immer größer wird, ist es im Vergleich zum Play Store immer noch sehr begrenzt und es fehlen viele Apps, was die Nutzung des Smartphones erheblich einschränkt.

Beratungsbedarf? Lassen Sie uns über Ihr Projekt sprechen.

Kontakt aufnehmen >