Google Billing Library 5:重置设备后isFeatureSupported返回SERVICE_DISCONNECTED
问题描述
我正在使用Google Billing Library 5版本,代码在API级别16、23、28、32的硬件设备上测试均正常。但在对一台运行API级别23的三星Galaxy S5(Android M)进行恢复出厂设置并登录全新Google ID后,购买功能失效,具体表现为:
billingClient.isReady返回falsebillingClient.isFeatureSupported返回SERVICE_DISCONNECTED,但onBillingServiceDisconnected未被调用billingClient.queryPurchasesAsync()可正常工作,返回OK响应码且显示无购买记录
该设备重置前运行正常,其他设备也无问题。应用管理器显示Google Play商店和Google Play Services版本与其他设备一致且已更新,符合官方要求。请问问题出在哪里?
相关代码
public void doPurchase( Activity activity ) { billingClient = BillingClient.newBuilder(activity).enablePendingPurchases() .setListener(this).build(); if ( ! billingClient.isReady() ) Log.i( appName, "Billing client is not ready" ); BillingResult billingResult = billingClient.isFeatureSupported( BillingClient.FeatureType.PRODUCT_DETAILS ); if ( billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK ) { Log.i( appName, String.format( "feature not supported %s", billingResult.toString() ) ); return; } billingClient.startConnection(new BillingClientStateListener() { public void onBillingSetupFinished( @NonNull BillingResult billingResult ) { if ( billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK ) { Log.i( appName, String.format( "billing setup response code %s", billingResult.toString() ) ); return; } launchPurchase( activity ); } public void onBillingServiceDisconnected() { Log.i( appName, "Disconnected" ); } }); } private void launchPurchase( final Activity activity ) { ImmutableList<QueryProductDetailsParams.Product> productList = ImmutableList.of( QueryProductDetailsParams.Product.newBuilder() .setProductId( SKU_BUY ) .setProductType( BillingClient.ProductType.INAPP) .build()); QueryProductDetailsParams.Builder builder = QueryProductDetailsParams.newBuilder(); builder.setProductList( productList ); billingClient.queryProductDetailsAsync( builder.build(), new ProductDetailsResponseListener() { @Override public void onProductDetailsResponse( @NonNull BillingResult billingResult, @Nullable List<ProductDetails> list ) { if ( billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK ) { Log.i( appName, String.format( "product details response code %s", billingResult.toString() ) ); return; } if ( list == null || list.size() <= 0 ) { Log.i( appName, "no products found" ); return; } ImmutableList<BillingFlowParams.ProductDetailsParams> deetsParams = ImmutableList.of( BillingFlowParams.ProductDetailsParams.newBuilder() .setProductDetails( list.get( 0 ) ) .build() ); BillingFlowParams purchaseParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList( deetsParams ) .build(); billingClient.launchBillingFlow( activity, purchaseParams ); } } ); }
问题分析与解决方案
1. 代码逻辑顺序错误
你在创建BillingClient实例后,立刻调用isReady()和isFeatureSupported(),但此时还未调用startConnection()建立连接,必然会返回false和SERVICE_DISCONNECTED——客户端还没尝试连接服务,自然处于未就绪状态。
正确流程应该是:
- 创建
BillingClient实例 - 调用
startConnection()发起连接 - 在
onBillingSetupFinished()回调确认连接成功(响应码为OK)后,再执行特性检查、商品查询等操作
当前代码在连接建立前就做了兼容性检查,直接导致流程提前终止,根本没走到后续的连接步骤。
2. 全新Google ID的Play服务初始化问题
恢复出厂后登录全新Google ID,设备上的Play服务需要完成首次初始化(同步账户信息、验证支付权限、下载必要组件),旧设备(如三星S5)这个过程可能耗时较长,甚至需要手动触发。可尝试:
- 打开Google Play商店,进入账户设置手动触发同步
- 重启设备,等待Play服务完成初始化
- 检查该Google ID是否完成基础账户验证(即使不绑定支付方式,首次登录也可能需要完成身份校验)
3. 三星旧设备的系统特殊限制
部分三星旧设备恢复出厂后,可能存在系统级服务延迟或权限异常,可尝试:
- 清除Google Play商店和Google Play Services的缓存与数据(注意:清除数据会重置Play服务设置,需重新登录账户)
- 确认设备日期时间设置为自动同步,避免时间偏差导致服务验证失败
修正后的代码示例
public void doPurchase( Activity activity ) { billingClient = BillingClient.newBuilder(activity).enablePendingPurchases() .setListener(this).build(); // 先启动连接,再在回调中执行后续操作 billingClient.startConnection(new BillingClientStateListener() { public void onBillingSetupFinished( @NonNull BillingResult billingResult ) { if ( billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK ) { Log.i( appName, String.format( "billing setup response code %s", billingResult.toString() ) ); return; } // 连接成功后再检查特性支持 BillingResult featureResult = billingClient.isFeatureSupported( BillingClient.FeatureType.PRODUCT_DETAILS ); if ( featureResult.getResponseCode() != BillingClient.BillingResponseCode.OK ) { Log.i( appName, String.format( "feature not supported %s", featureResult.toString() ) ); return; } launchPurchase( activity ); } public void onBillingServiceDisconnected() { Log.i( appName, "Disconnected" ); // 实现重连逻辑,避免服务断开后无法恢复 billingClient.startConnection(this); } }); }
内容的提问来源于stack exchange,提问作者Jerry Agin
相关产品推荐
相关产品推荐

