getPurchases()NullPointerException异常初始化MSERVICE [英] getPurchases() NullPointerException initializing mService

查看:425
本文介绍了getPurchases()NullPointerException异常初始化MSERVICE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:请参阅下面我的解决方案我的答案

我收到尝试使用 getPurchases()来检查所有的项目时NullPointerException错误,我不知道为什么,因为我已经跟着的文档。我发现的文件有时可能产生误导,所以我在这里。

I'm receiving a NullPointerException error when trying to check owned items using getPurchases() and I'm not sure why as I've followed the documentation. I'm finding that the documentation can be misleading at times, so here I am.

我已经设置了应用内结算,这样它初始化没关系,我得到一个成功的消息。它被初始化后,我要检查用户是否有pviously购买项目(S)$ P $和显示基于结果的按钮。这里是我的code到目前为止以下是我的LogCat中。出现在try / catch语句开头的错误。

I've set up In-app billing such that it initializes okay and I get a success message. After it is initialized, I want to check if the user has previously purchased item(s) and display a button based on the result. Here is my code so far and below is my LogCat. The error appears at the beginning of the try/catch.

public class MainActivity extends Activity
{
    IabHelper mHelper;
    IInAppBillingService mService;
    private Button buyButton;
    AdView adView;

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

        adView = (AdView)this.findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder().build();
        adView.loadAd(adRequest);

        buyButton = (Button)findViewById(R.id.buyButton);

        String base64EncodedPublicKey = "public_key";

        mHelper = new IabHelper(this, base64EncodedPublicKey);

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

        bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);

        try
        {
            Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null); //This is line 66 referenced in LogCat error

            if(ownedItems.getInt("RESPONSE_CODE") == 0)
            {
                ArrayList ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
                ArrayList purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
                ArrayList signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
                String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");

                for(int i=0; i<purchaseDataList.size(); ++i)
                {
                    String purchaseData = (String) purchaseDataList.get(i);
                    String signature = (String) signatureList.get(i);
                    String sku = (String) ownedSkus.get(i);

                    Log.d("TEST", "Purchased: "+i+ " -> "+sku);
                }
            }
            else
            {
                Log.d("TEST", "Not Items Owned!");
            }
        }
        catch(RemoteException e)
        {
            //TODO: Error, unable to get owned items
            e.printStackTrace();
            Log.d("TEST", "owned items check failed: "+e);
        }           
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    ServiceConnection mServiceConn = new ServiceConnection() 
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            mService = IInAppBillingService.Stub.asInterface(service);
            Log.d("TEST", "mService ready to go!"); //This displays if try/catch above is commented out. Is it not waiting for mService to be initialized before running try/catch?     
        }

        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            mService = null;            
        }
    };

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        if(mServiceConn != null)
        {
            unbindService(mServiceConn);
        }
    }
}

而logcat的误差

And the Logcat errors

01-04 22:39:35.052: E/AndroidRuntime(32375): FATAL EXCEPTION: main
01-04 22:39:35.052: E/AndroidRuntime(32375): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.iab/com.test.iab.MainActivity}: java.lang.NullPointerException
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.os.Looper.loop(Looper.java:137)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread.main(ActivityThread.java:5041)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at java.lang.reflect.Method.invokeNative(Native Method)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at java.lang.reflect.Method.invoke(Method.java:511)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at dalvik.system.NativeStart.main(Native Method)
01-04 22:39:35.052: E/AndroidRuntime(32375): Caused by: java.lang.NullPointerException
01-04 22:39:35.052: E/AndroidRuntime(32375):    at com.test.iab.MainActivity.onCreate(MainActivity.java:66)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.Activity.performCreate(Activity.java:5104)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
01-04 22:39:35.052: E/AndroidRuntime(32375):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
01-04 22:39:35.052: E/AndroidRuntime(32375):    ... 11 more
01-04 22:39:35.083: E/GooglePlayServicesUtil(32375): The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.

我的猜测是,我不是正确初始化MSERVICE?但我不明白,如果我不能,因为我相信我做到了完全一样的文档轮廓。感谢您的指导。

My guess is that I'm not initializing mService correctly? But I don't understand if I'm not because I believe I did it exactly as the documentation outlines. Thanks for guidance.

推荐答案

这是不工作的原因是因为 onServiceConnected()不能保证被调用,直到的onCreate()完成。让我感动的try / catch语句code到 onServiceConnected()。我不知道这是不是最好的做法,但它似乎已经解决我的问题。这里是导致code的人与此相同的错误找到了自己。这是散发着按钮和采购逻辑。我建议<一href=\"http://www.techotopia.com/index.php/Integrating_Google_Play_In-app_Billing_into_an_Android_Application_%E2%80%93_A_Tutorial\"相对=nofollow>本教程为code。

The reason this was not working was because onServiceConnected() isn't guaranteed to be called until onCreate() completes. So I moved the try/catch code into onServiceConnected(). I'm not sure if this is best practice, but it seems to have fixed my issue. Here is the resulting code for anyone finding themselves with this same error. This is exuding button and purchasing logic. I recommend this tutorial for that code.

public class MainActivity extends Activity
{
    IabHelper mHelper;
    IInAppBillingService mService;
    static final String ITEM_SKU = "android.test.purchased";
    private Button buyButton;
    AdView adView;

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

        adView = (AdView)this.findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder().build();
        adView.loadAd(adRequest);

        buyButton = (Button)findViewById(R.id.buyButton);

        bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);      
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    ServiceConnection mServiceConn = new ServiceConnection() 
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            mService = IInAppBillingService.Stub.asInterface(service);
            Log.d("TEST", "mService ready to go!");
            checkOwnedItems();    
        }

        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            mService = null;            
        }
    };

    private void checkownedItems()
    {
        try
        {
            Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);

            if(ownedItems.getInt("RESPONSE_CODE") == 0)
            {
                ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
                ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
                ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
                String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");

                if(purchaseDataList.size() > 0)
                {
                    //Item(s) owned

                    for(int i=0; i<purchaseDataList.size(); ++i)
                    {
                        String purchaseData = purchaseDataList.get(i);
                        String signature = signatureList.get(i); //Note signatures do not appear to work with android.test.purchased (silly google)
                        String sku = ownedSkus.get(i);
                    }
                }
                else
                {
                    //Item(s) not owned

                    String base64EncodedPublicKey = "public_key";

                    mHelper = new IabHelper(this, base64EncodedPublicKey);

                    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
                    {
                        @Override
                        public void onIabSetupFinished(IabResult result)
                        {
                            if(!result.isSuccess())
                            {
                                Log.d("TEST", "In-app Billing setup failed: " + result);
                            }
                            else
                            {
                                Log.d("TEST", "In-app Billing is set up OK");
                            }
                        }
                    });
                }
            }
            else
            {
                //Error checking owned items
            }
        }
        catch(RemoteException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        if(mServiceConn != null)
        {
            unbindService(mServiceConn);
        }
    }
}

这篇关于getPurchases()NullPointerException异常初始化MSERVICE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆