Have looked at this link :
onIabPurchaseFinished never called.
and ....
I have looked at the following link in so - which is the exact issue that I am facing :
IabHelper PurchaseFinishedListener
The issue stated by 'kevinl' in one of the answers in the above second link - is the issue I have i.e.
I have the 'onActivityResult' coded in my activity
The control does come into this method - but yet - it does not go to - onIabPurchaseFinished
I am invoking the Purchase flow as below:
public void onClickIap(View v) {
if(isAlreadyPurchased){
Log.d(TAG, "In onClickIap >>> The app is purchased ");
}else{
Log.d(TAG, "In onClickIap >>> The app is NOT purchased: ");
/** we need to check if this item was purchased from google store details **/
/** makes synchronous call -return control to callback method in listener **/
/** this is the heart of in app - where all the activity starts **/
mHelper.launchPurchaseFlow(this, ITEM_SKU_TEST_4, 10001,mPurchaseFinishedListener, "mypurchasetoken");
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase){
Log.d(TAG, "In onIabPurchaseFinished ");
if (result.isFailure()) {
Log.d(TAG, "In onIabPurchaseFinished >>> purchase error ");
return;
}else if (purchase.getSku().equals(ITEM_SKU_TEST_4)) {
Log.d(TAG, "In onIabPurchaseFinished purchase success ");
/**TODO update the db **/
DbClass dbDbClass = new DbClass(getApplicationContext());
dbHelper.updatePurchasedQuiz(2);
/** set the flag **/
isAlreadyPurchased = true;
Log.d(TAG, "The app after all the shebang: ");
Intent intent = new Intent(getApplicationContext(),ExamActivity.class);
intent.putExtra("quizId", "2");
startActivity(intent);
}else{
Log.d(TAG, " ");
Log.d(TAG, "In onIabPurchaseFinished in a weird condition ");
}
}
};
}
}
My implementation of onActivityResult ( where I can see the debug logs )
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, " ");
Log.d(TAG, "<<<<<< in IAP ONACTIVITYRESULT >>>>>>");
Log.d(TAG, "onActivityResult " + requestCode + "," + resultCode + "," + data);
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
Dont know if this would be the cause but the way I am invoking / initiatlizing the mHelper is :
1 In my activity onCreate - I start a thread ( AsyncTask )
2 In the method - doInBackground - I am initializing this helper :
mHelper = new IabHelper(ExamHomeActivity.this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { .... }
3 Then when this async task completes - I show some buttons on the screen
4 Clicking on any button invokes the method described above - onClickIap
Thanks
shankar
You are passing the mPurchaseFinishedListener before you have initialized it (which happens right after you call launchPurchaseFlow).
Also, initializing the listener in the onClick is not a very good idea. You will be doing this every time the button is pressed. Take that out from the onClickIap() method.
You can do that statically in your Activity, just like it is done in Google's sample app Trivial Drive:
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase){
Log.d(TAG, "In onIabPurchaseFinished ");
...
...
...
}
};
Initializing the IabHelper is probably best to be done in the onCreate() of the activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subscribe);
mHelper = new IabHelper(this);
}
Then do not forget to dispose of it in onDestory():
@Override
protected void onDestroy() {
super.onDestroy();
// very important:
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
}
Also, there is no need to set up the IabHelper from a background thread. Just call mHelper.startSetup from your UI thread whenever you are ready.