onBillingSetupFinished 从未调用过

onBillingSetupFinished never called

我一直与 Java 合作,但这次我尝试在 Kotlin 中开发,我有一个应用程序,该应用程序将有一个付费按钮来删除广告(使用 Google Play 的计费系统),但我无法让它工作。

创建时:

btnRemoveAds.setOnClickListener {
        Toast.makeText(this@Settings, "Click Button", Toast.LENGTH_SHORT).show()
        billingClient = BillingClient.newBuilder(this)
            .setListener(purchasesUpdatedListener)
            .enablePendingPurchases()
            .build()

        billingClient.startConnection(object : BillingClientStateListener {
            override fun onBillingSetupFinished(billingResult: BillingResult) {
                Toast.makeText(this@Settings, "SetupFinished", Toast.LENGTH_SHORT).show()
                if (billingResult.responseCode ==  BillingClient.BillingResponseCode.OK) {
                    Toast.makeText(this@Settings, "OK", Toast.LENGTH_SHORT).show()
                    // The BillingClient is ready. You can query purchases here.
                    billingClient.queryPurchasesAsync(
                        SkuType.INAPP
                    ) { billingResult, list ->
                        if (list.size != 0){
                            if (list.get(0).purchaseState == Purchase.PurchaseState.PURCHASED){
                                setPlus(true)
                                setResult(RESULT_OK)
                            } else{
                                queryAvaliableProducts()
                            }
                        } else{
                            queryAvaliableProducts()
                        }
                    }
                } else{
                    Toast.makeText(this@Settings, "NO", Toast.LENGTH_SHORT).show()
                }
            }
            override fun onBillingServiceDisconnected() {
                Toast.makeText(this@Settings, "Disconnected", Toast.LENGTH_SHORT).show()
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }
        })
    }

按下按钮时我唯一能看到的 Toast 是“单击按钮”

这些是我的方法:

private fun queryAvaliableProducts() {
    val skuList: MutableList<String> = ArrayList()
    skuList.add("remove_ads")
    val params = SkuDetailsParams.newBuilder()
    params.setSkusList(skuList).setType(INAPP)
    billingClient.querySkuDetailsAsync(
        params.build()
    ) { billingResult, skuDetailsList -> // Process the result.
        if (skuDetailsList!!.size != 0) {
            val billingFlowParams = BillingFlowParams.newBuilder()
                .setSkuDetails(skuDetailsList[0])
                .build()
            val responseCode = billingClient.launchBillingFlow(
                this@Settings,
                billingFlowParams
            ).responseCode
        }
    }
}

private val purchasesUpdatedListener =
    PurchasesUpdatedListener { billingResult, purchases ->
        // To be implemented in a later section.
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK
            && purchases != null
        ) {
            for (purchase in purchases) {
                handlePurchase(purchase)
            }
        } else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
            // Handle an error caused by a user cancelling the purchase flow.
        } else {
            // Handle any other error codes.
        }
    }

fun handlePurchase(purchase: Purchase) {
    if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged) {
            val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                .setPurchaseToken(purchase.purchaseToken)
                .build()
            billingClient.acknowledgePurchase(
                acknowledgePurchaseParams,
                acknowledgePurchaseResponseListener
            )
        }
    }
}

var acknowledgePurchaseResponseListener =
    AcknowledgePurchaseResponseListener { billingResult ->
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            setPlus(true)
            setResult(RESULT_OK)
            finish()
        }
    }

我还在billingClient.startConnection

之后实现了一个按钮来检查连接状态
btnConnectionState.setOnClickListener {
        Toast.makeText(this@Settings, billingClient.connectionState.toString(), Toast.LENGTH_SHORT).show()
    }

结果我得到 2(已连接),所以我觉得 onBillingSetupFinished 和 onBillingServiceDisconnected 从未执行过,这对我来说似乎很奇怪,我的代码中是否有任何错误?

除了 Toast 本身,您的代码 afaik 中没有任何错误。 onBillingServiceDisconnected 未在主线程上调用。如果你像这样尝试抓住它:

try {
    Toast.makeText(this@Settings, "NO", Toast.LENGTH_SHORT).show()
} catch (ex: Exception) {
    Log.e("MyApp", "Error", ex)
}

它会打印这样的错误

06-05 00:00:38.713 8595 9215 E MyApp : java.lang.NullPointerException: Can't toast on a thread that has not called Looper.prepare()

您还可以打印调用回调的线程:

Log.e("MyApp", "Running on ${Thread.currentThread().name}")

它会告诉你

Running on PlayBillingLibrary-1

所以切换回Toast的主线程(有方法)或者使用简单的Log语句来验证调用了方法。