Google 播放应用内结算 onPurchasesUpdated() 错误响应代码 -1

Google Play in-app Billing onPurchasesUpdated() error response code -1

我第一次在我的应用中实施应用内结算,即使所有代码都正确,它也不起作用!

我有一个BillingManager.java

public class BillingManager implements PurchasesUpdatedListener {
private static final String TAG = "BillingManager";

private final BillingClient mBillingClient;
private final Activity mActivity;
String base64Key = "mykey";
private static Context myCxt;
private String mAdRemovalPrice;
private static final String ITEM_SKU_ADREMOVAL = "myskuid";
public int billingResult;

public BillingManager(Activity activity) {
    mActivity = activity;
    mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
    mBillingClient.startConnection(new BillingClientStateListener() {
        @Override
        public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponse) {
            if (billingResponse == BillingClient.BillingResponse.OK) {
                Log.i(TAG, "onBillingSetupFinished() good response: " + billingResponse);

                List skuList = new ArrayList<>();
                skuList.add(ITEM_SKU_ADREMOVAL);
                SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
                mBillingClient.querySkuDetailsAsync(params.build(),
                        new SkuDetailsResponseListener() {
                            @Override
                            public void onSkuDetailsResponse(int responseCode, List skuDetailsList) {
                                // Process the result.

                                if (responseCode == BillingClient.BillingResponse.OK
                                        && skuDetailsList != null) {
                                    for (Object skuDetailsObject : skuDetailsList) {
                                        SkuDetails skuDetails = (SkuDetails) skuDetailsObject;
                                        String sku = skuDetails.getSku();
                                        String price = skuDetails.getPrice();
                                        if (ITEM_SKU_ADREMOVAL.equals(sku)) {
                                            mAdRemovalPrice = price;
                                        }
                                    }
                                }
                            }
                        });
            } else {
                Log.w(TAG, "onBillingSetupFinished() error code: " + billingResponse);
            }
        }
        @Override
        public void onBillingServiceDisconnected() {
            Log.w(TAG, "onBillingServiceDisconnected()");
        }
    });
}

@Override
public void onPurchasesUpdated(int responseCode, List<Purchase> purchases) {

    if (responseCode == BillingClient.BillingResponse.OK
            && purchases != null) {
    for(Purchase purchase: purchases) {
        // When every a new purchase is made
        // Here we verify our purchase
        Log.i(TAG, "onPurchasesUpdated() ourchase ok response: " + responseCode);

        if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
            // Invalid purchase
            // show error to user
            myCxt = MainActivity.proContext;

            Toast.makeText(myCxt, myCxt.getString(R.string.purchase_err), Toast.LENGTH_LONG).show();
            Log.i(TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping...");
            return;
        } else {
            // purchase is valid
            // Perform actions
            myCxt = MainActivity.proContext;

            Toast.makeText(myCxt, myCxt.getString(R.string.purchase_done), Toast.LENGTH_LONG).show();
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(myCxt);
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean("isPro", true);
            editor.apply();

        }
    }

    } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
    // Handle an error caused by a user cancelling the purchase flow.
        Log.i(TAG, "onPurchasesUpdated() user canceled response: " + responseCode);
} else {
    // Handle any other error codes.
        Log.i(TAG, "onPurchasesUpdated() error response: " + responseCode);
}
}

public void startPurchaseFlow() {

    BillingFlowParams flowParams = BillingFlowParams.newBuilder()
            .setSku(ITEM_SKU_ADREMOVAL)
            .setType(BillingClient.SkuType.INAPP)
            .build();
    mBillingClient.launchBillingFlow(mActivity, flowParams);
    Log.i(TAG, "StartPurchaseFlow called");
}

private boolean verifyValidSignature(String signedData, String signature) {
    try {
        return Security.verifyPurchase(base64Key, signedData, signature);
    } catch (IOException e) {
        Log.e(TAG, "Got an exception trying to validate a purchase: " + e);
        return false;
    }
}

然后我在我的应用程序菜单中这样称呼它:

if (id == R.id.action_pro) {
        BillingManager mbilling = new BillingManager(MainActivity.this);
        mbilling.startPurchaseFlow();
        return true;
    }

实际上,如果我在调试模式下阅读日志,似乎 onPurchasesUpdated() 方法会抛出错误 -1 作为响应代码!因此,这意味着响应代码为 -1,根据 Java 文档,这是 http 协议中的一般错误...为什么我会收到此消息?

即使与其他代码或在线指南相比,该代码看起来也不错。有没有人有什么建议?

请确保您的结算客户端在开始购买流程之前已初始化。

响应码-1表示billingclient断开连接