The new Android Billing v3 documentation and helper code uses startIntentSenderForResult()
when launching a purchase flow. I want to start a purchase flow (and receive the result) from a Fragment
.
For example the documentation suggests calling
startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
and the helper code calls
mHelper.launchPurchaseFlow(this, SKU_GAS, 10001,
mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
which calls startIntentSenderForResult()
.
The problem is, calling startIntentSenderForResult()
causes onActivityResult()
to be called on the parent Activity
rather than on the Fragment
that it was called from (where the IabHelper
resides).
I could receive the onActivityResult()
in the parent Activity
and then manually call the onActivityResult()
on the Fragment
, but is there a way to make a call to startIntentSenderForResult()
from a Fragment
that returns the result directly to that Fragment
's onActivityResult()
?
I suggest two solutions:
1.) Put the IabHelper mHelper on the activity and call the IabHelper from the fragment.
Something like:
To use this solution, Declare IabHelper as public in the activity and use a method to call the launcher from the Fragment.
public class MyActivity extends Activity{
public IabHelper mHelper
public purchaseLauncher(){
mHelper.launchPurchaseFlow(this, SKU_GAS, 10001,
mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
}
/*The finished, query and consume listeners should also be implemented in here*/
}
public class FragmentActivity extends Fragment{
MyActivity myAct = (MyActivity) getActivity();
myAct.purchaseLauncher();
}
2.) In onActivityResult, call the appropriate fragment that contains the IabHelper object. Appropriate fragment can have an access method to the helper object.
protected void onActivityResult(int requestCode, int resultCode,Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag("YourTag");
if (fragment != null)
{
((MyFragmentWithIabHelper)fragment).onActivityResult(requestCode, resultCode,data);
}
}
1) You should modify your resultCode (RC_REQUEST) to put fragment index to it.
int rc_reqest = RC_REQUEST + ((getActivity().getSupportFragmentManager().getFragments().indexOf(this)+1)<<16) ;
mHelper.launchPurchaseFlow(getActivity(), sku, rc_reqest ,mPurchaseFinishedListener, payload);
2) in IabHelper.launchPurchaseFlow(...)
change mRequestCode = requestCode
to
mRequestCode = requestCode&0xffff;
From SDK 24 and above, there is a startIntentSenderForResult method available in support Fragment also, which works as intended. Note that there is an additional Bundle parameter, which can be passed as null. Thus, final code will be:
startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0), null);
Of course, for API 23 and below, we will still need to use the tricks described in other answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With