【问题标题】:Dynamically link packages based on product flavor to support GMS & HMS with one code base根据产品风格动态链接包,以一个代码库支持 GMS 和 HMS
【发布时间】:2022-01-23 00:14:29
【问题描述】:

为了让我的应用程序在 Google PlayStore 和华为应用程序库上都获得批准和可见,我目前维护了两个不同的分支:

  • 安装了 react-native-maps 但没有 HMS 包的 Google 分支。

  • 已安装 HMS 地图但未安装 react-native-maps 的华为分支。

我知道 HMS+GMS 方法,但根据我的经验,像 react-native-maps 这样严重依赖 GMS 的模块使我的应用对纯 HMS 设备隐藏,即使我的应用有方法检查和永远不要导航到依赖 GMS 的屏幕。

两个分支在 JavaScript 端的代码相同,除了一个用于显示地图的文件,该文件在 GMS 手机上从 react-native-maps 导入,在华为手机上从 react-native-hms-map 导入。

我的问题是:有没有一种方法可以根据产品风格在构建时动态排除某些文件和包,以便我可以使用一个代码库而在构建 APK 时忽略某些文件。

解决方案: 设法提出了一个解决方案,通过禁用反应原生地图的自动链接并根据产品风格手动链接它,使我的应用程序获得批准并在应用程序商店中完全可见。 (代码可能不是最干净的,但它的行为符合预期,因此我们将不胜感激任何清理建议)

步骤:

1.在 android 上禁用 react-native-maps 的手动链接

通过在项目根目录下创建一个名为react-native.config.js的文件,并添加如下内容

module.exports = {
  dependencies: {
    "react-native-maps": {
      platforms: {
        android: null,
      }
    }
  }
}

2。为 Google 和华为添加了产品风格

通过将以下内容添加到 android/app/build.gradle

...
...
android{
    ...
    ...
    flavorDimensions "provider"
    productFlavors {
        google {
            
            dimension "provider"
            
        }
        huawei {
            
            dimension "provider"
            
        }
    }
    ...
    ...
}
...
...

3。在同一个 android/app/build.gradle 文件中添加了以下内容

...
...
dependencies {
    ...
    ...
    huaweiImplementation 'com.huawei.hms:location:4.0.2.300'
    huaweiImplementation 'com.huawei.hms:hwid:4.0.1.300'

    googleImplementation project(':react-native-maps')
    ...
    ...
}
...
...

4.将以下内容添加到 android/settings.gradle

include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android')

5.在 android/app/src 中创建了 2 个文件夹

文件夹名为:huawei 和 google,结构如下

6.在 android/app/src/google/java/com/appname 中添加了一个 java 文件

MapPackageChecker.java

package com.appname;
import com.facebook.react.ReactPackage;
import com.airbnb.android.react.maps.MapsPackage;

public class MapPackageChecker {

  public static ReactPackage getMapPackage() {
     return new MapsPackage();
  }

}

7.在android/app/src/huawei/java/com/appname里面添加了一个java文件

MapPackageChecker.java

package com.appname;
import com.facebook.react.ReactPackage;

public class MapPackageChecker {

  public static ReactPackage getMapPackage() {
     return null;
  }

}

8.将以下内容添加到 android/app/src/main/java/com/appname/MainApplication.java

import static com.appname.MapPackageChecker.getMapPackage;
...
...
        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          
          //start of new lines
          if(BuildConfig.FLAVOR.equals("google")){
            packages.add(getMapPackage());
          }
          //end of new lines

          return packages;
        }
...
...

9.从反应原生代码访问风味名称

我决定为此使用 react-native-build-config

导航组件示例:

import googleMapScreen from "./googleMapScreen.js"; //relies on gms maps
import huaweiMapScreen from "./huaweiMapScreen.js"; //relies on hms maps

import BuildConfig from 'react-native-build-config';
const flavor = BuildConfig.FLAVOR
...
...
    <Stack.Screen
        name="MapScreen"
        component={flavor === "huawei" ? huaweiMapScreen : googleMapScreen}
    />
...
...

10.添加产品风味后,我们需要对命令进行一些更改

yarn react-native run-android

变成: yarn react-native run-android --variant=huaweiDebug

或: yarn react-native run-android --variant=googleDebug

./gradlew assembleRelease

变成: ./gradlew assembleHuaweiRelease

或: ./gradlew assembleGoogleRelease

11.为方便起见,我们可以将以下内容添加到 package.json 脚本中

"scripts":{
   "run-huawei": "yarn react-native run-android --variant=huaweiDebug",
   "run-google": "yarn react-native run-android --variant=googleDebug",
}

【问题讨论】:

    标签: react-native huawei-mobile-services react-native-maps


    【解决方案1】:

    首先,华为确实支持 react-native-maps。请在此处查看:https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides-V1/integrating-sdk-0000001050034173-V1

    当HMS+GMS为首选方案时,APP需要在代码中根据设备上HMS和GMS服务的可用性来决定是使用HMS还是GMS。

    。如何决定是使用 HMS 还是 GMS :

    • 检查 GMS 是否可用

    也有一些链接供大家参考:

    React Native Application Detect 设备支持 GMS 或 HMS:https://forums.developer.huawei.com/forumPortal/en/topic/0201200045194610058?fid=0101187876626530001

    Choice SDK - 一个开源 GMS-HMS 包装器:https://forums.developer.huawei.com/forumPortal/en/topic/0201555879126330259?fid=0101187876626530001

    【讨论】:

    • 感谢您的回答,我不知道 Choice SDK,所以我会尝试一下。至于你提到的 react-native-maps 和 react-native-hms-map ,它们是两个不同的包。需要明确的是,所需的方法不是 GMS+HMS,因为当使用这种方法时,只有 HMS 设备无法在应用程序库中看到我的应用程序,而华为支持提到的原因是 react-native-maps 包。相反,我希望拥有单独的 GMS 和 HMS 构建,而无需在每次构建之前删除 react-native-maps 并添加 react-native-hms-map。
    • @RodSar 我的意思是使用 react-native-hms-map 如果你的应用程序设计没问题,它适用于所有类型的华为手机。
    • 是的,我将它用于我们的华为分支,而普通的 react-native-maps 用于谷歌分支,我只是在寻找一种同时安装两个软件包的方法仍然可以全面了解华为 App Gallery,而不必维护 2 个不同的分支
    【解决方案2】:

    您可以参考this

    在这里配置:

    并运行以下命令:

    【讨论】:

    • App ID: 103005683 当前版本的应用没有 react-native-maps 或任何 GMS 和 HMS 可用性检查,只安装了 HMS 包,这种方法可以在所有华为手机上显示但很难维护。以前的版本安装了 react-native-maps,但会根据可用的服务动态导航到我们地图屏幕的 GMS 或 HMS 版本,这种方法使它可以在某些华为手机上显示,但不会在最新的手机上显示。跨度>
    • 与审核组核实后发现,在测试过程中,您的上一版本应用中的地图在HMS设备上不可用,因此您的应用在HMS手机上不可见。我们怀疑 H 和 G 的逻辑有问题,您能介意发布您如何进行 HMS 和 GMS 可用性检查的代码吗?建议使用this判断G或H的逻辑。
    • 为了让事情更清楚,我将重新上传一个同时具有 react-native-maps 和 react-native-hms-map 的版本并进行可用性检查以确定导航位置,只要所有华为手机可以在不遇到GMS地图屏幕的情况下到达HMS地图屏幕,那么即使我安装了两个包也可以通过测试,对吗?谢谢你的帮助,真的很感激
    • 是的,您可以重新提交申请,以防万一您也可以将您的 APK 发送至 hmscore@huawei.com 以供我们查看。
    • 感谢您的帮助,我再次提交并获得了应用程序的批准和可见性,我已在原始帖子中添加了我的解决方案。
    猜你喜欢
    • 2021-04-05
    • 2021-10-25
    • 1970-01-01
    • 2022-10-23
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2014-11-10
    相关资源
    最近更新 更多