从0到1实现MyBookshelf应用内购买:Google Play Billing无缝集成指南
一、为什么需要应用内购买?
你是否遇到过用户反馈"想支持开发者却找不到渠道"?或者"特殊章节需要付费但无法支付"的问题?应用内购买(In-App Purchase, IAP)是解决这些痛点的最佳方案。通过Google Play Billing(谷歌应用内支付)集成,MyBookshelf可以实现数字内容购买、高级功能解锁等商业化场景,同时为用户提供安全便捷的支付体验。
二、集成前的准备工作
在开始编码前,需要完成以下准备工作:
2.1 配置AndroidManifest.xml
确保AndroidManifest.xml中已添加必要权限和服务声明。虽然当前项目清单AndroidManifest.xml未直接包含Billing权限,但后续需要添加:
<uses-permission android:name="com.android.vending.BILLING" />
2.2 添加依赖库
在app/build.gradle中添加Google Play Billing Library依赖:
dependencies {
implementation "com.android.billingclient:billing:4.0.0"
}
2.3 准备商品信息
在Google Play Console中创建商品,记录商品ID。建议在项目中统一管理:
public class IapConstants {
// 章节购买
public static final String SKU_CHAPTER_PREMIUM = "chapter_premium_1";
// 高级会员
public static final String SKU_MEMBERSHIP_MONTHLY = "membership_monthly";
}
三、核心实现步骤
3.1 初始化BillingClient
创建BillingManager管理类,封装BillingClient的初始化与连接:
public class BillingManager implements PurchasesUpdatedListener {
private BillingClient billingClient;
private Context context;
public BillingManager(Context context) {
this.context = context;
billingClient = BillingClient.newBuilder(context)
.enablePendingPurchases()
.setListener(this)
.build();
connect();
}
public void connect() {
if (!billingClient.isReady()) {
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// 连接成功,可以查询商品
}
}
@Override
public void onBillingServiceDisconnected() {
// 连接断开,尝试重连
connect();
}
});
}
}
// 其他方法...
}
3.2 查询商品详情
获取商品价格、描述等信息,用于UI展示:
public void querySkuDetails() {
List<String> skuList = new ArrayList<>();
skuList.add(IapConstants.SKU_CHAPTER_PREMIUM);
skuList.add(IapConstants.SKU_MEMBERSHIP_MONTHLY);
SkuDetailsParams params = SkuDetailsParams.newBuilder()
.setSkusList(skuList)
.setType(BillingClient.SkuType.INAPP)
.build();
billingClient.querySkuDetailsAsync(params, (billingResult, skuDetailsList) -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
for (SkuDetails details : skuDetailsList) {
// 缓存商品信息
if (details.getSku().equals(IapConstants.SKU_CHAPTER_PREMIUM)) {
// 更新UI显示价格
updateChapterPrice(details.getPrice());
}
}
}
});
}
3.3 发起购买流程
在阅读页面添加购买按钮,触发购买流程:
public void launchBillingFlow(Activity activity, SkuDetails skuDetails) {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
billingClient.launchBillingFlow(activity, billingFlowParams);
}
// 按钮点击事件
buyButton.setOnClickListener(v -> {
if (skuDetails != null) {
billingManager.launchBillingFlow(this, skuDetails);
}
});
3.4 处理购买结果
在PurchasesUpdatedListener中处理购买结果:
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
// 用户取消购买
showToast("购买已取消");
} else {
// 购买失败
showToast("购买失败,请重试");
}
}
private void handlePurchase(Purchase purchase) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams params = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(params, billingResult -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// 确认购买成功,解锁内容
if (purchase.getSku().equals(IapConstants.SKU_CHAPTER_PREMIUM)) {
unlockPremiumChapter();
}
}
});
}
}
}
四、UI与用户体验优化
4.1 购买按钮设计
使用项目资源中的购买图标,确保视觉一致性: 购买按钮图标
在布局文件中添加按钮:
<Button
android:id="@+id/btn_buy_chapter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chapter_pay"
android:drawableLeft="@drawable/ic_purchase"
android:background="@drawable/shape_fillet_btn"/>
4.2 购买状态管理
使用SharedPreferences保存购买状态:
private void savePurchaseState(String sku) {
SharedPreferences prefs = context.getSharedPreferences("iap_prefs", Context.MODE_PRIVATE);
prefs.edit().putBoolean(sku, true).apply();
}
public boolean isPurchased(String sku) {
SharedPreferences prefs = context.getSharedPreferences("iap_prefs", Context.MODE_PRIVATE);
return prefs.getBoolean(sku, false);
}
五、测试与调试
5.1 测试账号配置
在Google Play Console中添加测试账号,使用测试卡进行支付测试。
5.2 错误处理与日志
集成项目现有的Debug工具记录购买日志:
Debug.printLog("IAP", "Purchase result: " + billingResult.getResponseCode());
六、完整集成路径
- 权限配置:AndroidManifest.xml
- 字符串资源:strings.xml
- 按钮样式:shape_fillet_btn.xml
- 核心实现:BillingManager.java
- 阅读页面集成:ReadBookActivity.java
七、总结与注意事项
- 合规性:确保应用内购买内容符合Google Play政策,避免违规。
- 安全性:敏感购买逻辑建议在服务端验证,防止本地篡改。
- 用户体验:购买流程应简洁明了,提供清晰的成功/失败反馈。
- 兼容性:支持Billing Library最低版本与项目targetSdkVersion匹配。
通过以上步骤,MyBookshelf应用即可实现完整的Google Play Billing集成,为用户提供顺畅的购买体验,同时为项目增加商业化变现能力。更多实现细节可参考官方文档应用内购买指南。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



