8

I have an app with the usual Google ad and in-app-payment stuff. It's accepted into the Play Store all right. Now I'd like to make it support both GMS and HMS at the same time (based on the availability of the appropriate services, the app can decide which platform to use). The app, with the Huawei functionality built in, works just fine while testing on my own devices.

However, as soon as Huawei's libraries are bundled with the app, the Play Store Console simply refuses it. No error message, just a red exclamation point. There's no doubt about the situation, I started to remove the Huawei-related parts one by one and as soon as the last bit was removed, the bundle was automagically accepted again.

Yes, sure, I might have made some error I'm not aware of but the situation is, well, rather suspicious. If it makes any difference, I use Flutter and I try to upload an app bundle, not APKs, as per normal these days. The HMS library that seems to make it or break it is com.huawei.hms:hwid:4.0.0.300 from the maven repo at https://developer.huawei.com/repo/.

So, am I just seeing things or not?

Update:

OK, the quest goes on.

This is quite recent news: https://support.google.com/googleplay/android-developer/answer/9934569

Any existing app that is currently using an alternative billing system will need to remove it to comply with this update. For those apps, we are offering an extended grace period until September 30, 2021 to make any required changes. New apps submitted after January 20, 2021 will need to be in compliance.

No matter what the policy says, the Play Console seems to enforce it already. And as I found by looking into the app bundle, the flavor approach is just not enough. Even with the other flavor, there will remain some packages referenced by Flutter. Maybe just the referenced names, not the actual code after tree shaking, but this is already enough for the refusal.

So, at the end of the day, I really think this question needs to be sorted out and some clear guidelines found for and by ourselves, developers, if we really want to write cross-ecosystem, single source Flutter apps. As for me, I sure want to do it.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Gábor
  • 9,466
  • 3
  • 65
  • 79
  • There are numerous applications on Google Play Store which include both Huawei Mobile and Google Mobile Services together. In certain circumstances Play Store Console might reject Huawei IAP SDK, it is advised to make the project support different app packages for different channels, to adapt to different app store requirements. – zhangxaochen Oct 15 '20 at 02:20
  • That's the problem, please, read it more carefully. :-) While this was true earlier, with the upcoming changes in the Play Store, Google now started to refuse two-flavor packages that DON'T use HMS code but still has some meta references to them. When I create two flavors, one appgallery and one googleplay, Google will refuse the googleplay one. I don't speak about the appgallery flavor, that's obvious. – Gábor Oct 15 '20 at 10:46
  • 1
    Yes, if HMS IAP code is included, it will be rejected by GP. – zhangxaochen Oct 15 '20 at 12:56

2 Answers2

3

I have finally found a kind of a workaround, not automatic, but a useable approach.

Create two subpackages inside your project. They look like normal Flutter packages but reside inside your app. Basically, create two folders, gms_support and hms_support beside your usual lib. Both are packages with the usual structure:

  • lib
  • lib\Xms_support.dart
  • lib\src
  • lib\pubspec.yaml

Put all your vendor-dependent stuff into identically structured files inside the respective lib\src folders and make sure both XXX_support.dart files export them the usual way. The implementations should use the same classes and same signatures. Each pubspec.yaml refers to its own, vendor-specific Flutter plugins required for their implementation.

Your main app pubspec.yaml contains both references:

dependencies:
  ...
  gms_support:
    path: gms_support/
  hms_support:
    path: hms_support/

Also, add another support.dart inside your main app:

export 'package:gms_support/gms_support.dart';
export 'package:hms_support/hms_support.dart';

Wherever you need vendor-specific behavior in your app, you import and use this support.dart file.

Then, when you have to change from one flavor to another, you always have to change three things in sync:

  • the flavor (see the details of your IDE)
  • comment out the other export in support.dart
  • comment out the other reference in pubspec.yaml and make a pub update
Gábor
  • 9,466
  • 3
  • 65
  • 79
1

Different App store has different requirements for In-App Purchase Kit. The possible cause for the Play Store Console refusing your app is that your app integrated with other IAP Kit, and it does not meet the requirements of the app store review guide. You are advised to make your project support different app packages for different channels, to adapt different app store requirements.

Supporting Multiple Flavors

If your app needs to support multiple build types or flavors, configure the agconnect-services.json configuration file downloaded from AppGallery Connect for your app to implement the function. The agconnect-services.json file provides configuration information required by various services in your AppGalleryConnect project. Therefore, if you need to use multiple flavors to release different app versions, copy the agconnect-services.json file to the folder of each flavor and configure it.

Supporting Multiple Channels

If your project needs to support different app packages for different channels, the package name needs to vary depending on the channel. Change the package name in productFlavor in the build.gradle file under the app directory.

productFlavors { 
    huawei{ 
        // Unique package name. 
        applicationId "com.example.demo.huawei" 
        resValue "string", "app_name", "Huawei" 
    } 
    amazon{ 
        applicationId "com.example.demo.amazon" 
        resValue "string", "app_name", "Amazon" 
    } 
}

The preceding sample code shows different packaging configurations for different channels, Huawei and Amazon. The package names are different for the two channels. If the same agconnect-services.json file is used for the two channels, the package name verification fails. To support multiple channels, you need to add the agconnect-services.json file to the flavor folder of only the Huawei channel and ensure that the AppGallery Connect plug-in version in the project is 1.2.1.301 or later classpath'com.huawei.agconnect:agcp:1.2.1.301'). If the plug-in version is earlier than 1.2.1.301, upgrade it to 1.2.1.301 or later.

For more information, see docs.

zhangxaochen
  • 32,744
  • 15
  • 77
  • 108
  • Yes, I'm very much aware of the flavor approach. I tried to avoid it if it's possible because having a single app for both scenarios is more comfortable. I could very much understand if I used two services with conflicting `agconnect`, that would certainly cause problems (athough not during bundle uploading but in use), however, right now I only need one AG-supported scenario. The problem is that if I leave out *everything* related to IAP and ads, and only leave the *single line* in my app calling `isHuaweiMobileServicesAvailable()`, I get rejected. – Gábor Sep 28 '20 at 07:42
  • I suspect you might be connected to Huawei in some way. Could you check out my update? This approach might have worked in the past but it doesn't seem like it still does. – Gábor Sep 30 '20 at 11:59
  • What it boils down to is probably this: I can handle with flavors what I include myself in my app. But I can't handle what the plugins I reference (eg. `huawei_iap`) decide to include *on their own*. – Gábor Sep 30 '20 at 13:02
  • "isHuaweiMobileServicesAvailable()" is not a method that exposed or included in HMS Flutter Plugins. You may have used third-party plugins or used the one which is exposed in the base HMS SDK. “The application is still getting rejected” Any minimal reproducible project may help to analyze the issue. Please kindly refer to [Cloud Debugging](https://stackoverflow.com/a/63877454/13329100). – zhangxaochen Oct 15 '20 at 02:20
  • It's Huawei's own `huawei_iap` Flutter plugin. I have since opened an issue in the appropriate queue on GitHub, it's already assigned to one of your colleagues but there is no workaround yet. – Gábor Oct 15 '20 at 09:16
  • I can see where the misunderstanding comes from. What you copy-paste is the standard doc of how we should do it. However, my error report is about the fact that while this standard doc was just fine earlier, *there is a **new problem** now that makes it not work any more.* – Gábor Oct 15 '20 at 10:55
  • @Gábor The purpose of supporting multiple channels is to remove hms code when you upload your app to Google. That is, if app is released on GP, only Google dependency is added. If app is released on AP, only Huawei dependency is added. Maybe this answer about [Google dependency](https://stackoverflow.com/a/18213259/13329100) is helpful for you! – zhangxaochen Oct 15 '20 at 12:53
  • That's the problem I keep speaking about. :-) Yes, this is how it's supposed to be, I know. The reason for the bug report is that it doesn't work that way. There remain (probably) some metadata references that nobody cared about earlier but now, with some recent changes at Google's end, started to cause trouble. This is why I opened an issue. I know what the doc says, the problem is that doing as the doc says is no longer sufficient. – Gábor Oct 15 '20 at 12:57
  • @Gábor Yes, this flavor approach has not been supported in Flutter yet. You're advised to maintain two sets of code. One for google, one for hms. We will provide feedback if possible solutions are found. – zhangxaochen Oct 16 '20 at 11:09
  • There is a possible solution I settled on, I'll post it here as an aswer. You could mention it in your documentation. :-) – Gábor Nov 22 '20 at 13:15