android - 使用静态产品测试计费返回 SERVICE_DISCONNECTED

标签 android android-billing

我正在从 Version 3 升级我应用中的应用内结算至 newer code .版本 3 运行良好,现在正在我的应用程序中生产,但我读到它最终会被弃用。

当我尝试使用 static product id 测试购买流程时(android.test.purchased),BillingResult 结果代码仅返回 -1 并带有调试消息“服务连接已断开”。据我所知,较新的库中没有服务连接,但版本 3 中有。

如果我使用真实的应用内产品代码,它会告诉我我已经购买了它,这是正确的,但我需要测试实际的购买流程。

我正在实际设备 (Pixel 3 XL) 上测试此功能,而不是模拟器。我尝试在使用测试帐户(而非开发人员)登录的单独设备上对其进行测试,但我得到了相同的结果。

更新:我在 Developer Console 中设置了一个真实的(测试)应用内托管产品,然后在使用测试(非开发者)帐户登录的设备上安装了我的应用,但我仍然收到“服务连接已断开”错误。我觉得这是代码之外的东西,但不确定是什么。

更新 2:我创建了一个新项目,其中除了计费代码外什么都没有,它工作正常,所以我的应用程序中有一些东西导致它中断。

更新 3:我创建了一个新项目并将损坏的应用程序中的代码导入其中,但仍然收到相同的错误消息。我觉得,现在,我的包名称和返回错误消息的 Google 服务器有些东西。

更新 4:我创建了一个空白项目,但为它提供了与我损坏的应用程序相同的包名称,并且计费有效,所以它不是包名称。现在我的猜测是旧的 AIDL 计费代码(第 3 版)中存在一些干扰。

解决方案!!!在 AndroidManifest.xmlapplication 节点中,我有这个:tools:node="replace"。删除了该属性,现在可以计费了。

    mBillingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(this).build();
    mBillingClient.startConnection(new BillingClientStateListener() {
        @Override
        public void onBillingSetupFinished(BillingResult billingResult) {
            if (billingResult.getResponseCode() == OK) {
                    final Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
                    if (purchasesResult.getResponseCode() == OK) {

                        final List<Purchase> purchases = purchasesResult.getPurchasesList();

                        for (final Purchase purchase : purchases) {
                        }
                    }
            }
        }
        @Override
        public void onBillingServiceDisconnected() {
            CommonUtils.showToast(mActivity, "disconnected");
        }
    });
    
    
    mUnlockPremiumButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

                final List<String> skuList = new ArrayList<> ();
                skuList.add(getString(R.string.inapp_premium_product_id));

                final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder()
                    .setSkusList(skuList)
                    .setType(BillingClient.SkuType.INAPP);

                mBillingClient.querySkuDetailsAsync(params.build(),
                        new SkuDetailsResponseListener() {
                            @Override
                            public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {

                                for (SkuDetails skuDetails : skuDetailsList) {
                                    if (getString(R.string.inapp_premium_product_id).equals(skuDetails.getSku())) {

                                        final BillingFlowParams flowParams = BillingFlowParams.newBuilder()
                                                .setSkuDetails(skuDetails)
                                                .build();

                                        final BillingResult result = mBillingClient.launchBillingFlow(mActivity, flowParams);

                                        if (result.getResponseCode() == ITEM_ALREADY_OWNED)
                                        {
                                            CommonUtils.showToast(mActivity, getString(R.string.alert_purchased));
                                        }
                                        else if (result.getResponseCode() != OK)
                                        {
                                            //always returns a getResponseCode of -1 (service disconnected)
                                        }
                                    }
                                }
                            }
                        });
        }
    });

最佳答案

由于错误清楚地表明,由于以下可能的原因,Billing Client 已断开连接。

  1. 您已启动连接,但连接尚未完成设置。 可能的竞争条件,因为 startConnection 是一个异步进程。您可以使用 billingClient.isReady() 检查它是否可用。

  2. 您的应用可能在启动后失去了连接/互联网。

  3. 您的设备/模拟器不支持 Google Play 服务。

以下是 Billing API 3.0 和 Android Version Targeted SDK 28 中的工作代码。 如计费 API 错误处理部分 (https://developer.android.com/google/play/billing/integrate) 中所述,如果连接丢失,应用程序必须负责重新建立连接。我建议使用包含 Billing API 的 Singleton 类,并使用 billingClient.isReady() 方法检查连接是否成功,如果没有尝试重新建立连接。如果您在 BillingClientStateListener 类覆盖方法中添加日志记录。我将跳过该代码,因为它很简单,并且在我上面提供的链接中有详细记录。

public class ApplicationBillingClient
{
static ApplicationBillingClient applicationBillingClient= null;
private static BillingClient billingClient;

private ApplicationBillingClient() {}

private static boolean isInitialized()
{
    return applicationBillingClient != null && billingClient != null;
}

private static void initialize(Context applicationContext)
{
    try
    {
        if(applicationContext != null)
        {
            applicationBillingClient = new ApplicationBillingClient();
            BillingClient.Builder builder=  BillingClient.newBuilder(applicationContext);
            builder.setListener(new PurchaseActivityListener());
            builder.enablePendingPurchases();
            billingClient = builder.build();
        }

        LogUtil.info("Initializing the Billing Client");

    }
    catch (Exception ex)
    {
        LogUtil.error("Error while initializing billing client", ex);
    }

}

public static ApplicationBillingClient getInstance(Context applicationContext)
{
    if(isInitialized() == false)
    {
        initialize(applicationContext);
    }

    return  applicationBillingClient;
}

public void startConnection()
{
   billingClient.startConnection(new StateListener());
}

public boolean isReady()
{
    return billingClient.isReady();
}

public void getMonthlySubscription()
{
    try
    {
        if(billingClient.isReady())
        {
            SkuDetailsParams.Builder skuBuilder = SkuDetailsParams.newBuilder();
            skuBuilder.setType(BillingClient.SkuType.SUBS);
            skuBuilder.setSkusList(Arrays.asList(new String[]{MONTHLY_BILLING_SUBSCRIPTION_SKU}));
            SkuDetailsParams params = skuBuilder.build();
            billingClient.querySkuDetailsAsync(params, new SkuDetailsListener());
        }

    }
        catch (Exception ex)
    {
        LogUtil.error("Error while querying async SKU for Monthly Subscription", ex);
    }
  }
 }

 //In your activity
 ApplicationBillingClient appBillingClient = 
 ApplicationBillingClient.getInstance(applicationContext);
        if (appBillingClient.isReady() == false)
        {
            appBillingClient.startConnection();
        }
        else
        {
           appBillingClient.getMonthlySubscription();
        }

关于android - 使用静态产品测试计费返回 SERVICE_DISCONNECTED,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56332090/

相关文章:

java - 当应用程序崩溃时,Android App SharedPreferences 会被删除吗?

android - 更新后应用内计费不起作用 - Google 商店

android - 使用Android BillingClient,如何在重新安装或更改设备后恢复用户的IAP?

android - "com.android.vending.BILLING"和 "android.permission.BILLING"之间的区别

android - 我怎样才能简化我的布局?

java - 初始化 Android 应用程序

java - Android Play 商店订阅计费不会触发任何操作

android - 使用 SOOMLA Android Store 计费包装器请求交易

android - R8 说类型被多次定义 : in build\. 转换和在 build\tmp\kotlin-classes

android - 如何使用android ndk访问相机