I have a beta app google play. I can buy item once but When I want to buy again it says:
you already own this item
and I can't buy more then one. I think I can't consume; I searched but I can't solve this.
I add my codes:
mHelper = new IabHelper(this, apiKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(TAG, "In-app Billing setup failed: " +
result);
} else {
Log.d(TAG, "In-app Billing is set up OK");
mHelper.enableDebugLogging(true, TAG);
}
}
});
and the others..
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
public void consumeItem() {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
// Satın alma başarılı ise burada satın alma sonrası işlemleri yapabiliriz.
// consume(ITEM_SKU);
MacListesi mac = new MacListesi(getApplicationContext());
mac.kayitekle("SaidHoca");
finish();
startActivity(getIntent());
} else {
// handle error
}
}
};
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
} else if(purchase.getSku().equals(ITEM_SKU)) {
consumeItem();
consume(ITEM_SKU);
MacListesi mac = new MacListesi(getApplicationContext());
mac.kayitekle("SaidHoca");
finish();
startActivity(getIntent());
}
}
};
public void buyItem(View v) {
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroying helper.");
if (mHelper != null) {
try {
mHelper.dispose();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} finally {
}
}
mHelper = null;
}
Where I must consume item for buying more than one?
Related
The problem is that the app doesn't allow the users to purchase more than once. I need to make my item consumable, and the answer is all explained here.
What I need to know is EXACTLY WHERE I have to put this part:
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
in my code?
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,
Purchase purchase)
{
if (result.isFailure()) {
// Handle error
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
consumeItem();
buyButton.setEnabled(false);
}
}
};
public void consumeItem() {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory)
{
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
clickButton.setEnabled(true);
} else {
// handle error
}
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_app_billing);
buyButton = (Button)findViewById(R.id.buyButton);
clickButton = (Button)findViewById(R.id.clickButton);
String base64EncodedPublicKey =
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3F8aC2kUFQHf/X3xnfgulD0UpgrQifcjZ66zzhUPhQ/TcrONl22V74Q/Uj57rCwSUfdzz7wbUPxuPayGKBozzoH+2vhMGSetgCFZLcrNbRpBBbihOZrj//GTXMa6VkpUPTAqthEF0oI1M/bW9vF75xZI3u2KAS/AYDfqLTRZ6mh+xh6n/3i0ntSZT+UwzguwyHfS9JwuGGg5AKSutaWhnvOTNeQjsxTskc483h9DfvvRiwdiQPlv7wJRSSIc3RHVwDHleEJ8rsRa8JTypBJuL5oRZSGePUlejWhJvs23tgy5xrvGsMgsICssGzIem2XXSUWm/NDjeO0v2Eh+quQKVQIDAQAB";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
{
public void onIabSetupFinished(IabResult result)
{
if (!result.isSuccess())
{
Log.d(TAG, "In-app Billing setup failed: " + result);
} else
{
Log.d(TAG, "In-app Billing is set up OK");
}
}
});
}
}
Because in the other answer Haxis says "you have to call the consume function just after the purchase."
Could anyone help me please?
As you can check in the google sample -
https://github.com/googlesamples/android-play-billing/blob/master/TrivialDrive/app/src/main/java/com/example/android/trivialdrivesample/MainActivity.java
consumeAsync() is called twice:
-When the purchase is complete, in OnIabPurchaseFinishedListener
-When the inventory is queried at the start of the activity, in QueryInventoryFinishedListener
You also need to call it when the purchase was successful as well as when you query the inventory and find a consumable item in there (because if the item is consumed, then it won't appear in the inventory)
I am trying to integrate IAB into my application. I have implemented it successfully, but I have issue. Item not getting consumed. So once I make a purchase, I cannot purchase the item again. Here is my code for the same
public class BtnListener implements View.OnClickListener
{
// On-click event handler for all the buttons
#Override
public void onClick(View view)
{
switch (view.getId())
{
case R.id.TwoSeconds:
mHelper.launchPurchaseFlow(TimeBoosterActivity.this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "2");
break;
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,
Purchase purchase)
{
if (result.isFailure()) {
// Handle error
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
consumeItem();
//buyButton.setEnabled(false);
}
}
};
public void consumeItem()
{
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
Toast.makeText(getApplicationContext(), "Failed to consume item",
Toast.LENGTH_SHORT).show();
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
String getSeconds=purchase.getDeveloperPayload();
SharedPreferences saveTwoSeconds=getSharedPreferences(getSeconds, Context.MODE_PRIVATE);
//clickButton.setEnabled(true);
} else {
// handle error
Toast.makeText(getApplicationContext(), "Failed to consume item",
Toast.LENGTH_SHORT).show();
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
I implement an in-app for Google Play. I use the test item: android.test.purchased and described the item as NONconsumable (not consuming it anywhere in the code with mHelper.consumeAsync). While running the app, after some "restart"s and "force close"s, "going online to offline" and "offline to online" somewhere in the middle, the item becomes consumable again and I can purchase the item. It is consumable sometimes and non consumable other times! I appreciate any suggestion. My code is below:
...
public class Home extends Activity {
...
static final String ITEM_SKU = "android.test.purchased";
IabHelper mHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
}
#Override
protected void onStart() {
super.onStart();
mHelper = new IabHelper(this, key);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener(){
public void onIabSetupFinished(IabResult result){
if (!result.isSuccess()){
Log.d("setup", "NOT OK");
}
else{
Log.d("setup", "OK");
List SKU_List = new ArrayList();
SKU_List.add(ITEM_SKU);
mHelper.queryInventoryAsync(false, SKU_List, mQueryFinishedListener);
}
}
});
}
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener(){
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
return;
}
try {
if (inventory.hasPurchase(ITEM_SKU)) {
buttonsInPremiumMode();
} else {
buttonsNOTPremiumMode();
String itemPrice = inventory.getSkuDetails(ITEM_SKU).getPrice();
buyPremiumButton.setText(getResources().getString(R.string.buyPremiumButton) + itemPrice);
}
}
catch(Exception e){
}
}
};
private void purchase(){
if (mHelper != null){
mHelper.flagEndAsync();
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001, mPurchaseFinishedListener, "payloadercode");
}
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener(){
public void onIabPurchaseFinished(IabResult result, Purchase purchase){
if (result.isFailure()){
}
else if (purchase.getSku().equals(ITEM_SKU)){
buttonsInPremiumMode();
}
else {
}
}
};
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) {
mHelper.dispose();
}
mHelper=null;
}
private void buttonsNOTPremiumMode(){
...
}
private void buttonsInPremiumMode(){
...
}
}
Putting
mHelper.flagEndAsync()
just before
mHelper.launchPurchaseFlow
fixed my problem.
I'm trying to implement in-app purchases on fragments. I used the tutorial http://twigstechtips.blogspot.com/2013/12/android-setting-up-in-app-billing-api.html including modifying IabHelper. I also needed to modify MainActivity:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
PremiumFragment premiumFragment = new PremiumFragment();
premiumFragment.onActivityResult(requestCode, resultCode, data);
}
to send the result to a fragment. Problem is when google billing dialog box disappears, I need manualy reload fragment, to call OnIabPurchaseFinishedListener. My code:
public class PremiumFragment extends Fragment implements NamedTopBar,
OnClickListener {
static final String ITEM_SKU_SUBSCRIPTION = "test";
static final int RC_REQUEST = 10001;
IabHelper iabHelper;
private Button subscriptionButton;
private boolean mBillingServiceReady;
private boolean subBool;
// Callback for when a purchase is finished
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
#Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "mPurchaseFinishedListener");
// if we were disposed of in the meantime, quit.
if (iabHelper == null) {
return;
}
// Don't complain if cancelling
if (result.getResponse() == IabHelper.IABHELPER_USER_CANCELLED) {
Log.d(TAG, "User canceled purchase");
return;
}
if (!result.isSuccess()) {
Log.d(TAG, "Error purchasing: " + result.getMessage());
if (result.getResponse() == 7) {
Toast.makeText(getActivity(), "item already purchased!",
Toast.LENGTH_LONG).show();
}
return;
}
if (!verifyDeveloperPayload(purchase)) {
Log.d(TAG,
"Error purchasing. Authenticity verification failed.");
return;
}
// Purchase was success! Update accordingly
if (purchase.getSku().equals(ITEM_SKU_SUBSCRIPTION)) {
Toast.makeText(getActivity(),
"Thank you for buying SUBSCRIPTION!", Toast.LENGTH_LONG)
.show();
subBool = true;
}
initialiseStuff(subBool);
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
#Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
// if we were disposed of in the meantime, quit.
if (iabHelper == null) {
return;
}
if (result.isSuccess()) {
iabHelper.queryInventoryAsync(iabInventoryListener());
} else {
Log.d(TAG, "Error while consuming: " + result);
}
// Update the UI to reflect their latest purchase
initialiseStuff(subBool);
}
};
private View window;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Log.d(TAG, "onCreate");
initialiseBilling();
}
private void initialiseBilling() {
if (iabHelper != null) {
return;
}
String base64EncodedPublicKey = "";
iabHelper = new IabHelper(getActivity(), base64EncodedPublicKey);
iabHelper.enableDebugLogging(false);
Log.d(TAG, "Starting setup.");
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
#Override
public void onIabSetupFinished(IabResult result) {
// Have we been disposed of in the meantime? If so, quit.
if (iabHelper == null) {
return;
}
// Something went wrong
if (!result.isSuccess()) {
Log.d(TAG,
"Problem setting up in-app billing: "
+ result.getMessage()
);
return;
}
// IAB is fully set up. Now, let's get an inventory of stuff we
// own.
Log.d(TAG, "In-app Billing is set up OK");
mBillingServiceReady = true;
iabHelper.queryInventoryAsync(iabInventoryListener());
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
window = inflater.inflate(R.layout.premium_fragment, null);
initViews();
return window;
}
#Override
public void onDestroy() {
super.onDestroy();
if (iabHelper != null) {
iabHelper.dispose();
iabHelper = null;
}
}
private void initViews() {
subscriptionButton = (Button) window
.findViewById(R.id.buy_premium_button);
subscriptionButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buy_premium_button:
Log.d(TAG, "buy_premium_button");
if (mBillingServiceReady) {
/*
* TODO: for security, generate your payload here for
* verification. See the comments on verifyDeveloperPayload()
* for more info. Since this is a SAMPLE, we just use an empty
* string, but on a production app you should carefully generate
* this.
*/
if (iabHelper != null)
iabHelper.flagEndAsync();
String payload = "";
iabHelper.launchPurchaseFlow(getActivity(),
ITEM_SKU_SUBSCRIPTION, RC_REQUEST,
mPurchaseFinishedListener, payload);
} else {
showToast();
}
break;
}
}
private void showToast() {
Toast.makeText(
getActivity(),
"Purchase requires Google Play Store (billing) on your Android.",
Toast.LENGTH_LONG).show();
}
private IabHelper.QueryInventoryFinishedListener iabInventoryListener() {
return new IabHelper.QueryInventoryFinishedListener() {
#Override
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
// Have we been disposed of in the meantime? If so, quit.
if (iabHelper == null) {
return;
}
// Something went wrong
if (!result.isSuccess()) {
Log.d(TAG,
"onFailure: QueryInventoryFinishedListener," +
"result: " + result
);
return;
}
Log.d(TAG, "Checking for purchases");
Purchase purchaseSubscription = inventory
.getPurchase(ITEM_SKU_SUBSCRIPTION);
subBool = (purchaseSubscription != null && verifyDeveloperPayload(purchaseSubscription));
initialiseStuff(subBool);
}
};
}
private void initialiseStuff(boolean subBool) {
if (subBool) {
subscriptionButton.setText("You already have premium");
subscriptionButton.setEnabled(false);
} else {
subscriptionButton.setEnabled(true);
}
}
boolean verifyDeveloperPayload(Purchase purchase) {
// String payload = p.getDeveloperPayload();
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (iabHelper == null)
return;
// Pass on the activity result to the helper for handling
if (!iabHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}
How to call mPurchaseFinishedListener automatically after dialog box disappears?
I added In-app billing v3 in my app and when I try to buy an item, the transfer is successful and money is taken from credit card, but the item doesn't add in app. What could be wrong?
//EDIT
public class GetcoinsActivity extends MainActivity {
SharedPreferences prefs_coins;
static final String ITEM_SKU_1 = "coins_1";
static final int RC_REQUEST = 10001;
private static final String TAG = "com.chess.black";
IabHelper mHelper;
Button btn1;
int score_get = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_getcoins);
prefs_coins = PreferenceManager.getDefaultSharedPreferences(GetcoinsActivity.this);
if (prefs_coins.contains(activity_play_normal.APP_PREFERENCES_score))
{
score_get = prefs_coins.getInt(activity_play_normal.APP_PREFERENCES_score, 0);
}
btn1 = (Button) findViewById(R.id.buttonBuy30);
String base64EncodedPublicKey = "here's my key";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new
IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result)
{
if (!result.isSuccess()) {
Log.d(TAG, "In-app Billing setup failed: " +
result);
} else {
Log.d(TAG, "In-app Billing is set up OK");
}
}
});
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,
Purchase purchase)
{
if (result.isFailure()) {
// Handle error
return;
}
else if (purchase.getSku().equals(ITEM_SKU_1)) {
consumeItem();
}
}
};
public void consumeItem() {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory)
{
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU_1),
mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
score_get = score_get + 500;
Editor editor = prefs_coins.edit();
editor.putInt(activity_play_normal.APP_PREFERENCES_score, score_get);
editor.commit();
} else {
// handle error
}
}
};
public void OnClickBuy30(View v)
{
mHelper.launchPurchaseFlow(GetcoinsActivity.this, ITEM_SKU_1, RC_REQUEST,
mPurchaseFinishedListener);
}
protected void OnDestroy()
{
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
protected void OnActivityResult(int requestCode, int resultCode, Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
ok first please put Logs in your code ... (Log.d(..))
maybe your score will be not written in the preferences because the billing process is in another process .. try this
SharedPreferences yourPrefs= ctx.getSharedPreferences(ctx.PREFS_NAME,ctx.MODE_MULTI_PROCESS);