- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Google Play Store 上发布了一个 Android 应用程序,上周我发布了一个新的更新,只是为了解决一些小问题。从我在 Play 商店添加更新版本的那天开始,我可以在 Firebase Crashlytics 上看到有人尝试购买应用功能时出现问题。
在我在生产中发布更新版本之前,我在 Alpha 测试中添加了该应用程序,以便确保 InAppPurchase 正常工作,并且确实如此。
当其他人尝试购买应用程序功能时,我可以看到抛出了这个致命异常:
Fatal Exception: java.lang.IllegalArgumentException: SKU cannot be null.
at com.android.billingclient.api.BillingFlowParams$Builder.build(com.android.billingclient:billing@@3.0.0:23)
SKU 在我的“托管产品”列表中仍然有效。
billingClient = BillingClient.newBuilder(getActivity())
.enablePendingPurchases()
.setListener(purchasesUpdatedListener)
.build();
这是我用来启动连接的代码:
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
Log.d(TAG, "Connection finished");
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
List<String> skuList = new ArrayList<>();
skuList.add("unlock_keyboard");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult,
List<SkuDetails> skuDetailsList) {
// Process the result.
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
for (Object skuDetailsObject : skuDetailsList) {
skuDetails = (SkuDetails) skuDetailsObject;
sku = skuDetails.getSku();
}
Log.d(TAG, "i got response");
Log.d(TAG, String.valueOf(billingResult.getResponseCode()));
Log.d(TAG, billingResult.getDebugMessage());
}
}
});
}
}
这是我用来处理购买的代码:
PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
for (Purchase purchase : list) {
handlePurchase(purchase);
Log.d(TAG, "Purchase completed" + billingResult.getResponseCode());
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
Log.d(TAG, "User Canceled" + billingResult.getResponseCode());
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
if ("unlock_keyboard".equals(sku)) {
KeyboardAlreadyPurchasedConfirmation();
}
Log.d(TAG, "Item Already owned" + billingResult.getResponseCode());
}
}
};
为了启动计费流程,用户必须单击对话框中的按钮。这是代码:
builder.setPositiveButton(
getString(R.string.purchase_keyboard),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
sku = "unlock_keyboard";
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
billingClient.launchBillingFlow(Objects.requireNonNull(getActivity()), flowParams);
}
});
在我的应用程序之前的版本中,这种情况从未发生过,它只是在新更新后才开始。我只需要知道可能导致此问题的原因,是我的代码有问题还是只是 Google Play 服务有问题?我必须说明这发生在具有不同 Android 版本的不同设备上。
最佳答案
我还没有解决这个问题,但我找到了一种方法来减少这个库升级产生的错误数量。
我所做的是将 Google Billing Library 从版本 降级。 3.0.1 到版本 2.1.0 即使我仍然在 Firebase 中遇到一些错误(SKU 为空),大多数用户现在都可以购买产品。
另外,我实现了一个方法,当首次打开 Activity 时无法启动 Google Billing 库连接时调用该方法,因此更准确地说是 重启计费连接方法。
如果您遇到同样的问题,我建议您至少现在尝试同样的事情,因为 Google Billing 库似乎仍然存在一些需要修复的问题。
1. 在 build.gradle(app) 添加这一行:
implementation 'com.android.billingclient:billing:2.1.0'
2 .
在 AndroidManifest.xml 文件中添加 BILLING 权限,因为这个库的旧版本仍然需要它:
<uses-permission android:name="com.android.vending.BILLING" />
3 .
创建重启计费连接方式:
public void restartBillingConnection() {
billingClient = BillingClient.newBuilder(Objects.requireNonNull(getActivity())).enablePendingPurchases().setListener(ChooseOptionsFragment.this).build();
billingClient.startConnection(new BillingClientStateListener() {@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
Log.d(TAG, "Connection finished");
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
List < String > skuList = new ArrayList < >();
skuList.add(ITEM_SKU_AD_REMOVAL);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, List < SkuDetails > skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
for (Object skuDetailsObject: skuDetailsList) {
skuDetails = (SkuDetails) skuDetailsObject;
sku = skuDetails.getSku();
String price = skuDetails.getPrice();
if (ITEM_SKU_AD_REMOVAL.equals(sku)) {
skuPrice = price;
BillingFlowParams flowParams = BillingFlowParams.newBuilder().setSkuDetails(skuDetails).build();
billingClient.launchBillingFlow(Objects.requireNonNull(Objects.requireNonNull(getActivity())), flowParams);
}
else {
Log.d(TAG, "Sku is null");
}
}
Log.d(TAG, "i got response");
Log.d(TAG, String.valueOf(billingResult.getResponseCode()));
Log.d(TAG, billingResult.getDebugMessage());
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ERROR) {
Toast.makeText(getActivity(), "Error in completing the purchase!", Toast.LENGTH_SHORT).show();
}
}
});
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_TIMEOUT) {
Toast.makeText(getActivity(), "Service timeout!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getActivity(), "Failed to connect to the billing client!", Toast.LENGTH_SHORT).show();
}
}@Override
public void onBillingServiceDisconnected() {
restartBillingConnection();
}
});
}
4. 确保在 Google Billing 服务断开连接时调用此方法:
@Override
public void onBillingServiceDisconnected() {
restartBillingConnection();
}
希望此解决方案可以帮助您暂时解决此问题。如果您有其他方法可以完全修复它,请在这篇文章中留下答案。
关于Android - 生产中的 Google Play 计费库错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62857724/
所以我的应用程序的评论显示在我的游戏控制台中,但是由于某种原因,当我在 google Play 商店上访问我的应用程序链接并以普通用户的身份查看它时,我没有收到新评论的通知,我的显示了 13 条评论,
一旦我在 2.3 play 项目上运行 'sbt compile',我就不能再使用 'sbt compile' 来编译任何 Play 2.2.x 项目。这是我运行 sbt 命令时的错误。 [info]
我有点困惑,想得到一个解释。 我正在使用 Java Play 2 和 Akka Actor 。我使用 play run 启动系统。 不过,我刚刚看到一个视频,使用了命令: play akka star
当我玩游戏时,我遇到两个选择play.api.mvc和 play.mvc包裹 有什么不同? 最佳答案 从戏! 2 文档: The API available in the play.api packa
从 2.3 迁移到 2.4 后,我收到此错误。我应该使用的正确导入语句是什么? error: value routesImport is not a member of object play.Pla
所以我在 google play 上有一个应用程序已经将近 6 个月了,最近两个月我更新了我的应用程序屏幕截图,从那时起,每次我更新我的应用程序时,我都开始收到应用程序拒绝。 上次我提出上诉并被接受,
我有以下代码: Snapshots.OpenSnapshotResult result; result = Games.Snapshots.open(googleApiClient, "save",
在过去 72 小时内,我为 Google Play 开发者计划支付的 Google 电子钱包付款显示为“您的购买正在处理中”。我知道这可能需要长达 48 小时,但这是他们处理时间最坏情况之后的一整天。
我在 Play 商店发布了应用程序,我不知道为什么应用程序显示预注册,我想为我的用户提供直接下载选项。伸出援手将不胜感激。 最佳答案 instructions for pre-registration
我有一个 PHP 后端,它与 Google Play 服务集成以验证从 APP 进行的购买。购买信息返回收据和签名,我需要验证购买是否正确。 我收到: { ...rest of the data
我在 Google Play Developer Console 上创建了我的 Android 应用程序的草稿。我已经填写了所有需要的信息。必需的步骤之一是“内容评级”。我已填写表格以自动分配 Goo
我已经设置好了 com.typesafe.play play_2.13 2.7.4 在项目 pom.xml 中。但是,当我尝试遵循this tutorial时,语句 pla
我在 Play 商店上发布了一个应用程序,并收到了一些评论。在Google Play开发者控制台中,我在一些评论中看不到应用程序的版本。这是我在“应用程序”标题下找到的内容。 版本代码 — 版本名称
假设 A 是所有者。我希望我们团队的 B、C 和 D 用户能够上传我们应用程序的新版本。这可能吗?来自 this我不太清楚用户有什么样的权限。如果有人对这部分有任何经验,欢迎。 最佳答案 您需要 go
我正在尝试将应用重新提交到 Google Play,但我似乎可以找到一种技术上的方法来实现此目的。 我对“您的应用主要针对 COPPA 定义的 13 岁以下 child 吗?”的回答是肯定的,然后在不
我想分享一下我在分析 Google Play 控制台的新功能时遇到的情况,并尝试找到解决方案。 正如你们许多人可能已经知道的那样,Google 已在 Google Play 控制台上发布了更新并引入了
我有两个用 playframework 编写的应用程序。我想加入另一个。我有一个数据库,我想在它们之间共享我的登录类。应用程序对类、方法、变量使用不同的名称。 我怎样才能实现它?我应该创建 jar 版
对于我的硕士论文,我需要自动将来自 Google Play 的不同 Android 应用程序的信息写入一个文本文件。所以我使用 perl 脚本语言来实现这种自动化。我的 perl 脚本可以在 Goog
我想测试子项目是如何工作的,尤其是 routes在主项目 ( this was not visible before ) 中考虑了子项目的数量。 我在这里阅读了文档: https://github.c
我正在使用 Play 框架 2.1.2,我有一个 handlere 方法返回一个 Promise,如 Play 的 2.1.2 documentation 中所述 但是 Play 抛出编译错误说: C
我是一名优秀的程序员,十分优秀!