I tried setting up InApp purchases for a donation with the guide provided by Google but when I call the activity (which should return if it was a success or not) but it throws this error:
In-app billing error: Illegal state for operation (launchPurchaseFlow): IAB helper is not set up
The activity is called with this method:
public boolean donation() {
int success = 0;
Intent intent = new Intent(Main.this, Donate.class);
startActivityForResult(intent, success);
if (success != 0) {
return true;
}
else return false;
}
And the Donate class (which I tried coding with the guide) looks like this:
import java.math.BigInteger;
import java.security.SecureRandom;
import maturaarbeit.nicola_pfister.marks.R;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
public class Donate extends Activity {
IabHelper mHelper;
private static final String TAG = "Donate";
private String payload;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String base64EncodedPublicKey = getKey();
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
}
});
SharedPreferences prefs = getSharedPreferences(getPackageName() + "_preferences", MODE_PRIVATE); //Add shared preferences
payload = prefs.getString("devpayload", null);
if (payload == null) {
payload = getPayload();
Editor editor = prefs.edit();
editor.putString("devpayload", payload)
.apply();
}
mHelper.launchPurchaseFlow(this, "donation_1chf", 1, mPurchaseFinishedListener, payload);
finish();
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase info) {
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " +result);
return;
}
else if (info.getDeveloperPayload().equals(payload)) {
return;
}
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.i(TAG, "onActivityResult handled by IABUtil.");
}
}
private String getKey() {
//Code for building public key
}
private String getPayload() {
SecureRandom random = new SecureRandom();
{
return new BigInteger(130, random).toString(32);
}
}
@Override
protected void onDestroy() {
if (mHelper != null) mHelper.dispose();
mHelper = null;
super.onDestroy();
}
}
It is supposed to generate a dev payload which is stored in shared prefs if there isn't already one. If you need any additional information feel free to ask.
Thanks for your help!
You have to wait for onIabSetupFinishedListener
to return before calling launchPurchaseFlow
- move those lines into your onIabSetupFinishedListener
's onIabSetupFinished
method to ensure that the IabHelper
's setup is complete:
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
else { // Only launch the purchase flow if setup succeeded
mHelper.launchPurchaseFlow(Donate.this, "donation_1chf", 1,
mPurchaseFinishedListener, payload);
}
}
});
You should use real device for app billing because when using emulator some parameters are being null and it causes runtime errors.
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