我正在从 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.xml
的 application
节点中,我有这个: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 已断开连接。
您已启动连接,但连接尚未完成设置。 可能的竞争条件,因为 startConnection 是一个异步进程。您可以使用 billingClient.isReady() 检查它是否可用。
您的应用可能在启动后失去了连接/互联网。
您的设备/模拟器不支持 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/