And*_*dan 52 android google-play-services huawei-mobile-services
如何在应用程序中同时拥有 Google 移动服务和华为移动服务?
由于华为已经失去了GMS的许可,看来我们需要用华为提供的服务替换应用程序中使用的所有GMS服务。什么是“最佳实践”?使用口味并以某种方式单独处理每个类,还是复制粘贴项目并开始替换?或者……更好的是,有没有办法同时拥有和……以某种方式让应用程序根据它所在的设备决定使用哪种服务?显然,最后一个假设APK文件大小增加。
有任何想法吗?
And*_*dan 45
所以,我设法这样做:
定义了两种口味
gms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"g"'
}
hms {
dimension "services"
buildConfigField "String", "SERVICE_USED", '"h"'
}
Run Code Online (Sandbox Code Playgroud)
每当我需要决定执行以下操作时,我都会在代码中使用“g”和“h”:API 需要deviceType“android”或“iOS”,并且包含华为构建,我们定义了另一个常量“huawei” . 我SERVICE_USED过去知道要发送什么常量。
然后我在 build.gradle 的顶部做了这个:
apply plugin: 'com.android.application'
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Hms")) {
//*meh*
} else {
apply plugin: 'io.fabric'
}
Run Code Online (Sandbox Code Playgroud)
因为我使用的是fabric(和fabric / firebase ...并不真正与HMS一起使用)而且我也在build.gradle的最底部做了这个
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Hms")) {
apply plugin: 'com.huawei.agconnect'
} else {
apply plugin: 'com.google.gms.google-services'
}
Run Code Online (Sandbox Code Playgroud)
只包含正确的插件。
然后我开始gms通过制作包装器并分离每种风格的代码来处理正在使用的每件事(地图、位置、推送通知、分析)。即对于推送通知,我创建了一个HPushNotif有getToken方法的。我在两种风格中定义了相同的类和方法,但我根据服务类型(gms 或 hms)实现它们。
在项目中包含依赖项时,我使用了这种类型的表示法:
//GMS stuff
gmsImplementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
gmsImplementation 'com.google.firebase:firebase-core:16.0.9'
gmsImplementation 'com.google.firebase:firebase-messaging:18.0.0'
gmsImplementation 'com.google.firebase:firebase-crash:16.2.1'
gmsImplementation 'com.google.android.gms:play-services-maps:16.1.0'
gmsImplementation 'com.google.android.gms:play-services-location:16.0.0'
gmsImplementation 'com.google.android.gms:play-services-tagmanager:16.0.8'
//HMS stuff
hmsImplementation 'com.huawei.agconnect:agconnect-core:1.0.0.300'
hmsImplementation 'com.huawei.hms:push:4.0.3.301'
hmsImplementation 'com.huawei.hms:maps:4.0.1.301'
hmsImplementation 'com.huawei.hms:location:4.0.3.303'
Run Code Online (Sandbox Code Playgroud)
在gms和hms前Implementation指味道的名字。只有在选择了适当的 BuildVariant(即正在构建适当的风格)时才会加载这些依赖项。
基本上,我为这两种情况包装了地图、分析、位置和推送通知的逻辑。这就是结构的外观。没什么特别的。
就是这样。当他们创建 HMS 时,他们基本上是按类复制 GMS,按方法复制。您将看到确切的方法名称与调用参数 even 和返回值完全匹配。它们 99.99% 相同。这让事情变得更容易。基本上你只需要复制两个类中的代码并导入正确的东西(在类的顶部)。您很少需要更改已为 GMS 编写的代码。
希望它可以帮助某人。
dea*_*ish 32
在我回答您的问题之前,先简要解释一下什么是 HMS 和 GMS:
您可以在华为的应用程序商店(名为 AppGallery)中发布您的应用程序(使用 Google 的库),但此应用程序将可见并可下载,仅适用于包含 HMS+GMS 的华为设备(2020 年之前的所有设备都具有 HMS 和 GMS)。
然而,较新的手机,即 Mate 30 系列,P40 - 将只安装 HMS。因此,如果您想让您的应用对所有华为设备(HMS+GMS 和 HMS)可见,那么您必须在您的应用中实现检测用户设备上正在运行的服务的功能。它将决定调用什么适当的函数(即初始化华为地图或谷歌地图的实例)。
对于华为移动服务,我们使用:
HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context);
Run Code Online (Sandbox Code Playgroud)
https://developer.huawei.com/consumer/en/doc/development/HMS-References/huaweiapiavailability
对于 Google 移动服务,我们使用:
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
Run Code Online (Sandbox Code Playgroud)
https://developers.google.com/android/reference/com/google/android/gms/common/GoogleApiAvailability
public static boolean isHmsAvailable(Context context) {
boolean isAvailable = false;
if (null != context) {
int result = HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context);
isAvailable = (com.huawei.hms.api.ConnectionResult.SUCCESS == result);
}
Log.i(TAG, "isHmsAvailable: " + isAvailable);
return isAvailable;
}
public static boolean isGmsAvailable(Context context) {
boolean isAvailable = false;
if (null != context) {
int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
isAvailable = (com.google.android.gms.common.ConnectionResult.SUCCESS == result);
}
Log.i(TAG, "isGmsAvailable: " + isAvailable);
return isAvailable;
}
Run Code Online (Sandbox Code Playgroud)
AFAIK 这些类(HuaweiApiAvailability/GoogleApiAvailability)在您实现任何华为工具包/Google 的库时可用。
cap*_*ink 10
虽然这实际上取决于您的应用程序的架构,但目前有 2 个合理的替代方案;
综合之前给出的所有好的答案:https://github.com/abusuioc/from-gms-to-hms#step-5-integrate-hms-sdks-in-your-app
对于大多数应用程序来说,推荐的方式是依赖 GMS 和 HMS SDK 的单一构建+在运行时(基于设备上的可用性)决定使用哪一个。
必须设置googleand huaweiasproductFlavors以及随后的 as sourceSets。
根项目build.gradle:
buildscript {
repositories {
google()
mavenCentral()
maven { url "https://developer.huawei.com/repo/" }
}
dependencies {
classpath "com.android.tools.build:gradle:7.2.2"
classpath "com.google.gms:google-services:4.3.13"
classpath "com.huawei.agconnect:agcp:1.7.0.300"
}
}
Run Code Online (Sandbox Code Playgroud)
模块build.gradle:
plugins {
id "com.android.application"
id "androidx.navigation.safeargs"
}
def json_huawei_release = "src/huaweiRelease/agconnect-services.json"
def json_huawei_debug = "src/huaweiDebug/agconnect-services.json"
def json_google = "src/google/google-services.json"
if (getGradle().getStartParameter().getTaskRequests().toString().contains('Huawei')) {
if (project.file(json_huawei_debug).exists() || project.file(json_huawei_release).exists()) {
apply plugin: "com.huawei.agconnect"
}
}
if (getGradle().getStartParameter().getTaskRequests().toString().contains('Google')) {
if (project.file(json_google).exists()) {
println "found: ${project.file(json_google)}"
apply plugin: "com.google.gms.google-services"
apply plugin: "com.google.firebase.crashlytics"
} else {
println "missing: ${project.file(json_google)}"
}
}
android {
...
flavorDimensions "vendor"
productFlavors {
google {
dimension "vendor"
versionNameSuffix "-google"
}
huawei {
dimension "vendor"
versionNameSuffix "-huawei"
}
}
sourceSets {
google {
java.srcDirs = ['src/main/java', 'src/google/java']
}
huawei {
java.srcDirs = ['src/main/java', 'src/huawei/java']
}
}
}
dependencies {
/** Google Play Services */
googleImplementation "com.google.android.gms:play-services-base:18.0.1"
googleImplementation "com.google.android.gms:play-services-basement:18.0.0"
googleImplementation "com.google.android.gms:play-services-auth:20.0.0"
googleImplementation "com.google.android.gms:play-services-identity:18.0.0"
googleImplementation "com.google.android.gms:play-services-oss-licenses:17.0.0"
/** Google Firebase */
googleImplementation "com.google.firebase:firebase-auth:21.0.1"
googleImplementation "com.google.firebase:firebase-database:20.0.3"
googleImplementation "com.google.firebase:firebase-messaging:23.0.0"
googleImplementation "com.google.firebase:firebase-functions:20.0.1"
googleImplementation "com.google.firebase:firebase-crashlytics:18.2.6"
googleImplementation "com.google.firebase:firebase-analytics:20.0.2"
googleImplementation "com.google.firebase:firebase-perf:20.0.4"
// googleImplementation "com.firebaseui:firebase-ui-auth:8.0.0"
/** Huawei Mobile Services */
huaweiImplementation "com.huawei.hms:base:6.1.0.302"
huaweiImplementation "com.huawei.hms:push:6.1.0.300"
huaweiImplementation "com.huawei.hms:hianalytics:6.3.0.300"
/** Huawei AppGallery Connect */
huaweiImplementation "com.huawei.agconnect:agconnect-core:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-auth:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-remoteconfig:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-function:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-cloud-database:1.5.2.300"
huaweiImplementation "com.huawei.agconnect:agconnect-applinking:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-crash:1.6.5.300"
huaweiImplementation "com.huawei.agconnect:agconnect-apms:1.5.2.309"
huaweiImplementation "com.huawei.agconnect:agconnect-storage:1.5.0.100"
huaweiImplementation "com.huawei.agconnect:agconnect-appmessaging:1.6.5.300"
}
Run Code Online (Sandbox Code Playgroud)
这允许为所有内容提供自定义实现;它将构建两个不同的工件。
测试时必须考虑切换构建变体和测试设备 - 但可以在 IDE 运行配置中传递任务名称和设备序列号(以便在正确的测试设备上运行正确的构建变体)。
无论@ AndreiBogdan和@ deadfish的答案是正确的。我想补充一点:
首先,您需要根据应用场景和开发/测试成本选择合适的解决方案(G+H 或 G2H)。
如果选择G2H方案,兼容性测试的工作量很小。您只需要在华为手机上测试新的 APK。在华为应用市场和 Google Play 上发布您的应用,并使用不同的软件包。您在 AppGallery 上发布的应用仅包含华为的逻辑代码。您可以参考@AndreiBogdan的回答,或查看文档 Supporting Multiple Channels。
正如@captaink所说,您可以使用HMS Toolkit Convertor。它支持 G+H 和 G2H 转换。目前,HMS Toolkit 支持 Java 和 Kotlin。支持的 Android Studio 版本:3.3.2?4.1。
| 归档时间: |
|
| 查看次数: |
12554 次 |
| 最近记录: |