26

アプリ内課金のバージョン 3 の「TrivialDrive」の例に基づいて、テストの目的でアプリ内課金をアプリに含めようとしました (および、デモの「util」サブディレクトリ)、しかしそれは私にとってはうまくいきません - LogCat では、アプリがエラーで終了する直前に、「アプリ内課金エラー:操作の不正な状態 (launchPurchaseFlow): IAB 」というメッセージが表示されます。ヘルパーが設定されていません。」 (startRegistered() 関数が起動された直後に、「登録ボタンがクリックされました。アップグレードの購入フローを開始しています。」というログ メッセージが表示されました。)...

ここで何がうまくいかないのですか?

私のコードの関連部分は次のとおりです。

package com.mytest;

(..)
import com.mytest.iab.IabHelper; // the originals from the demo example, unmodified
import com.mytest.iab.IabResult;
import com.mytest.iab.Inventory;
import com.mytest.iab.Purchase;

public class Result3 extends Activity implements OnClickListener {

private static final String TAG = "BillingService";

private Context mContext;

boolean mIsRegistered = false;

    // this has already been set up for my app at the publisher's console
static final String IS_REGISTERED = "myregistered";

static final int RC_REQUEST = 10001;

// The helper object
IabHelper mHelper; 

/** Call when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.result3);
    mContext = this;

    String base64EncodedPublicKey = "[my public key]"; // (from publisher's console for my app)

    // Create the helper, passing it our context and the public key to verify signatures with
    Log.d(TAG, "Creating IAB helper.");
    mHelper = new IabHelper(this, base64EncodedPublicKey);

    // enable debug logging (for a production application, you should set this to false).
    mHelper.enableDebugLogging(true);

    // Start setup. This is asynchronous and the specified listener
    // will be called once setup completes.
    Log.d(TAG, "Starting setup.");
    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) {
            Log.d(TAG, "Setup finished.");

            if (!result.isSuccess()) {
                complain("Problem setting up in-app billing: " + result);
                return;
            }

            // Hooray, IAB is fully set up. Now, let's get an inventory of stuff we own.
            Log.d(TAG, "Setup successful. Querying inventory.");
            mHelper.queryInventoryAsync(mGotInventoryListener);
        }
    });

   // Set the onClick listeners
   findViewById(R.id.btnPurchase).setOnClickListener(this);
}

// Listener that's called when we finish querying the items we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Log.d(TAG, "Query inventory finished.");
        if (result.isFailure()) {
            complain("Failed to query inventory: " + result);
            return;
        }

        Log.d(TAG, "Query inventory was successful.");

        // Do we have the premium upgrade?
        mIsRegistered = inventory.hasPurchase(IS_REGISTERED);
        Log.d(TAG, "User is " + (mIsRegistered ? "REGISTERED" : "NOT REGISTERED"));

        setWaitScreen(false);
        Log.d(TAG, "Initial inventory query finished; enabling main UI.");
    }
};      

// User clicked the "Register" button.
private void startRegistered() {
    Log.d(TAG, "Register button clicked; launching purchase flow for upgrade.");
    setWaitScreen(true);
    mHelper.launchPurchaseFlow(this, IS_REGISTERED, RC_REQUEST, mPurchaseFinishedListener);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

    // Pass on the activity result to the helper for handling
    if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
        // not handled, so handle it ourselves (here's where you'd
        // perform any handling of activity results not related to in-app billing..
        super.onActivityResult(requestCode, resultCode, data);
    }
    else {
        Log.d(TAG, "onActivityResult handled by IABUtil.");
    }
}

// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
        if (result.isFailure()) {
            // Oh noes!
            complain("Error purchasing: " + result);
            setWaitScreen(false);
            return;
        }

        Log.d(TAG, "Purchase successful.");

        if (purchase.getSku().equals(IS_REGISTERED)) {
            Log.d(TAG, "User has registered..");
            alert("Thank you.");
            mIsRegistered = true;
            setWaitScreen(false);
        }
    }
};

// We're being destroyed. It's important to dispose of the helper here!
@Override
public void onDestroy() {
    // very important:
    Log.d(TAG, "Destroying helper.");
    if (mHelper != null) mHelper.dispose();
    mHelper = null;
}

void complain(String message) {
    Log.e(TAG, "**** Register Error: " + message);
    alert("Error: " + message);
}

void setWaitScreen(boolean set) {
    // just a dummy for now
}

void alert(String message) {
    AlertDialog.Builder bld = new AlertDialog.Builder(this);
    bld.setMessage(message);
    bld.setNeutralButton("OK", null);
    Log.d(TAG, "Showing alert dialog: " + message);
    bld.create().show();
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btnPurchase:
        startRegistered();
        break;
    default:
        break;
    }
}

}

ここにLogcatからのより多くの行:

12-20 01:06:36.701: D/dalvikvm(299): GC_FOR_MALLOC freed 4262 objects / 308592 bytes in 84ms
12-20 01:06:36.701: D/webviewglue(299): nativeDestroy view: 0x2ea718
12-20 01:06:36.771: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:07.111: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:18.510: D/webviewglue(299): nativeDestroy view: 0x2dd458
12-20 01:07:18.510: D/dalvikvm(299): GC_FOR_MALLOC freed 6042 objects / 544504 bytes in 50ms
12-20 01:07:18.530: D/webviewglue(299): nativeDestroy view: 0x2ea8d0
12-20 01:07:18.660: D/BillingService(299): Creating IAB helper.
12-20 01:07:18.660: D/BillingService(299): Starting setup.
12-20 01:07:18.660: D/IabHelper(299): Starting in-app billing setup.
12-20 01:07:19.621: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:20.160: W/webcore(299): Can't get the viewWidth after the first layout
12-20 01:07:32.481: D/webviewglue(299): nativeDestroy view: 0x3f88e8
12-20 01:07:32.491: D/dalvikvm(299): GC_FOR_MALLOC freed 5798 objects / 513640 bytes in 50ms
12-20 01:07:32.511: D/BillingService(299): Register button clicked; launching purchase flow for upgrade.    
12-20 01:07:32.511: E/IabHelper(299): In-app billing error: Illegal state for operation (launchPurchaseFlow): IAB helper is not set up.
12-20 01:07:32.521: D/AndroidRuntime(299): Shutting down VM
12-20 01:07:32.521: W/dalvikvm(299): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-20 01:07:32.541: E/AndroidRuntime(299): FATAL EXCEPTION: main
12-20 01:07:32.541: E/AndroidRuntime(299): java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: launchPurchaseFlow
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.test_ed.iab.IabHelper.checkSetupDone(IabHelper.java:673)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:315)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:294)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.test_ed.Result3.startRegistered(Result3.java:157)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.test_ed.Result3.onClick(Result3.java:248)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.view.View.performClick(View.java:2408)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.view.View$PerformClick.run(View.java:8816)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.os.Handler.handleCallback(Handler.java:587)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.os.Handler.dispatchMessage(Handler.java:92)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.os.Looper.loop(Looper.java:123)
12-20 01:07:32.541: E/AndroidRuntime(299):  at android.app.ActivityThread.main(ActivityThread.java:4627)
12-20 01:07:32.541: E/AndroidRuntime(299):  at java.lang.reflect.Method.invokeNative(Native Method)
12-20 01:07:32.541: E/AndroidRuntime(299):  at java.lang.reflect.Method.invoke(Method.java:521)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-20 01:07:32.541: E/AndroidRuntime(299):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-20 01:07:32.541: E/AndroidRuntime(299):  at dalvik.system.NativeStart.main(Native Method)
4

5 に答える 5

4

まったく同じ問題に頭を悩ませました。IabHelper-Setup が開始されますが、その後何も起こりません。また、アプリ内購入をクリックすると、発生したのとまったく同じエラーが返されます。

これが私が理解したことです:私はEclipseのエミュレーターのみを使用しました。特定の Google Play バージョンが必要であると読んだ後、テスト エミュレーション ドライブで Google Play が完全に欠落していることに気付きました。

その後、実際の電話を使用すると、問題なく動作しました。そのため、まだその問題で立ち往生している場合は、実際のデバイスを使用してみてください (利用可能なデバイスがある場合)。これでうまくいくはずです。

于 2013-02-12T11:22:45.650 に答える