Android: Consume a product after purchase (in-app billing) - android

I have some problems with in app billing, I wanted to create an product inside the app that can be bought several times. But google made the in app billing in a way that a product first must be consumed before you can buy it again. I tried it with the following code:
public class HomeFragment extends Fragment {
private WebView homesite;
private String homeTabUrl;
private ProgressBar pBar;
private Bundle webViewBundle;
private Boolean buddyProfile = false;
private Boolean buddyProfile2 = false;
String url="";
private Context mContext;
final static String REQUEST_SUCCESS = "COMPLETED";
//Amount point
private static final int CREDIT_AMOUNT_100 = 100;
private static final int CREDIT_AMOUNT_500 = 500;
public static final String PAY_UID_100 = "messages";
public static final String PAY_UID_500 = "messages2";
private int mCreditAmount;
private IabHelper mHelper;
private static final int PAYINAPP_REQUESTCODE = 10001;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);
StaticMembers.loadHomeTab = true;
purchaseCredit(CREDIT_AMOUNT_100);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//Logger.error("YES-HERE IN ONACTIVITY RESULT");
if (checkReultPayInApp(requestCode,resultCode, data)) {
return;
}
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onStart() {
super.onStart();
}
private void loadData(View v) {
initPayinApp();
}
private void initPayinApp() {
// TODO Auto-generated method stub
String base64EncodedPublicKey = "n9goJ2waiwGS3F0E+XpjlMJRnn6rKtaH3lWxGUZQjNJeAAdL78mFeUTAGaZLgX/YOIuERWL5IzLaTXNi69c60oeh489wi3lyGtWbNvXR5EXVNhazti2mZgwvjhUdzW7/73mV0rHZn0f24G3Dpy0zLaTXNi69c60oeh489wi3lyGtWbNvXR5EXVNhazti2mZgwvjhUdzW7/73mV0rHZn0f24G3Dpy0wkIFWt51OnnusIVlJHrwJ8dYz4mUZ6SLFhkXL8NhrRAcZKvUV3WySB55SA5uu1+IoGG7mJw0QPn9goJ2waiwGS3F0E+XpjlMJRnn6rKtaH3lWxGUZQjNJeAAdL78mFeUTAGaZLgX/YOIuERWL5I7uInsqWH+ny1HFDr2wIDAQAB";
mHelper = new IabHelper(getActivity(), base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d("YES", "In-app Billing setup failed: " + result);
} else {
Log.d("YES", "In-app Billing is set up OK");
}
}
});
}
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
Logger.error("YES- Only in consume Listener");
if (result.isSuccess()) {
Logger.error("YES-in success consume Listener");
}
else {
Logger.error("YES-!in success consume Listener");
}
}
};
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
Logger.error("YES-IN SUCCESS: " + result.getMessage());
if (result.isFailure()) {
Logger.error("YES-"+result.getMessage());
return;
}
else if (purchase.getSku().equals(PAY_UID_100)) {
Logger.error("YES-100 purchased");
// remove query inventory method from here and put consumeAsync() directly
Toast.makeText(getActivity(), "100 points added successfully", Toast.LENGTH_SHORT).show();
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
} else if ( purchase.getSku().equals(PAY_UID_500)) {
Toast.makeText(getActivity(), "500 points added successfully", Toast.LENGTH_SHORT).show();
Logger.error("YES-500 purchased");
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
}
};
private void purchaseCredit(int creditAmount) {
mCreditAmount = creditAmount;
try {
if (mHelper != null) mHelper.flagEndAsync();
mHelper.launchPurchaseFlow(getActivity(), getIdPayInAppByAmount(creditAmount), PAYINAPP_REQUESTCODE,
mPurchaseFinishedListener, "mypurchasetoken");
} catch (Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
protected String getIdPayInAppByAmount(int creditAmount) {
switch (creditAmount) {
case CREDIT_AMOUNT_100:
return PAY_UID_100;
case CREDIT_AMOUNT_500:
return PAY_UID_500;
}
return null;
}
private boolean checkReultPayInApp(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode!= PAYINAPP_REQUESTCODE) {
return false;
}
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
if (resultCode == Activity.RESULT_OK) {
// Purchased Status = Purchased
try {
// Product Details JSON
JSONObject jo = new JSONObject(purchaseData);
// Purchased Product ID
String sku = jo.getString("productId");
addCredit(mCreditAmount);
} catch (Exception e) {
e.printStackTrace();
}
} else {
}
return true;
}
public void addCredit(final int creditAmount) {
TaskPost.depositPoint(getActivity(), new User().getEmail(), creditAmount, new MyHttpClient.OnRequestListener() {
public void OnStart() {
// TODO Auto-generated method stub
}
#Override
public void OnFinish(String result) {
if (result.equalsIgnoreCase(REQUEST_SUCCESS)) {
Toast.makeText(mContext,"You have just add " + creditAmount+ " success to your account",Toast.LENGTH_SHORT).show();
}
}
});
}
}
Please let me know what wrong I am doing while consuming the product so I can make changes accordingly.

you should consume the previously purchased items.
private void initPayinApp() {
// TODO Auto-generated method stub
String base64EncodedPublicKey = "";
mHelper = new IabHelper(getActivity(), base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d("YES", "In-app Billing setup failed: " + result);
} else {
Log.d("YES", "In-app Billing is set up OK");
//comment this function once all the previously purchased items are consumed successfully
reset();
}
}
});
}
void reset() {
mHelper.queryInventoryAsync(mGotInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (result.isFailure()) {
Log.d(TAG, "Failed to query inventory: " + result);
return;
}
Log.d(TAG, "Query inventory was successful.");
if(inventory.hasPurchase(PAY_UID_100))
{
Log.d(TAG, "already purchased : " + PAY_UID_100);
mHelper.consumeAsync(inventory.getPurchase(PAY_UID_100), mConsumeFinishedListener);
}
if(inventory.hasPurchase(PAY_UID_500))
{
Log.d(TAG, "already purchased : " + PAY_UID_500);
mHelper.consumeAsync(inventory.getPurchase(PAY_UID_500), mConsumeFinishedListener);
}
}
};

Related

Check Google In app purchase inventory

I am new to the coding and i mostly copy and paste from the google in app billing
Can anyone guide me in what is wrong in the code. Refer this
Android check if in app purchase was bought before
Here is my purchaseActivity
public class PurchaseActivity extends CustomMenu {
tk.myessentialoils.ideasapp.util.IabHelper mHelper;
Button buyButton;
String product1SKU;
Boolean VIP=false;
//String product1SKU = "vip_member";//getResources().getString(R.string.product1SKU);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_purchase);
buyButton = findViewById(R.id.buyButton);
product1SKU = getString(R.string.product1SKU);
mHelper = new tk.myessentialoils.ideasapp.util.IabHelper(this, getString(R.string.billing64basecode));
mHelper.startSetup(new tk.myessentialoils.ideasapp.util.IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(tk.myessentialoils.ideasapp.util.IabResult result) {
if (!result.isSuccess()) {
// Oh no, there was a problem.
Log.d("TAG", "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
}
});
/*
try {
mHelper.queryInventoryAsync(mGotInventoryListener);
} catch (IabHelper.IabAsyncInProgressException e) {
Log.d("TAG","Error querying inventory. Another async operation in progress.");
}
SharedPreferences.Editor editor = this.getSharedPreferences("Name", MODE_PRIVATE).edit();
Log.d("TAG", "checkVIPStatus: " +VIP);
editor.putBoolean("VIP",VIP);
editor.apply();
*/
}
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) try {
mHelper.dispose();
} catch (tk.myessentialoils.ideasapp.util.IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
mHelper = null;
}
public void buyClick(View view) {
try {
mHelper.launchPurchaseFlow(this, product1SKU, 10001,
mPurchaseFinishedListener, "mypurchasetoken");
} catch (tk.myessentialoils.ideasapp.util.IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
Toast.makeText(this, "Please set up your google account", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
tk.myessentialoils.ideasapp.util.IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new tk.myessentialoils.ideasapp.util.IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(tk.myessentialoils.ideasapp.util.IabResult result,
tk.myessentialoils.ideasapp.util.Purchase purchase)
{
if (mHelper == null) return;
if (result.isFailure()) {
// Handle error
Log.d("TAG", "onQueryInventoryFinished: Failed");
}
else if (purchase.getSku().equals(product1SKU)) {
buyButton.setEnabled(false);
VIP=true;
storeVIP();
}
}
};
tk.myessentialoils.ideasapp.util.IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new tk.myessentialoils.ideasapp.util.IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(tk.myessentialoils.ideasapp.util.IabResult result,
tk.myessentialoils.ideasapp.util.Inventory inventory) {
if (result.isFailure()) {
// handle error here
Log.d("TAG", "onQueryInventoryFinished: Failed");
}
else {
// does the user have the premium upgrade?
boolean mIsPremium = inventory.hasPurchase(product1SKU);
buyButton.setEnabled(false);// update UI accordingly
VIP=true;
storeVIP();
}
}
};
private void storeVIP(){
SharedPreferences.Editor editor = getSharedPreferences("Name", MODE_PRIVATE).edit();
Log.d("TAG", "checkVIPStatus: " +VIP);
editor.putBoolean("VIP",VIP);
editor.apply();
}
}
Question 1
My purchase activity crashed when I enable the commented code.
mHelper.queryInventoryAsync(mGotInventoryListener);
With the error IAB is not set up.
Can anyone show me what is wrong with this?
Question 2
Should I use queryInventoryAsync or use the method as described in here?
Android: in-app: check if an item has been purchased
Which method is easier or more efficient?
Question 1 answer
Place inside the IAB
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_purchase);
buyButton = findViewById(R.id.buyButton);
product1SKU = getString(R.string.product1SKU);
mHelper = new tk.myessentialoils.ideasapp.util.IabHelper(this, getString(R.string.billing64basecode));
mHelper.startSetup(new tk.myessentialoils.ideasapp.util.IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(tk.myessentialoils.ideasapp.util.IabResult result) {
if (result.isSuccess()) {
Log.d("TAG", "onIabSetupFinished: ");
// Hooray, IAB is fully set up!
try {
mHelper.queryInventoryAsync(mGotInventoryListener);
} catch (IabHelper.IabAsyncInProgressException e) {
Log.d("TAG","Error querying inventory. Another async operation in progress.");
}
}
else {
// Oh no, there was a problem.
Log.d("TAG", "Problem setting up In-app Billing: " + result);
}
}
});
}
Question 2 answer
It depend of type of item we are selling.
For one time transactions, and the item cannot be bought further, i used queryInventoryAsync.

Inappbilling add item and save it

I'm trying to add InAppBilling funciton to my android application. I just like to know before I do my alfa test that is it enough if I add the item (which is an int variable) with SharedPreferences and save it with SharedPreferences on this way:
private static final String HINT = "Hint";
private static final String VALUE = "VALUE";
int hints;
private static final String TAG =
"com.example.game";
com.example.game.util.IabHelper mHelper;
static final String ITEM_SKU = "com.lots.hints";
private Button clickButton;
private Button buyButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pontpiac);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.setContentView(R.layout.activity_pontpiac);
android.support.v7.app.ActionBar actionbar = getSupportActionBar();
actionbar.hide();
SharedPreferences sphint = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
hints = sphint.getInt(VALUE, 0);
buyButton = (Button)findViewById(R.id.buyButton);
clickButton = (Button)findViewById(R.id.clickButton);
clickButton.setEnabled(false);
String base64EncodedPublicKey =
"<my base64 code>";
mHelper = new com.example.game.util.IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new
com.example.game.util.IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(com.example.game.util.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");
}
}
});
}
public void buttonClicked (View view)
{
clickButton.setEnabled(false);
buyButton.setEnabled(true);
}
public void buyClick(View view) {
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "mypurchasetoken");
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
com.example.game.util.IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new com.example.game.util.IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(com.example.game.util.IabResult result,
com.example.game.util.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);
}
com.example.game.util.IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new com.example.game.util.IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(com.example.game.util.IabResult result,
com.example.game.util.Inventory inventory) {
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
}
}
};
com.example.game.util.IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new com.example.game.util.IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(com.example.game.util.Purchase purchase,
com.example.game.util.IabResult result) {
if (result.isSuccess()) {
hints = hints + 50;
clickButton.setEnabled(true);
} else {
// handle error
}
Toast.makeText(Pontpiac.this, "You have "+hints + " piece of hints!",
Toast.LENGTH_LONG).show();
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
public static boolean verifyPurchase(String base64PublicKey,
String signedData, String signature) {
if (TextUtils.isEmpty(signedData) ||
TextUtils.isEmpty(base64PublicKey) ||
TextUtils.isEmpty(signature)) {
Log.e(TAG, "Purchase verification failed: missing data.");
if (BuildConfig.DEBUG) {
return true;
}
return false;
}
PublicKey key = com.example.game.util.Security.generatePublicKey(base64PublicKey);
return com.example.game.util.Security.verify(key, signedData, signature);
}
#Override
protected void onPause() {
SharedPreferences sp = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
SharedPreferences.Editor et = sp.edit();
et.putInt(VALUE, hints);
et.commit();
super.onPause();
}
#Override
protected void onStop() {
SharedPreferences sp = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
SharedPreferences.Editor et = sp.edit();
et.putInt(VALUE, hints);
et.commit();
super.onStop();
}
}
I'm just confused and don't know where to add the item. Only in the IabHelper.OnConsumeFinishedListener method?
If anyone know that please response!

consuming in App purchased item

I'm trying to use in app purchase, after I want to purchase my item, I get the following error in the result of " IabHelper.OnConsumeFinishedListener mConsumeFinishedListener "
my Item is not a subscription !
the result.getmessage is as following: "Items of type 'subs' can't be consumed. (response: -1010:Invalid consumption attempt)"
what shall I do ?
my full code:
public class BuyCoins extends Activity{
String TAG="TESTPURCHASE";
IabHelper mHelper;
static final String ITEM_100_SKU = "ir.e_rundev.brainwars.test";
static final String ITEM_500_SKU = "ir.e_rundev.brainwars.test2";
static final String ITEM_1000_SKU = "ir.e_rundev.brainwars.1000coins";
String ITEM_SKU="";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.buy_coins);
Swarm.setActive(this);
String base64EncodedPublicKey =
"(I HAVE MY CODE HERE)";
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");
}
}
});
Button btn100 = (Button) findViewById(R.id.btn_Buy_100);
Button btn500 = (Button) findViewById(R.id.btn_Buy_500);
Button btn1000 = (Button) findViewById(R.id.btn_Buy_1000);
btn100.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ITEM_SKU=ITEM_100_SKU;
buyCoin(view);
}
});
btn500.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ITEM_SKU=ITEM_500_SKU;
buyCoin(view);
}
});
btn1000.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// ITEM_SKU=ITEM_1000_SKU;
// buyCoin(view);
}
});
}
public void buyCoin (View view) {
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "mypurchasetoken");
}
#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_100_SKU)) {
consumeItem();
Log.d(TAG, "Here"+purchase.getItemType());
} else if (purchase.getSku().equals(ITEM_500_SKU)) {
consumeItem();
} else if (purchase.getSku().equals(ITEM_1000_SKU)) {
consumeItem();
}
}
public void consumeItem() {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
Log.d(TAG,"here 3");
}
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);
Log.d(TAG,"here 4"+inventory.getPurchase(ITEM_SKU).getItemType());
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
//clickButton.setEnabled(true);
// Log.d(TAG,"SUCCESSFUL");
purchaseFinished(ITEM_SKU);
Log.d(TAG,"here2");
SharedPreferences settings = getSharedPreferences("MYSETTINGS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("isPremium", true);
editor.apply();
Adad.setDisabled(true);
} else {
// handle error
Log.d(TAG,"here 5");
Log.d(TAG,result.getMessage());
Log.d(TAG,purchase.toString());
}
}
};
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
}
public void onResume() {
super.onResume();
Swarm.setActive(this);
TextView tvCoins = (TextView) findViewById(R.id.tv_Buy_Coins);
GameInventory gameInventory = new GameInventory(getApplicationContext());
tvCoins.setText(String.valueOf(gameInventory.getCoinsCount()));
}
public void onPause() {
super.onPause();
Swarm.setInactive(this);
}
private void purchaseFinished(String SKU){
GameInventory gameInventory = new GameInventory(getApplicationContext());
if (SKU==ITEM_100_SKU) {
gameInventory.updateCoinsCount(gameInventory.getCoinsCount() + 100);
}else if(SKU==ITEM_500_SKU){
gameInventory.updateCoinsCount(gameInventory.getCoinsCount() + 520);
}else if (SKU==ITEM_1000_SKU){
gameInventory.updateCoinsCount(gameInventory.getCoinsCount() + 1100);
}
ITEM_SKU = "";
}
}
Hey I'm also working on InApp Purchase since 10 days and I've successfully integrated in my existing app and ready to make it live. Initially when i had started doing this I've downloaded google InApp Billing Example called "Trivial Drive" from here.
But it didn't help me much as it has lots of issues and bugs, So I've decided do it on my own from scratch using new v3 api which you can find here. This tutorial has clear explanation that would help you and also if you have time, see this youtube video where google employee had explained clearly how to integrate it.
Also if you want quick example, I've a sample app which you can download from here.
The following video also explains how to integrate InApp Purchase. Please go through it.
https://www.youtube.com/watch?v=-h2ESH71hAI
Thank you

Chartboost PostInstall Tracker

Can someone explain to me how can i integrate Chartboost post install?
Already tried this post-install integration guide with my testing app (uploaded as alpha test) and with this reserved in-app purchases:
android.test.purchased
android.test.canceled
android.test.refunded
android.test.item_unavailable
When i try to run this code:
public void ChartboostPI(View view) {
trackInAppGooglePlayPurchaseEvent("Sample Title", "Sample description for product: android.test.canceled.", "0.99", "USD", "android.test.purchased", "inapp:"+this.getPackageName()+":android.test.canceled", "j");
}
i'm getting:
iap failure responce!!
P.S.:
Maybe there is some ways to test my own inapps, but i dont know how to specify this in in-app purchase code (I will be glad if someone will explain me how).
Finally i found the answer, cb developers posted example with release of 5.0.3
Here is example code:
public class GoogleIAPTracking extends Activity{
private static final String TAG = "com.chartboost.sdk.sample.cbtest.inappbilling";
private static final int INAPP_REQUEST_CODE = 10001;
//private static final String RELEASE_ITEM_SKU = "com.example.buttonclick";
private static final String TEST_ITEM_SKU = "android.test.purchased";
private Button clickButton;
private Button buyButton;
private String ITEM_SKU;
IabHelper mHelper;
Inventory inventory;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pit);
Chartboost.onCreate(this);
Chartboost.setDelegate(delegate);
buyButton = (Button)findViewById(R.id.buyButton);
clickButton = (Button)findViewById(R.id.clickButton);
clickButton.setEnabled(false);
ITEM_SKU = TEST_ITEM_SKU;
String base64EncodedPublicKey = getResources().getString(R.string.base64EncodedPublicKey);
/*Setting up Inapp billing purchase*/
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.enableDebugLogging(true);
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 ###############");
Log.d(TAG, "In-app Billing is set up OK");
}
}
});
}
public void buyClick(View view) {
mHelper.launchPurchaseFlow(this, ITEM_SKU, INAPP_REQUEST_CODE, mPurchaseFinishedListener, "mypurchasetoken");
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
#Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG,"###### onIabPurchaseFinished"+purchase +"#####"+ ITEM_SKU);
if (result.isFailure()) {
Runnable r = new Runnable() {
#Override
public void run() {
mHelper.myconsume(GoogleIAPTracking.this.getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");
}
};
r.run();
Log.d(TAG,"###### onIabPurchaseFinished Error ");
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
buyButton.setEnabled(false);
}
}
};
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
Log.d(TAG,"###### onQueryInventoryFinished : " + inv);
if (result.isFailure()) {
// Handle failure
}
else {
Log.d(TAG," ####### Its in the inventory consuming the item !!!!");
try{
// MIGHT THROW AN EXCEPTION IF Chartboost.onStart() is not called.
Log.d(TAG,"########## Send it to Chartboost PIT ###########");
SkuDetails item = inv.getSkuDetails(ITEM_SKU);
Purchase purchase = inv.getPurchase(ITEM_SKU);
if(item !=null && purchase != null) {
String data =purchase.getOriginalJson();
String signature = TextUtils.isEmpty(purchase.getSignature()) ?"test":purchase.getSignature();
signature = TextUtils.isEmpty(signature) ?"test":signature;
if(item != null){
CBAnalytics.trackInAppGooglePlayPurchaseEvent(item.getTitle(),
item.getDescription(),
item.getPrice(),
item.getCurrencyCode(),
purchase.getSku(),
data,
signature);
}
}
} catch(Exception e){
Log.d(TAG, e.getMessage());
}
mHelper.consumeAsync(inv.getPurchase(ITEM_SKU), mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
Log.d(TAG,"###### onConsumeFinished");
if (result.isSuccess()) {
Log.d(TAG,"###### onConsumeFinished sucess");
}
buyButton.setEnabled(true);
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
// Pass on the activity result to the helper for handling
if (!mHelper.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.");
}
};
/* The following methods reflect the buttons in our UI. */
public void onLoadButtonClick(View view) {
String toastStr = "Loading Interstitial";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
Chartboost.showInterstitial(CBLocation.LOCATION_STARTUP);
}
public void onMoreButtonClick(View view) {
String toastStr = "Loading More Apps";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
Chartboost.showMoreApps(CBLocation.LOCATION_GAME_SCREEN);
}
public void trackMiscRevenueGeneratingEventOfType(View view) {
String toastStr = "Sending trackMiscRevenueGeneratingEventOfType to SDK ..";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
//pit.trackMiscRevenueGeneratingEvent(CBMiscRevenueGeneratingEventType.CBMiscRevenueGeneratingEventType1, 100, "USD", "HayDay");
}
public void trackCustomEventOfType(View view) {
String toastStr = "Sending trackCustomEventOfType to SDK ..";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
//pit.trackCustomEventofType(CBCustomEventType.CBCustomEventType1, 2);
}
public void trackInGameScore(View view) {
String toastStr = "Sending trackInGameScore to SDK ..";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
//pit.trackInGameScore(10);
}
public void trackPlayerCurrencyBalance(View view) {
String toastStr = "Sending trackPlayerCurrencyBalance to SDK ..";
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
//pit.trackPlayerCurrencyBalance(5, "USD");
}
/*Activity callback methods*/
#Override
protected void onStart() {
super.onStart();
Chartboost.onStart(this);
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG,"### onResume");
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStop() {
super.onStop();
Chartboost.onStop(this);
}
#Override
public void onBackPressed() {
if (Chartboost.onBackPressed())
return;
else
super.onBackPressed();
}
#Override
public void onDestroy() {
super.onDestroy();
Chartboost.onDestroy(this);
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
/**
* Chartboost Delegate callbacks
*/
private ChartboostDelegate delegate = new ChartboostDelegate() {
};
}

load specific visible people in google plus in android

I have successfully implemented google plus
list people activity
public class ListPeopleActivity extends Activity implements
PlusClient.ConnectionCallbacks, PlusClient.OnPeopleLoadedListener,
PlusClient.OnConnectionFailedListener, DialogInterface.OnCancelListener {
private static final String TAG = "ListPeopleActivity";
private static final String STATE_RESOLVING_ERROR = "resolving_error";
private static final int DIALOG_GET_GOOGLE_PLAY_SERVICES = 1;
private static final int REQUEST_CODE_SIGN_IN = 1;
private static final int REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES = 2;
private ArrayAdapter mListAdapter;
private ListView mPersonListView;
private ArrayList<String> mListItems;
private PlusClient mPlusClient;
private boolean mResolvingError;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.person_list_activity);
mPlusClient = new PlusClient.Builder(this, this, this)
.setVisibleActivities(MomentUtil.VISIBLE_ACTIVITIES).build();
mListItems = new ArrayList<String>();
mListAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mListItems);
mPersonListView = (ListView) findViewById(R.id.person_list);
mResolvingError = savedInstanceState != null
&& savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
int available = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (available != ConnectionResult.SUCCESS) {
showDialog(DIALOG_GET_GOOGLE_PLAY_SERVICES);
}
}
#Override
protected Dialog onCreateDialog(int id) {
if (id != DIALOG_GET_GOOGLE_PLAY_SERVICES) {
return super.onCreateDialog(id);
}
int available = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (available == ConnectionResult.SUCCESS) {
return null;
}
if (GooglePlayServicesUtil.isUserRecoverableError(available)) {
return GooglePlayServicesUtil.getErrorDialog(available, this,
REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES, this);
}
return new AlertDialog.Builder(this)
.setMessage(R.string.plus_generic_error).setCancelable(true)
.setOnCancelListener(this).create();
}
#Override
protected void onStart() {
super.onStart();
mPlusClient.connect();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
#Override
protected void onStop() {
super.onStop();
mPlusClient.disconnect();
}
#Override
public void onPeopleLoaded(ConnectionResult status,
PersonBuffer personBuffer, String nextPageToken) {
switch (status.getErrorCode()) {
case ConnectionResult.SUCCESS:
mListItems.clear();
try {
int count = personBuffer.getCount();
Log.e("", "count : " + count);
for (int i = 0; i < count; i++) {
mListItems.add(personBuffer.get(i).getDisplayName());
Log.e("", "" + personBuffer.get(i).getDisplayName() + " "
+ personBuffer.get(i).getId() + " isPlusUser : "
+ personBuffer.get(i).isPlusUser()
+ " isVerified : "
+ personBuffer.get(i).isVerified()
+ " hasCircledByCount : "
+ personBuffer.get(i).hasCircledByCount()
+ " getObjectType : "
+ personBuffer.get(i).getObjectType());
}
} finally {
personBuffer.close();
}
mListAdapter.notifyDataSetChanged();
break;
case ConnectionResult.SIGN_IN_REQUIRED:
mPlusClient.disconnect();
mPlusClient.connect();
break;
default:
Log.e(TAG, "Error when listing people: " + status);
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
mResolvingError = false;
handleResult(resultCode);
break;
case REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES:
handleResult(resultCode);
break;
}
}
private void handleResult(int resultCode) {
if (resultCode == RESULT_OK) {
// onActivityResult is called after onStart (but onStart is not
// guaranteed to be called while signing in), so we should make
// sure we're not already connecting before we call connect again.
if (!mPlusClient.isConnecting() && !mPlusClient.isConnected()) {
mPlusClient.connect();
}
} else {
Log.e(TAG, "Unable to sign the user in.");
finish();
}
}
#Override
public void onConnected(Bundle connectionHint) {
mPersonListView.setAdapter(mListAdapter);
// mPlusClient.loadVisiblePeople(this, null);
mPlusClient.loadPeople(this, "103193341800315457743");
}
#Override
public void onDisconnected() {
mPersonListView.setAdapter(null);
mPlusClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
return;
}
mPersonListView.setAdapter(null);
try {
result.startResolutionForResult(this, REQUEST_CODE_SIGN_IN);
mResolvingError = true;
} catch (IntentSender.SendIntentException e) {
// Get another pending intent to run.
mPlusClient.connect();
}
}
#Override
public void onCancel(DialogInterface dialogInterface) {
Log.e(TAG, "Unable to sign the user in.");
finish();
}
In above code it mPlusClient.loadVisiblePeople(this, null); load all visible(in circle) people.. I want to load one specific people which is in my circle. and mPlusClient.loadPeople(this, "103193341800315457743"); this can load specific people but how can I know it is in my circle or not... because it returns everytime whether it is in my circle or not.
Actually I want to know that specific people is in my circle or not.
try, mPlusClient.loadPerson(this, "103193341800315457743");

Categories

Resources