在应用内结算后,Bad Base64输入字符在0:60(十进制)崩溃

时间:2015-02-16 05:22:18

标签: in-app-purchase in-app-billing

我一直关注Techotopia in-app billing tutorial 并继续使我的发布版本崩溃并出现以下错误

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10001, result=-1, data=Intent { (has extras) }} to activity {com.spudproducts.inappbilling/com.spudproducts.inappbilling.InAppBillingActivity}: java.lang.IllegalArgumentException: com.spudproducts.inappbilling.util.Base64DecoderException: Bad Base64 input character at 0: 60(decimal)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3556)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3599)
at android.app.ActivityThread.access$1300(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5274)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalArgumentException: com.spudproducts.inappbilling.util.Base64DecoderException: Bad Base64 input character at 0: 60(decimal)
at com.spudproducts.inappbilling.util.Security.generatePublicKey(Security.java:106)
at com.spudproducts.inappbilling.util.Security.verifyPurchase(Security.java:77)
at com.spudproducts.inappbilling.util.IabHelper.handleActivityResult(IabHelper.java:479)
at com.spudproducts.inappbilling.InAppBillingActivity.onActivityResult(InAppBillingActivity.java:72)
at android.app.Activity.dispatchActivityResult(Activity.java:6179)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3552)
... 10 more
Caused by: com.spudproducts.inappbilling.util.Base64DecoderException: Bad Base64 input character at 0: 60(decimal)
at com.spudproducts.inappbilling.util.Base64.decode(Base64.java:546)
at com.spudproducts.inappbilling.util.Base64.decode(Base64.java:474)
at com.spudproducts.inappbilling.util.Base64.decode(Base64.java:420)
at com.spudproducts.inappbilling.util.Security.generatePublicKey(Security.java:96)    

应用程序以前在调试模式下运行正常(使用android.test.purchased),但现在崩溃尽管我还原了任何更改,但错误日志

02-16 16:09:22.832  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Starting async operation: launchPurchaseFlow
02-16 16:09:22.833  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Constructing buy intent for android.test.purchased, item type: inapp
02-16 16:09:22.906  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Launching buy intent for android.test.purchased. Request code: 10001
02-16 16:09:28.687  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Ending async operation: launchPurchaseFlow
02-16 16:09:28.688  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Successful resultcode from purchase activity.
02-16 16:09:28.688  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Purchase data: {"packageName":"com.spudproducts.payforatap","orderId":"transactionId.android.test.purchased","productId":"android.test.purchased","developerPayload":"mypurchasetoken","purchaseTime":0,"purchaseState":0,"purchaseToken":"inapp:com.spudproducts.payforatap:android.test.purchased"}
02-16 16:09:28.688  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Data signature:
02-16 16:09:28.688  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Extras: Bundle[{INAPP_PURCHASE_DATA={"packageName":"com.spudproducts.payforatap","orderId":"transactionId.android.test.purchased","productId":"android.test.purchased","developerPayload":"mypurchasetoken","purchaseTime":0,"purchaseState":0,"purchaseToken":"inapp:com.spudproducts.payforatap:android.test.purchased"}, INAPP_DATA_SIGNATURE=, RESPONSE_CODE=0}]
02-16 16:09:28.688  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Expected item type: inapp
02-16 16:09:28.694  22976-22976/com.spudproducts.payforatap E/IABUtil/Security﹕ Purchase verification failed: missing data.
02-16 16:09:28.694  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Purchase signature successfully verified.
02-16 16:09:28.695  22976-22976/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Starting async operation: refresh inventory
02-16 16:09:28.702  22976-23140/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Querying owned items, item type: inapp
02-16 16:09:28.702  22976-23140/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Package name: com.spudproducts.payforatap
02-16 16:09:28.702  22976-23140/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Calling getPurchases with continuation token: null
02-16 16:09:28.749  22976-23140/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Owned items response: 0
02-16 16:09:28.749  22976-23140/com.spudproducts.payforatap E/IABUtil/Security﹕ Purchase verification failed: missing data.
02-16 16:09:28.749  22976-23140/com.spudproducts.payforatap D/com.spudproducts.inappbilling﹕ Sku is owned: android.test.purchased
02-16 16:09:28.756  22976-22976/com.spudproducts.payforatap I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@ff8bddb time:63182857
02-16 16:09:28.756  22976-23140/com.spudproducts.payforatap E/IABUtil/Security﹕ Base64 decoding failed.
02-16 16:09:28.763  22976-23140/com.spudproducts.payforatap E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-4554
    Process: com.spudproducts.payforatap, PID: 22976
    java.lang.IllegalArgumentException: com.spudproducts.inappbilling.util.Base64DecoderException: Bad Base64 input character at 0: 60(decimal)

以下是我使用的代码,直接从教程开始,我花了好几天时间甚至重新做了整个项目以努力修复它,但面临同样的问题

InAppBillingActivity.java

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

import com.spudproducts.inappbilling.util.IabHelper;
import com.spudproducts.inappbilling.util.IabResult;
import com.spudproducts.inappbilling.util.Inventory;
import com.spudproducts.inappbilling.util.Purchase;


public class InAppBillingActivity extends Activity {


    private static final String TAG =
            "com.spudproducts.inappbilling";
    IabHelper mHelper;
    static final String ITEM_SKU = "android.test.purchased";
    //static final String ITEM_SKU = "com.example.buttonclick";

    private Button clickButton;
    private Button buyButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_in_app_billing);

        buyButton = (Button)findViewById(R.id.buyButton);
        clickButton = (Button)findViewById(R.id.clickButton);
        clickButton.setEnabled(false);

        String base64EncodedPublicKey =
                "<keyWhichWasCheckedABillionTimes>";

        mHelper = new IabHelper(this, base64EncodedPublicKey);

        mHelper.startSetup(new
                                   IabHelper.OnIabSetupFinishedListener() {
                                       public void onIabSetupFinished(IabResult result)
                                       {
                                           if (!result.isSuccess()) {
                                               Log.d(TAG, "In-app Billing setup failed: " +
                                                       result);
                                           } else {
                                               Log.d(TAG, "In-app Billing is set up OK");
                                               mHelper.enableDebugLogging(true, TAG);
                                           }
                                       }
                                   });
    }


    public void buttonClicked (View view)
    {
        clickButton.setEnabled(false);
        buyButton.setEnabled(true);
    }

    public void buyClick(View view) {
        mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
                mPurchaseFinishedListener, "mypurchasetoken");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent data)
    {
        if (!mHelper.handleActivityResult(requestCode,
                resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                consumeItem();
                buyButton.setEnabled(false);
            }

        }
    };


    public void consumeItem() {
        mHelper.queryInventoryAsync(mReceivedInventoryListener);
    }

    IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
            = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result,
                                             Inventory inventory) {

            if (result.isFailure()) {
                // Handle failure
            } else {
                mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                        mConsumeFinishedListener);
            }
        }
    };

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
            new IabHelper.OnConsumeFinishedListener() {
                public void onConsumeFinished(Purchase purchase,
                                              IabResult result) {

                    if (result.isSuccess()) {
                        clickButton.setEnabled(true);
                    } else {
                        // handle error
                    }
                }
            };

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mHelper != null) mHelper.dispose();
        mHelper = null;
    }

}

修改后的Security.java中的verifyPurchase已在教程

中修复
public static boolean verifyPurchase(String base64PublicKey,
                                         String signedData, String signature) {
        if (TextUtils.isEmpty(signedData) ||
                TextUtils.isEmpty(base64PublicKey) ||
                TextUtils.isEmpty(signature)) {
            Log.e(TAG, "Purchase verification failed: missing data.");
            if (BuildConfig.DEBUG) {
                return true;
            }
            return false;
        }

        PublicKey key = Security.generatePublicKey(base64PublicKey);
        return Security.verify(key, signedData, signature);
    }

我已经尝试到处寻找修复程序,并试图修改代码堆(但在回到教程代码之前)

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:0)

我正在从Playstore复制许可证密钥,并将其粘贴到源代码中的双引号之间。

在双引号之间粘贴字符串时,Android Studio会自动放置转义序列字符。

所以解决方案是先粘贴许可证密钥,然后在其周围加上双引号