从旧版 AppCoins SDK 迁移到新版 Aptoide SDK
概述
本次迁移将旧版 AppCoins Billing SDK(io.catappult:android-appcoins-billing)替换为最新的 Aptoide Billing SDK(com.aptoide:android-aptoide-billing)。新版 SDK 带来了现代化的 API、更简洁的结构、对 Android 功能更好的兼容性,并与行业计费标准更紧密地保持一致。以下步骤涵盖了替换依赖项、采用 AptoideBillingClient 以及更新购买和商品查询。
迁移步骤摘要
成功完成迁移的主要步骤如下:
-
更新 SDK 依赖项
在 Gradle 文件中将 AppCoins SDK 依赖项替换为新版 Aptoide SDK。 -
重构 Billing Client 初始化
使用新的构建器模式将AppcoinsBillingClient替换为AptoideBillingClient。 -
更新购买监听器
更新PurchasesUpdatedListener,使其处理BillingResult而非用于 ResponseCode 的整数。 -
更新购买查询逻辑
将queryPurchases(SkuType)替换为queryPurchasesAsync(QueryPurchasesParams)。 -
迁移商品查询逻辑
将querySkuDetailsAsync替换为queryProductDetailsAsync,使用QueryProductDetailsParams定义要搜索的商品类型,并接收ProductDetails而非SkuDetails。 -
更新购买流程
将基于 SKU 的直接购买替换为使用ProductDetailsParams的BillingFlowParams。 -
重构消耗逻辑
将旧的consumeAsync(token)方法替换为使用ConsumeParams的新方法。
1. 更新 SDK 依赖项
AppCoins SDK:
implementation("io.catappult:android-appcoins-billing:0.9.+")
Aptoide SDK:
implementation("com.aptoide:android-aptoide-billing:1.+")
更新你的 build.gradle 并同步项目。
项目同步完成后,按照下面的示例,通过将 appcoins 替换为 aptoide,将旧版 AppCoins Billing SDK 的所有导入更新为新版 Aptoide Billing SDK。
旧版导入:
import com.appcoins.sdk.billing.Purchase
新版导入:
import com.aptoide.sdk.billing.Purchase
2. 重构 Billing Client 初始化
旧版初始化:
val cab = CatapultBillingAppCoinsFactory.BuildAppcoinsBilling(context, publicKey, listener)
cab.startConnection(appCoinsBillingStateListener)
CatappultAppcoinsBilling cab = CatapultBillingAppCoinsFactory.BuildAppcoinsBilling(context, publicKey, listener)
cab.startConnection(appCoinsBillingStateListener)
新版初始化:
val billingClient = AptoideBillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.setPublicKey(publicKey)
.build()
billingClient.startConnection(aptoideBillingClientStateListener)
AptoideBillingClient billingClient = AptoideBillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.setPublicKey(publicKey)
.build();
billingClient.startConnection(aptoideBillingClientStateListener);
所需更改:
- 将
AppcoinsBillingClient替换为AptoideBillingClient - 将
AppCoinsBillingStateListener替换为AptoideBillingClientStateListener - 对于响应代码,使用
BillingResult而非原始整数
3. 更新购买监听器
旧版:
val purchasesUpdatedListener = PurchasesUpdatedListener { responseCode, purchases ->
if (responseCode == ResponseCode.OK.value) {
for (purchase in purchases) {
// Apply here your Purchase result logic
}
}
}
PurchasesUpdatedListener purchasesUpdatedListener = (responseCode, purchases) -> {
if (responseCode == ResponseCode.OK.getValue()) {
for (Purchase purchase : purchases) {
// Apply here your Purchase result logic
}
}
};
新版:
val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases ->
if (billingResult.responseCode == BillingResponseCode.OK) {
for (purchase in purchases) {
// Apply here your Purchase result logic
}
}
}
PurchasesUpdatedListener purchasesUpdatedListener = (billingResult, purchases) -> {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (Purchase purchase : purchases) {
// Apply here your Purchase result logic
}
}
};
要点:
- 响应代码现在来自
billingResult.responseCode - 提取令牌以及处理交付/消耗的逻辑保持不变
4. 更新购买查询逻辑
旧版:
val purchasesResult = cab.queryPurchases(SkuType.inapp)
PurchasesResult purchasesResult = cab.queryPurchases(SkuType.inapp)
新版:
val params = QueryPurchasesParams.newBuilder()
.setProductType(ProductType.INAPP)
.build()
billingClient.queryPurchasesAsync(params) { billingResult, purchases ->
// Handle results
}
QueryPurchasesParams params = QueryPurchasesParams.newBuilder()
.setProductType(ProductType.INAPP)
.build();
billingClient.queryPurchasesAsync(params, (billingResult, purchases) -> {
// Handle results
});
5. 迁移商品查询逻辑
旧版:
cab.querySkuDetailsAsync(SkuDetailsParams(...), listener)
cab.querySkuDetailsAsync(new SkuDetailsParams(...), listener)
新版:
val params = QueryProductDetailsParams.newBuilder()
.setProductList(
listOf(
Product.newBuilder()
.setProductId("your_product_id")
.setProductType(ProductType.INAPP)
.build()
)
).build()
billingClient.queryProductDetailsAsync(params) { billingResult, productDetailsResult ->
if (billingResult.responseCode == BillingResponseCode.OK) {
for (product in productDetailsResult.productDetailsList) {
// Use product details here
}
}
}
QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
.setProductList(
List.of(
Product.newBuilder()
.setProductId("your_product_id")
.setProductType(ProductType.INAPP)
.build()
)
).build();
billingClient.queryProductDetailsAsync(params, (billingResult, productDetailsResult) -> {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (ProductDetails product : productDetailsResult.getProductDetailsList()) {
// Use product details here
}
}
});
注意事项:
- 将
SkuDetailsParams替换为QueryProductDetailsParams - 将
SkuType替换为ProductType
6. 更新购买流程
旧版:
val billingFlowParams = BillingFlowParams(...)
cab.launchBillingFlow(activity, billingFlowParams)
BillingFlowParams billingFlowParams = new BillingFlowParams(...);
cab.launchBillingFlow(activity, billingFlowParams);
新版:
val productDetailsParams = BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build()
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(listOf(productDetailsParams))
.setObfuscatedAccountId(userId)
.setFreeTrial(true)
.build()
billingClient.launchBillingFlow(activity, billingFlowParams)
BillingFlowParams.ProductDetailsParams productParams =
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build();
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(List.of(productParams))
.setObfuscatedAccountId(userId)
.setFreeTrial(true) // Use this to initiate Free Trials
.build();
billingClient.launchBillingFlow(activity, billingFlowParams);
主要更改:
- 使用
ProductDetails而非原始 SKU 字符串 - 添加
setObfuscatedAccountId()用于用户级别的跟踪 setFreeTrial()处理试用逻辑
7. 重构消耗逻辑
旧版:
cab.consumeAsync(purchase.token, consumeResponseListener)
cab.consumeAsync(purchase.getToken(), consumeResponseListener);
新版:
val consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
billingClient.consumeAsync(consumeParams, consumeResponseListener)
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.consumeAsync(consumeParams, consumeResponseListener);
重要:
- 务必在 48 小时内消耗购买
- 订阅也应被消耗或确认(通过 Backend API)
更改对比表
| 功能 | 旧版 AppCoins SDK | 新版 Aptoide SDK |
|---|---|---|
| Billing Client 类 | AppcoinsBillingClient | AptoideBillingClient |
| 查询商品 | querySkuDetailsAsync | queryProductDetailsAsync |
| 购买流程参数 | 使用 SKU 的 BillingFlowParams | 使用 ProductDetails 的 BillingFlowParams |
| 计费操作结果 | 作为 ResponseCode 的 Int 值 | 使用包含 BillingResponseCode 和 Debug Message 的 BillingResult |
| 消耗 | consumeAsync(token) | consumeAsync(ConsumeParams) |
常见问题
在哪里可以找到完整的 Aptoide Billing SDK 集成文档?
关于新版 Aptoide Billing SDK 集成的完整文档可在此处找到。其中包含了完整且成功集成我们计费系统所需的最重要步骤。
在哪里可以找到旧版 AppCoins Billing SDK 集成文档?
关于旧版 Aptoide Billing SDK 集成的文档可在此处找到。