【问题标题】:Huawei In App Purchase : Performing multiple requests in short time leads to an error华为应用内购买:短时间内执行多个请求导致错误
【发布时间】:2020-07-29 06:39:08
【问题描述】:

我在我的应用程序中使用华为应用内购买。问题是当用户在短时间内(比如说大约 2 秒)向 IapClient 发出多个请求(比如说大约 5 个)时,我的应用程序会抛出一个错误

我的日志如下:

com.huawei.hms.iap.IapApiException: -1: Core error
   at com.huawei.hms.iap.f.doExecute(IsEnvReadyTaskApiCall.java:1068)
   at com.huawei.hms.common.internal.TaskApiCall.onResponse(TaskApiCall.java:190)
   at com.huawei.hms.common.internal.HuaweiApiManager$ConnectionManager$1.onCallback(HuaweiApiManager.java:272)
   at com.huawei.hms.common.internal.HmsClient$a.onError(HmsClient.java:134)
   at com.huawei.hms.adapter.BaseAdapter$BaseRequestResultCallback.onResult(BaseAdapter.java:205)
   at com.huawei.hms.adapter.BaseAdapter$BaseRequestResultCallback.onResult(BaseAdapter.java:175)
   at com.huawei.hms.support.api.PendingResultImpl$a.b(PendingResultImpl.java:490)
   at com.huawei.hms.support.api.PendingResultImpl$a.handleMessage(PendingResultImpl.java:467)
   at android.os.Handler.dispatchMessage(Handler.java:110)
   at android.os.Looper.loop(Looper.java:219)
   at android.app.ActivityThread.main(ActivityThread.java:8347)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

IAP 调用的次数/频率是否有任何限制?在这种情况下您有什么建议?

【问题讨论】:

    标签: android huawei-mobile-services huawei-developers


    【解决方案1】:

    错误代码-1表示建议您使用obtainOwnedPurchases API检查用户是否购买了产品。

    解决方案:使用obtainOwnedPurchases API 来检查用户是否购买了产品。

    对于已购买的消耗品,发货后调用consumeOwnedPurchase API消耗产品。食用后可下次购买。如果产品是非消耗品或订阅产品,则无法再次购买该产品。

    查询所有已购买应用内商品的信息,包括消耗品、非消耗品和自动续订订阅。

    如果返回耗材信息,可能会因为某些异常导致耗材无法送达。在这种情况下,您的应用需要检查耗材是否已送达。如果没有,则应用需要交付它们并调用 consumeOwnedPurchase API 来消费它们。 如果返回非消耗品信息,则不需要消耗非消耗品。 如果返回订阅信息,则返回该用户在应用中已有的所有订阅关系。

    如果 purchaseState 为 0,则表示产品为 PURCHASED。

    如果 purchaseState 为 1,则表示产品为 CANCELED。

    如果 purchaseState 为 2,则表示产品为 PURCHASED。

    代码:

    public void checkUserOwnedTheProduct(final Context context) {
        OwnedPurchasesReq ownedPurchasesReq = new OwnedPurchasesReq();
        ownedPurchasesReq.setPriceType(productType);
        Task<OwnedPurchasesResult> task = Iap.getIapClient(context).obtainOwnedPurchases(ownedPurchasesReq);
        task.addOnSuccessListener(new OnSuccessListener<OwnedPurchasesResult>() {
            @Override
            public void onSuccess(OwnedPurchasesResult result) {
                // Obtain the execution result.
                if (result != null && result.getInAppPurchaseDataList() != null) {
                    for (int i = 0; i < result.getInAppPurchaseDataList().size(); i++) {
                        String inAppPurchaseData = result.getInAppPurchaseDataList().get(i);
                        String inAppSignature = result.getInAppSignature().get(i);
                        boolean success = CipherUtil.doCheck(inAppPurchaseData, inAppSignature, Key.getPublicKey());
                        if (success) {
                            try {
                                InAppPurchaseData inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseData);
                                int purchaseState = inAppPurchaseDataBean.getPurchaseState();                            
    
                            } catch (JSONException e) {
                            }
                        }
                    }
                } else {
                    if (productType == IapClient.PriceType.IN_APP_NONCONSUMABLE) {
                        ((HmsInAppPurchaseList) context).loadList();
                        return;
                    }
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof IapApiException) {
                    IapApiException apiException = (IapApiException) e;
                    Status status = apiException.getStatus();
                    int returnCode = apiException.getStatusCode();
                } else {
                    // Other external errors
                }
            }
        });
    }
    

    有关更多信息,您可以访问以下链接:

    应用内购买文章:

    客户端: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201255229704010231&fid=0101187876626530001

    服务器端: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201273064244120101&fid=0101187876626530001

    应用内购买 Github 链接:

    客户端: https://github.com/DTSE-India-Community/HMS-In-App-Purchase-Kit

    服务器端: https://github.com/DTSE-India-Community/Huawei-In-App-Purchase-And-Push-Kit-Server_Side-Implementation

    【讨论】:

      【解决方案2】:

      你得到的错误代码是 -1 在官方文档中,解决方案是这样描述的

      如果在请求购买过程中返回此错误码,建议您使用obtainOwnedPurchases接口检查用户是否购买了该产品。

      文档:https://developer.huawei.com/consumer/en/doc/development/HMS-References/iap-ExceptionHandlingAndGeneralErrorCodes-v4

      IAP 服务中的网络请求以异步方式处理。

      从检查服务是否可用到完成交易的过程按步骤处理。这些步骤必须按顺序执行。每个步骤都包含异常处理。

      如果某一步骤发生异常且未处理,则无法进行下一步。我的建议是遵循购买流程,仔细处理每个步骤的结果,以完成交易并确保良好的用户体验。

      请致电

      isEnvReady()
      

      确保每次购买时 IAP 环境都准备好进行购买。

      【讨论】:

        猜你喜欢
        • 2016-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-21
        • 1970-01-01
        相关资源
        最近更新 更多