简体   繁体   中英

mService is becoming null after first time. In app bill android

I am using following code to find weather this user is premium user or not. Weather the user has purchase in app billing or not. But when i call this method isPremium(). it gives right result first time only but when i do it after first time, it always give wrong result. The mService variable of IInAppBillingService is null. Can some one tell me what could be reason of it. The code is as below.

public boolean isPremium() {
        boolean mIsPremium = false;
        Log.d(TAG, "::isPremium:" + "mService:"+mService);
        if(mService==null){
            return mIsPremium;
        }

        try {
            Bundle ownedItems = mService.getPurchases(3, getPackageName(),
                    "inapp", null);
            if (ownedItems != null) {
                int response = ownedItems.getInt("RESPONSE_CODE");
                if (response == 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 signature = null;
                        String purchaseData = (String) purchaseDataList.get(i);
                        if (signatureList != null)
                            signature = (String) signatureList.get(i);
                        String sku = (String) ownedSkus.get(i);
                        Log.d(TAG, "::isPremium:" + "sku:" + sku);
                        Log.d(TAG, "::isPremium:" + "purchaseData:"
                                + purchaseData);
                        Log.d(TAG, "::isPremium:" + "signature:" + signature);
                        if (sku.equalsIgnoreCase(SKU_PREMIUM)) {
                            Log.d(TAG, "::isPremium:" + "Already Purchased");
                            return true;
                        }

                        // do something with this purchase information
                        // e.g. display the updated list of products owned by
                        // user
                    }

                    // if continuationToken != null, call getPurchases again
                    // and pass in the token to retrieve more items
                }
            }
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return mIsPremium;
    }

The following is code to initialize service. where every time i come to service. i only get "onServiceConnected " log. and never got log ":onServiceDisconnected:"

ServiceConnection mServiceConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "::onServiceDisconnected:" + "");
            mService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "::onServiceConnected:" + "");
            mService = IInAppBillingService.Stub.asInterface(service);

        }
    };

So can some one give me idea what could be reason of mService becoming null after first time ? Should we only call it 1 time only ? is my service getting disconnected ? But i could not see it in my log.

According to what you said on your question:

But when I call this method isPremium(). it gives right result but when i do it after first time.

Your mService it is probably not binded the first time but it is at the second call. When you bind a service it takes some time to be established and that's probably why the second time you acces it your mService haves a value,and so do the isPremium.

If you look at this link(Extending the Binder class) , the example uses a boolean mBound to see if the service was binded as follows

On the service-side

public class IInAppBillingService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();


    public class LocalBinder extends Binder {
        IInAppBillingService getService() {
        // Return this instance of IInAppBillingService so clients can call public methods
        return IInAppBillingService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /** method for clients */
    public Bundle getPurchases(...) {
      //...
    }
}

On the activity-side

public class BindingActivity extends Activity {
    IInAppBillingService mService;
    boolean mBound = false;

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

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to IInAppBillingService
        Intent intent = new Intent(this, IInAppBillingService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }


    public void doStuff(View v) {
        if (mBound) {
            if(isPremium()){
                 //...
            }
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
             IBinder service) {
            // We've bound to IInAppBillingService, cast the IBinder and get IInAppBillingServiceinstance
            //The connection has been established
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            //You can use a boolean or you can call to isPremium if you are going to use it once, depends of your scenario
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

You have only posted the isPremium function, but not the way you initialize your mService. If you have not extended the binder class on the link above you can find differents ways, one should be the same that you are using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM