I have an existing Google Play Android app that uses the Google Billing Library and I'd like to use the recently released Amazon Appstore Billing Compatibility SDK that implements a compatible API.
Their guide suggests replacing Java/Kotlin lines as follows, and on first take it works well. Just replace:
import com.android.billingclient.api.*
with
import com.amazon.device.iap.billingclient.api.*
I already use the Gradle flavor mechanism to slightly tweak the build (e.g. different store & support URLs), so in an ideal world, I could leverage that. I.e. I have this in my app/build.gradle file:
flavorDimensions = ["appstore"]
productFlavors {
google {
dimension "appstore"
buildConfigField "String", "ENCRYPTED_GOOGLE_IAP_KEY", "<removed>"
}
amazon {
dimension "appstore"
buildConfigField "String", "ENCRYPTED_GOOGLE_IAP_KEY", "ignored"
}
}
and I've configured the dependencies in the same build.gradle so that only the appropriate library is available:
dependencies {
...
googleImplementation 'com.android.billingclient:billing:6.1.0'
amazonImplementation files('libs/appstore-billing-compatibility-4.1.0.jar')
}
So, what I'd really like to be able to do is to conditionally import the appropriate dependency, i.e. with a preprocessor, it would be something like this:
#if defined(amazon)
import com.android.billingclient.api.*
#endif
#if defined(google)
import com.amazon.device.iap.billingclient.api.*
#endif
but of course that's not a Java/Kotlin compatible approach. I could copy my existing implementation into two folders and tweak just the import line, i.e.:
src/
|-- google/
| |-- java/
| |-- com/
| |-- example/
| |-- MyPurchaseCode.kt
|-- amazon/
| |-- java/
| |-- com/
| |-- example/
| |-- MyPurchaseCode.kt
but the code is identical except for that one line, so it will be a pain to maintain (and, after all, isn't the point of the Amazon compatibility library that I can keep my existing code :) )
Any suggestions on how I might do this? I wondered about creating some sort of "wrapper" interface and then having 2 source files, located as above, that implement it. But they're big with many classes and my understanding is that I'd have to clone the declarations.
Perhaps I'm overthinking this and there's some simple answer! (I admit my Java / Kotlin knowledge has faded …)
Thanks in advance!
You can for instance define type aliases of the objects you're using in the main
MyPurchaseCode.ktfile. There will be two Kotlin files with such type alias, one for thegoogleflavor and the second for theamazonone.Let's take for instance the
Purchaseobject: the type alias definition for google should be located heregoogle/java/com/example/and will look something like:and the one for
amazonshould be located underamazon/java/com/example/and look like:You can now add additional typealias for all the other common objects.
Your
MyPurchaseCode.ktcan be located undermain/src/java/com/example.Hope this helps
Response: This was great, thank you! (TIL Kotlin's
typealias). The final solution has one gotcha but works well enough. Specifically,typealiasdoesn't (always?) allow subtypes per this report as referenced here, so for the Amazon file I end up with:and similar for Google, namely:
The gotcha is shown here, where it is necessary to alias sub-types explicitly:
This means my code in
mainhad to change from:to:
which can be a little less clear, but I can live with that!