应用内结算不起作用:" IAB助手设置不与QUOT;不与、不起作用、助手、IAB

2023-09-12 07:30:46 作者:兔子吃萝卜

我想包括我的应用程序和测试的目的在应用内计费,基于TrivialDrive为例,整个过程在应用内计费版本3(和实施IAB文件的未修改版本为在演示的UTIL子目录中)提供的,但它不为我工作 - 在LogCat中,应用程序将终止与错误之前,它给消息应用内计费误差:非法状态。操作(launchPurchaseFlow):IAB助手未设置的(右后startRegistered()函数已被解雇,并给了我日志消息。注册按钮,点击;启动升级购买流程)...

任何想法出了问题吗?

下面是我的code中的相关部分:

 包com.mytest;

(..)
进口com.mytest.iab.IabHelper; //从演示示例中的原件,未修改
进口com.mytest.iab.IabResult;
进口com.mytest.iab.Inventory;
进口com.mytest.iab.Purchase;

公共类Result3扩展活动实现OnClickListener {

私有静态最后字符串变量=BillingService有;

私人语境mContext;

布尔mIsRegistered = FALSE;

    //这个已经被设置为我的应用程序在发布服务器的控制台
静态最后弦乐IS_REGISTERED =myregistered;

静态最终诠释RC_REQUEST = 10001;

//将辅助对象
IabHelper mHelper;

/ **呼叫首先创建的活动时。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.result3);
    mContext =这一点;

    字符串base64En codedPublicKey =[我的公钥]; //(从我的应用程序发布者的控制台)

    //创建助手,通过它我们的背景和公钥来验证签名与
    Log.d(TAG,创建IAB的帮手。);
    mHelper =新IabHelper(这一点,base64En codedPublicKey);

    //启用调试日志(用于生产应用程序,你应该设置为false)。
    mHelper.enableDebugLogging(真正的);

    //开始安装。这是异步的,指定监听器
    一旦安装完成//将被调用。
    Log.d(TAG,开始安装。);
    mHelper.startSetup(新IabHelper.OnIabSetupFinishedListener(){
        公共无效onIabSetupFinished(IabResult结果){
            Log.d(TAG,安装完毕。);

            如果(!result.isSuccess()){
                抱怨(问题设置在应用内结算:+结果);
                返回;
            }

            //万岁,IAB是完全成立。现在,让我们的东西,我们自己的库存。
            Log.d(TAG,设置成功查询库存。);
            mHelper.queryInventoryAsync(mGotInventoryListener);
        }
    });

   //设置onClick的监听器
   findViewById(R.id.btnPurchase).setOnClickListener(本);
}

//监听器这就是所谓的,当我们完成查询,我们自己的项目
IabHelper.QueryInventoryFinishedListener mGotInventoryListener =新IabHelper.QueryInventoryFinishedListener(){
    公共无效onQueryInventoryFinished(IabResult结果,库存盘点){
        Log.d(TAG,查询库存结束了。);
        如果(result.isFailure()){
            抱怨(无法查询盘点:+结果);
            返回;
        }

        Log.d(TAG,查询库存是成功的。);

        //我们是否有premium升级?
        mIsRegistered = inventory.hasPurchase(IS_REGISTERED);
        Log.d(TAG,用户是+(mIsRegistered注册:别录));

        setWaitScreen(假);
        Log.d(TAG,初始库存查询完毕;使主界面。);
    }
};

//用户点击注册按钮。
私人无效startRegistered(){
    Log.d(TAG,注册按钮点击,推出升级购买流程。);
    setWaitScreen(真正的);
    mHelper.launchPurchaseFlow(这一点,IS_REGISTERED,RC_REQUEST,mPurchaseFinishedListener);
}

@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    Log.d(TAG,onActivityResult(+请求code +,+结果code +,+数据);

    //传递活动结果的帮手处理
    如果(!mHelper.handleActivityResult(要求code,因此code,数据)){
        //没有处理,因此处理它自己(在这里就是你会
        //执行不相关的应用内结算活动结果的任何处理..
        super.onActivityResult(要求code,因此code,数据);
    }
    其他 {
        Log.d(TAG,onActivityResult由IABUtil处理。);
    }
}

//回调时,购买完成后进行
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =新IabHelper.OnIabPurchaseFinishedListener(){
    公共无效onIabPurchaseFinished(IabResult结果,购购){
        Log.d(TAG,购买完成:+结果+,购买+购买);
        如果(result.isFailure()){
            //哦不一!
            抱怨(错误采购:+结果);
            setWaitScreen(假);
            返回;
        }

        Log.d(TAG,购买成功);

        如果(purchase.getSku()。等于(IS_REGISTERED)){
            Log.d(TAG,用户注册了..);
            警报(谢谢你。);
            mIsRegistered = TRUE;
            setWaitScreen(假);
        }
    }
};

//我们正在遭到破坏。重要的是要处理的帮手来了!
@覆盖
公共无效的onDestroy(){
    // 很重要:
    Log.d(TAG,销毁帮手。);
    如果(mHelper!= NULL)mHelper.dispose();
    mHelper = NULL;
}

投诉无效(字符串消息){
    Log.e(TAG,****注册错误:+消息);
    警报(错误:+消息);
}

无效setWaitScreen(布尔集){
    //只是一个虚拟的现在
}

警告无效(字符串消息){
    AlertDialog.Builder BLD =新AlertDialog.Builder(本);
    bld.setMessage(消息);
    bld.setNeutralButton(OK,NULL);
    Log.d(TAG,显示警告对话框:+消息);
    。bld.create()显示();
}

@覆盖
公共无效的onClick(视图v){
    开关(v.getId()){
    案例R.id.btnPurchase:
        startRegistered();
        打破;
    默认:
        打破;
    }
}
 

}

利用51拍牌助手来提高中标率,更可以一人拍多个标书不求人 科技频道

这是这里的logcat多行:

  1月十二号日至20日:06:36.701:D / dalvikvm(299):GC_FOR_MALLOC释放4262对象/ 308592字节84ms
1月12日至20号:06:36.701:D / webviewglue(299):nativeDestroy观点:0x2ea718
1月12日至20号:06:36.771:W / WebCore的(299):第一个布局后无法得到viewWidth
1月12日至20号:07:07.111:W / WebCore的(299):第一个布局后无法得到viewWidth
1月12日至20号:07:18.510:D / webviewglue(299):nativeDestroy观点:0x2dd458
1月12日至20号:07:18.510:D / dalvikvm(299):GC_FOR_MALLOC释放6042对象/ 50ms的中字节544504
1月12日至20号:07:18.530:D / webviewglue(299):nativeDestroy观点:0x2ea8d0
1月12日至20号:07:18.660:D / BillingService有(299):创建IAB帮手。
1月12日至20号:07:18.660:D / BillingService有(299):启动安装程序。
1月12日至20号:07:18.660:D / IabHelper(299):启动应用内结算的设置。
1月12日至20号:07:19.621:W / WebCore的(299):第一个布局后无法得到viewWidth
1月12日至20号:07:20.160:W / WebCore的(299):第一个布局后无法得到viewWidth
1月12日至20号:07:32.481:D / webviewglue(299):nativeDestroy观点:0x3f88e8
1月12日至20号:07:32.491:D / dalvikvm(299):GC_FOR_MALLOC释放对象5798/50毫秒中的字节513640
1月12日至20号:07:32.511:D / BillingService有(299):注册单击按钮;推出升级购买流程。
1月12日至20号:07:32.511:E / IabHelper(299):在应用内计费误差:非法状态操作(launchPurchaseFlow):IAB助手不成立。
1月12日至20号:07:32.521:D / AndroidRuntime(299):关闭虚拟机
1月12日至20号:07:32.521:W / dalvikvm(299):主题ID = 1:螺纹退出与未捕获的异常(组= 0x4001d800)
1月12日至20号:07:32.541:E / AndroidRuntime(299):致命异常:主要
1月12日至20号:07:32.541:E / AndroidRuntime(299):java.lang.IllegalStateException:IAB帮手不成立。无法执行操作:launchPurchaseFlow
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.test_ed.iab.IabHelper.checkSetupDone(IabHelper.java:673)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:315)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.test_ed.iab.IabHelper.launchPurchaseFlow(IabHelper.java:294)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.test_ed.Result3.startRegistered(Result3.java:157)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.test_ed.Result3.onClick(Result3.java:248)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.view.View.performClick(View.java:2408)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.view.View $ PerformClick.run(View.java:8816)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.os.Handler.handleCallback(Handler.java:587)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.os.Handler.dispatchMessage(Handler.java:92)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.os.Looper.loop(Looper.java:123)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在android.app.ActivityThread.main(ActivityThread.java:4627)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在java.lang.reflect.Method.invokeNative(本机方法)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在java.lang.reflect.Method.invoke(Method.java:521)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:868)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
1月12日至20号:07:32.541:E / AndroidRuntime(299):在dalvik.system.NativeStart.main(本机方法)
 

解决方案

有同样的问题在执行purchaseFlow功能。看看Activity类在谷歌的例子,特别是在方法保护无效onActivityResult(INT申请code,INT结果code,意图数据)。你可能忘了来实现这一点。此功能是至关重要的整个机制以无故障工作。

  @覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    Log.i(TAG,onActivityResult(+请求code +,+结果code +,+数据);

    //传递活动结果的帮手处理
    如果(!inappBillingHelper.handleActivityResult(要求code,因此code,数据)){
        super.onActivityResult(要求code,因此code,数据);
    }
    其他 {
        Log.i(TAG,onActivityResult由IABUtil处理。);
    }
}
 

编辑: 此外,该问题同样存在,当你有你的手机上的Gmail帐户(今天这件事发生在我身上)密码错误有关。当然,所有的Inapp计费功能,应在手机上进行测试,但我认为这是显而易见的。

I tried to include in-app billing in my app and for the purpose of testing, based the whole procedure on the "TrivialDrive" example for version 3 of in-app billing (and implementing the unmodified versions of the IAB files as supplied in the "util" subdirectory of the demo), but it doesn't work for me - on LogCat, just before the app terminates with an error, it gives the message "In-app billing error: Illegal state for operation (launchPurchaseFlow): IAB Helper is not set up." (right after the startRegistered() function has been fired and given me the LOG message "Register button clicked; launching purchase flow for upgrade.")...

Any idea what goes wrong here?

Here are the relevant parts of my code:

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;
    }
}

}

Here more lines from 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)

解决方案

Had the same issue while executing purchaseFlow function. Take a look at Activity class in the Google's example and specifically at the method protected void onActivityResult(int requestCode, int resultCode, Intent data). You probably forgot to implement this one. This function is vital for the whole mechanism to work without a glitch.

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

    // Pass on the activity result to the helper for handling
    if (!inappBillingHelper.handleActivityResult(requestCode, resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data);
    }
    else {
        Log.i(TAG, "onActivityResult handled by IABUtil.");
    }
}

EDIT: Additionally the problem also exists when you have wrong password associated with your gmail account on your phone (this happened on me today). Of course all the Inapp billing features should be tested on the phone, but that I think is obvious.