在应用程序计费中,待处理意图和切换活动存在问题

发布于 2024-11-15 14:39:12 字数 6085 浏览 9 评论 0原文

好吧,我已经尝试解决这个问题好几天了,我不会来这里寻找有人为我做我的工作,因为我一直在排除故障并修复了 LogCat 中的每一条错误消息。我正在使用 Andengine 开发一款 Android 游戏(这可能是问题的一部分,因此熟悉它可能会有所帮助)。我没有做任何太花哨的事情,我的游戏活动都是单一场景,没有任何物理或类似的东西,只是一堆精灵和纹理。我还将 Andengine 用于游戏中的所有其他活动,因为我发现它是设置具有图形吸引力的屏幕的一种非常简单的方法。我的应用内商店就是这样的屏幕之一,用户可以在其中购买关卡包和新精灵。这一切的计费部分都运行得很好,购买进入市场,那里没有什么太复杂的...

当用户单击购买时,市场屏幕会弹出并加载他们选择的产品(这些是真实的产品,而不是尽管游戏尚未发布,但 Android 已进行测试)。无论我使用“Android 2.0”实现(它是游戏堆栈的一部分)还是“Android 1.6”实现(它是其自身堆栈的一部分),市场屏幕都会在当前活动上方弹出。我更喜欢使用 Android 2.0 实现,但如果我只能让 1.6 运行,我会采用它。所以无论如何,当用户使用后退按钮取消购买或使用信用卡完成购买时,就会出现问题,这两种情况都会导致市场屏幕消失,并且应用程序启动一个只是黑屏的新活动(最终会导致出并导致强制关闭)。购买过程正常,但用户没有获得产品,因为在我们到达更改用户在游戏中的物品的代码之前游戏强制退出。现在,对于一些代码,我使用了本教程(http://www.anddev.org/advanced-tutorials-f21/simple-inapp-billing- payment-t52060.html),而没有进行任何更改。 BillingHelper 类是最重要的,因为它包含 requestPurchase() 方法和 startBuyPageActivity() 方法。我从我的 StoreFront 活动中调用请求购买,如下所示:

            BillingHelper.requestPurchase(StoreFront.this, itemID); 

在 StoreFront 的 onCreate 中,我有这些东西(正如 tut 告诉的那样):

        startService(new Intent(mContext, BillingService.class));
    BillingHelper.setCompletedHandler(mTransactionHandler);

...

//some handler that billing needs
public Handler mTransactionHandler = new Handler(){
    public void handleMessage(android.os.Message msg) {
        Log.i(TAG, "Transaction complete");
        Log.i(TAG, "Transaction status: "+BillingHelper.latestPurchase.purchaseState);
        Log.i(TAG, "Item purchased is: "+BillingHelper.latestPurchase.productId);

        if(BillingHelper.latestPurchase.isPurchased()){
            //TODO do something here if we've completed our latest purchase,
            //this should be with the status bar notifications and
            //saved preferences
        }
    };

};

所以我认为问题不在那里。以下是 BillingHelper 的相关部分

protected static void requestPurchase(Context activityContext, String itemId){
    if (amIDead()) {
        return;
    }
    Log.i(TAG, "requestPurchase()");
    Bundle request = makeRequestBundle("REQUEST_PURCHASE");
    request.putString("ITEM_ID", itemId);
    try {
        Bundle response = mService.sendBillingRequest(request);

        //The RESPONSE_CODE key provides you with the status of the request
        Integer responseCodeIndex   = (Integer) response.get("RESPONSE_CODE");
        //The PURCHASE_INTENT key provides you with a PendingIntent, which you can use to launch the checkout UI
        PendingIntent pendingIntent = (PendingIntent) response.get("PURCHASE_INTENT");
        //The REQUEST_ID key provides you with a unique request identifier for the request
        Long requestIndentifier     = (Long) response.get("REQUEST_ID");
        Log.i(TAG, "current request is:" + requestIndentifier);
        C.ResponseCode responseCode = C.ResponseCode.valueOf(responseCodeIndex);
        Log.i(TAG, "REQUEST_PURCHASE Sync Response code: "+responseCode.toString());

        startBuyPageActivity(pendingIntent, new Intent(), activityContext);
    } catch (RemoteException e) {
        Log.e(TAG, "Failed, internet error maybe", e);
        Log.e(TAG, "Billing supported: "+isBillingSupported());
    }
}

,我尝试使用各种参数作为“ActivityContext”从 StoreFront 调用,例如 StoreFront.this、getApplicationContext()、其他地方的静态上下文存储、其他地方存储的静态 Activity、getBaseContext() 任何我想要的东西。可能会想到...

这是其他相关活动

private static void startBuyPageActivity(PendingIntent pendingIntent, Intent intent, Context context){
    //android 1.6 method
    try {
        pendingIntent.send(context, 0, intent);         
    } catch (CanceledException e){
        Log.e(TAG, "startBuyPageActivity CanceledException");
    }
}

没什么花哨的,我只是希望用户在购买商品或在此过程中按下返回时返回到我的任何各种活动(最好是 StoreFront)。请帮忙!

编辑:我想要任何可能的解决方案,以允许应用内计费在购买完成后返回到我的应用程序,即使是最混乱的解决方案。

编辑

logcat 和方法调用了问题所在:

  "BillingService Starting", 
  BillingHelper.setCompletedHandler(), 
  StoreFront.onStart() called, 
  StoreFront.onResume() called, 
  "BillingService Service starting with onCreate", 
  "BillingService Market Billing Service Successfully Bound", 
  "BillingService Market Billing Service Connected", 
  BillingHelper.instantiateHelper(), 
  then this is where I actually click the buy button in the store (all of that runs just when opening StoreFront):
  BillingHelper.setCompletedHandler(), 
  BillingHelper.isBillingSupported(), 
  BillingHelper.amIDead(), 
  BillingHelper.makeRequestBundle(), 
  "BillingService isBillingSupported response was: RESULT OK", 
  BillingHelper.requestPurchase(), 
  BillingHelper.amIDead(), 
  "BillingService requestPurchase()", 
  BillingHelper.makeRequestBundle(), 
  "BillingService current request is ......", 
  "BillingService REQUEST PURCHASE Sync Response code: RESULT OK", 
  BillingHelper.startBuyPageActivity(), 
  "BillingService Recieved action: com.android.vending.billing.RESPONSE CODE", 
  "BillingService checkResponseCode got requestID..."
  "BillingService checkResponseCode go responseCode RESULT ERROR" 
  (this is because I can't purchase on this device), 
  and then I get an Error message saying: "E 32427 Surface surface (identity=5925) is invalid, err=-19 (No such device)" and from there nothing works anymore. 

我还在另一部手机上对此进行了测试(与我合作的另一位开发人员,他实际上可以在其中购买东西,但仍然会出现黑屏错误)并且他也从未收到您在评论中提到的处理程序消息

编辑:如果我必须猜测错误在哪里,我会说是这个

06-16 11:20:23.635: DEBUG/dalvikvm(3807): GC_EXPLICIT freed 53K, 45% free 3710K/6663K, external 1K/513K, paused 102ms
06-16 11:20:23.885: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Adreno200-EGL(3807): egliSwapWindowSurface: unable to dequeue native buffer

注意中断的异常是 Andengine 库所期望的,所以这是一个红鲱鱼。

另外(我希望这里允许这样做)我将为解决方案提供贝宝奖励。如果这违反了 SO 的条款,那么只需删除此行,请不要关闭此问题。

Ok so I have been trying to fix this for days, and I'm not coming here looking for someone to do my work for me as I have been troubleshooting and fixed every single error message in the LogCat. I am developing an Android game using Andengine (this might be part of the problem so being familiar with it could help). I'm not doing anything too fancy, my game activities are all single scene and don't have any Physics or anything like that, just a bunch of sprites and textures. I also used Andengine for all of the other activities in my game because I find it to be a very easy way to set up graphically appealing screens. One such screen is my in-app store, where users can buy levelpacks and new sprites. The billing part of this all works great, the purchases go through to the Market and there's nothing too complicated there...

When the user clicks buy, the market screen pops up and loads the product they have selected (these are real products, not the android tests although the game is not published). The Market screen pops up over the current activity, regardless of whether I use the "Android 2.0" implementation where it is part of the game's stack or I use the "Android 1.6" implementation and it is part of its own stack. I would prefer to use the Android 2.0 implementation but if I can only get the 1.6 to work I will take that. So anyway, the problem arises when the user either cancels the purchase using the back button or completes the purchase with a credit card, both result in the market screen disappearing and the app starting a new activity that is just a black screen (which eventually times out and causes a force close). The purchase goes through OK but the user does not get the product because the game force quits before we get to the code to change the user's items in the game. Now for some code, I used this tutorial (http://www.anddev.org/advanced-tutorials-f21/simple-inapp-billing-payment-t52060.html) without changing much of anything. The BillingHelper class is most important, as it holds the requestPurchase() method and the startBuyPageActivity() methods. I call request purchase from my StoreFront activity like this:

            BillingHelper.requestPurchase(StoreFront.this, itemID); 

and in the onCreate of the StoreFront I have this stuff (as told to do by the tut):

        startService(new Intent(mContext, BillingService.class));
    BillingHelper.setCompletedHandler(mTransactionHandler);

...

//some handler that billing needs
public Handler mTransactionHandler = new Handler(){
    public void handleMessage(android.os.Message msg) {
        Log.i(TAG, "Transaction complete");
        Log.i(TAG, "Transaction status: "+BillingHelper.latestPurchase.purchaseState);
        Log.i(TAG, "Item purchased is: "+BillingHelper.latestPurchase.productId);

        if(BillingHelper.latestPurchase.isPurchased()){
            //TODO do something here if we've completed our latest purchase,
            //this should be with the status bar notifications and
            //saved preferences
        }
    };

};

So I don't think the problem lies there. Here are the relevant parts of BillingHelper

protected static void requestPurchase(Context activityContext, String itemId){
    if (amIDead()) {
        return;
    }
    Log.i(TAG, "requestPurchase()");
    Bundle request = makeRequestBundle("REQUEST_PURCHASE");
    request.putString("ITEM_ID", itemId);
    try {
        Bundle response = mService.sendBillingRequest(request);

        //The RESPONSE_CODE key provides you with the status of the request
        Integer responseCodeIndex   = (Integer) response.get("RESPONSE_CODE");
        //The PURCHASE_INTENT key provides you with a PendingIntent, which you can use to launch the checkout UI
        PendingIntent pendingIntent = (PendingIntent) response.get("PURCHASE_INTENT");
        //The REQUEST_ID key provides you with a unique request identifier for the request
        Long requestIndentifier     = (Long) response.get("REQUEST_ID");
        Log.i(TAG, "current request is:" + requestIndentifier);
        C.ResponseCode responseCode = C.ResponseCode.valueOf(responseCodeIndex);
        Log.i(TAG, "REQUEST_PURCHASE Sync Response code: "+responseCode.toString());

        startBuyPageActivity(pendingIntent, new Intent(), activityContext);
    } catch (RemoteException e) {
        Log.e(TAG, "Failed, internet error maybe", e);
        Log.e(TAG, "Billing supported: "+isBillingSupported());
    }
}

Which I have tried calling from StoreFront with a variety of arguments as "ActivityContext" such as StoreFront.this, getApplicationContext(), a static context store elsewhere, a static Activity stored elsewhere, getBaseContext() anything I could possible think of...

Here is the other relevant activity

private static void startBuyPageActivity(PendingIntent pendingIntent, Intent intent, Context context){
    //android 1.6 method
    try {
        pendingIntent.send(context, 0, intent);         
    } catch (CanceledException e){
        Log.e(TAG, "startBuyPageActivity CanceledException");
    }
}

Nothing fancy, I just want the user to be returned to any of my various activities (preferably StoreFront) when they either buy the item or press back during the process. HELP PLEASE!

Edit: I want any possible solution to allow in-app billing to return to my app after the purchase is complete, even the messiest solution.

EDIT

A logcat and method calls of what the issue:

  "BillingService Starting", 
  BillingHelper.setCompletedHandler(), 
  StoreFront.onStart() called, 
  StoreFront.onResume() called, 
  "BillingService Service starting with onCreate", 
  "BillingService Market Billing Service Successfully Bound", 
  "BillingService Market Billing Service Connected", 
  BillingHelper.instantiateHelper(), 
  then this is where I actually click the buy button in the store (all of that runs just when opening StoreFront):
  BillingHelper.setCompletedHandler(), 
  BillingHelper.isBillingSupported(), 
  BillingHelper.amIDead(), 
  BillingHelper.makeRequestBundle(), 
  "BillingService isBillingSupported response was: RESULT OK", 
  BillingHelper.requestPurchase(), 
  BillingHelper.amIDead(), 
  "BillingService requestPurchase()", 
  BillingHelper.makeRequestBundle(), 
  "BillingService current request is ......", 
  "BillingService REQUEST PURCHASE Sync Response code: RESULT OK", 
  BillingHelper.startBuyPageActivity(), 
  "BillingService Recieved action: com.android.vending.billing.RESPONSE CODE", 
  "BillingService checkResponseCode got requestID..."
  "BillingService checkResponseCode go responseCode RESULT ERROR" 
  (this is because I can't purchase on this device), 
  and then I get an Error message saying: "E 32427 Surface surface (identity=5925) is invalid, err=-19 (No such device)" and from there nothing works anymore. 

Also I have tested this on a different phone (another developer I am working with, who can actually buy things in it but still gets the black screen error) and he never got the Handler messages you mentioned in your comment either

Edit: if I had to guess where the error is, I'd say it's this

06-16 11:20:23.635: DEBUG/dalvikvm(3807): GC_EXPLICIT freed 53K, 45% free 3710K/6663K, external 1K/513K, paused 102ms
06-16 11:20:23.885: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Adreno200-EGL(3807): egliSwapWindowSurface: unable to dequeue native buffer

Note that the interrupted exception is expected by the Andengine library so that is a red herring.

Also (I hope this is allowed on here) I will offer paypal reward for a solution. If this is against the Terms of SO then just delete this line, please don't close this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坚持沉默 2024-11-22 14:39:12

我可能知道出了什么问题,并且我要给你做一个测试。用户取消购买或完成购买后,购买屏幕会运行结束调用。对我来说,由于某种原因,结束调用逐渐进入当前正在运行的活动并且(关闭???它)。

以下是日志中的相关行:

06-16 11:20:22.774: WARN/ActivityManager(132): Duplicate finish request for HistoryRecord{40ace828 com.android.vending/.billing.InAppBuyPageActivity}

我想我在代码中修复了这个问题问题是我记不清我到底做了什么(也许没有在我的购买完整处理程序中调用完成......)

我对 Andgen 一无所知,但是如果对主要 Andgen 活动调用完成调用会发生什么?我想它会停止执行,你可能会遇到黑屏和应用程序崩溃。

因此,为了测试这一点,请为您的购买页面创建一个单独的活动。不需要太复杂——也许启动后只需要购买一种罐装产品即可。运行你的代码,看看它是否仍然给你带来厄运的黑屏。我敢打赌:它可能会退出活动回到您的游戏,但我认为它会起作用。

希望这有帮助,祝你好运!

I may know what's wrong and I have a test for you to do. The buy screen runs a finish call after the user cancels the purchase or completes the purchase. For me for some reason the finish call was drifting down into the currently running activity and (CLOSING??? it).

Here's the relevant line from the log:

06-16 11:20:22.774: WARN/ActivityManager(132): Duplicate finish request for HistoryRecord{40ace828 com.android.vending/.billing.InAppBuyPageActivity}

I think I fixed this in my code problem is that I can't remember exactly what I did (maybe didn't call finish in my purchase complete handler...)

I don't know anything about Andgen, but what would happen if a finish call got called on the main Andgen activity? I'd imagine it would stop execution and you might get a black screen and an app crash.

So to test this, create a separate activity for you buy page. Doesn't need to be complicated - maybe have it just buy one canned product after it starts up. Run your code and see if it still gives you the black screen of doom. My bet: it may exit out of the activity back to your game but I think it'll work.

Hope this helps and Good Luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文