I'm writing an application for android and I have difficulties with saving int variable with SharedPreferences when using In-App billing. I'd like to add 50 points to my int variable and then save it with SharedPreferences. When the purchase is finished the user got nothing, but it said Payment Succesfull.How should I add and save the 50 points?
Here is my code:
private static final String HINT = "Hint";
private static final String VALUE = "VALUE";
int hints;
private static final String TAG =
"com.game.example";
com.game.example.util.IabHelper mHelper;
static final String ITEM_SKU = "com.fifty.points";
private Button clickButton;
private Button buyButton;
Button btn;
#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 =
"Base64 code;
mHelper = new com.game.example.util.IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new
com.game.example.util.IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(com.game.example.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.game.example.util.IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new com.game.example.util.IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(hu.szada.kepkirako.util.IabResult result,
com.game.example.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.game.example.util.IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new com.game.example.util.IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(com.game.example.util.IabResult result,
com.game.example.util.Inventory inventory) {
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
}
}
};
#Override
protected void onResume() {
SharedPreferences sphint = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
hints = sphint.getInt(VALUE, 0);
super.onResume();
}
com.game.example.util.IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new com.game.example.util.IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(hu.szada.kepkirako.util.Purchase purchase,
com.game.example.util.IabResult result) {
if (result.isSuccess()) {
hints = hints + 50;
clickButton.setEnabled(true);
} else {
// handle error
}
}
};
#Override
protected void onPause() {
SharedPreferences sphint = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
SharedPreferences.Editor et2 = sphint.edit();
et2.putInt(VALUE, hints);
et2.commit();
Toast.makeText(Pontpiac.this, "" + hints,
Toast.LENGTH_LONG).show();
super.onPause();
}
#Override
protected void onStop() {
SharedPreferences sphint = getApplicationContext().getSharedPreferences(HINT, MODE_PRIVATE);
SharedPreferences.Editor et2 = sphint.edit();
et2.putInt(VALUE, hints);
et2.commit();
super.onStop();
}
#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.game.example.util.Security.generatePublicKey(base64PublicKey);
return hu.szada.kepkirako.util.Security.verify(key, signedData, signature);
}}
TinyDB -- Android-Shared-Preferences-Turbo
This class simplifies calls to SharedPreferences in a line of code. It can also do more like: saving a list of strings, integers and saving images. All in 1 line of code!
Example usage:
TinyDB tinydb = new TinyDB(context);
tinydb.putInt("clickCount", 2);
tinydb.putFloat("xPoint", 3.6f);
tinydb.putLong("userCount", 39832L);
tinydb.putString("userName", "john");
tinydb.putBoolean("isUserMale", true);
tinydb.putList("MyUsers", mUsersArray);
tinydb.putImagePNG("DropBox/WorkImages", "MeAtlunch.png", lunchBitmap);
//These plus the corresponding get methods are all included
This is just an example of how easy it is to use. There are many more usefull methods included in the class. Enjoy :)
Related
I'm creating an Android app that manages screenshot folders in the gallery.
One of the functions of the app is to automatically delete screenshot images, and to do this, I created two classes: DeleteActivity and MyJobService. MyJobService class is doing background work with JobScheduler.So I'm going to send uri from the DeleteActivity class to MyJobService class and delete pictures from the screenshot folder with the uri, but this is the code I've worked on so far, but there's no error, and nothing happens. What's the problem? Is there a way to automatically delete pictures other than using uri? Please let me know if there's a good way.
DeleteAcitivity.class
public class MainActivity extends AppCompatActivity {
private static final int READ_REQUEST_CODE = 42;
private static final int JOB_REQUEST_CODE = 43;
public static final String PREFS_NAME = "MyPrefsFile";
private static final int DELETE_JOB_KEY = 123;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("LastSetting", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
final int spinnerSelected = sharedPreferences.getInt("LastClick", 0);
final Spinner spinner = (Spinner) findViewById(R.id.spinner);
final View txt1 = findViewById(R.id.txt1);
final View txt2 = findViewById(R.id.txt2);
final SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("switchkey", false);
Switch deleteSwitch = findViewById(R.id.switchdel);
deleteSwitch.setChecked(silent);
deleteSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
txt1.setEnabled(true);
spinner.setEnabled(true);
txt2.setEnabled(true);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, JOB_REQUEST_CODE);
} else {
txt1.setEnabled(false);
spinner.setEnabled(false);
txt2.setEnabled(false);
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.cancel(DELETE_JOB_KEY);
Log.d(TAG, "Job cancelled");
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("switchkey", isChecked).commit();
}
});
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.days_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setSelection(spinnerSelected);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
editor.putInt("LastClick", position).commit();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
String txtSpinner = spinner.getSelectedItem().toString();
Button picture = (Button) findViewById(R.id.btnfind);
picture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == READ_REQUEST_CODE && resultCode == RESULT_OK) {
try {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
}
Bitmap img = getBitmapFromUri(uri);
DocumentsContract.deleteDocument(getContentResolver(), uri);
} // try
catch (Exception e) {
} // catch
} // if
if(requestCode == JOB_REQUEST_CODE)
{
if(resultData != null) {
ComponentName componentName = new ComponentName(MainActivity.this, MyJobService.class);
PersistableBundle bundle = new PersistableBundle();
bundle.putString("imageUri", resultData.getData().toString());
JobInfo.Builder builder = new JobInfo.Builder(DELETE_JOB_KEY, componentName)
.setExtras(bundle)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setPeriodic(15 * 60 * 1000);
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.schedule(builder.build());
}
}
} // onActivityResult()
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
}
MyJobService.class
public class MyJobService extends JobService {
private static final String TAG = "MyJobService";
private boolean jobCancelled = false;
private JobParameters jobParameters;
private DeleteAsyncTask deleteAsyncTask;
#Override
public boolean onStartJob(JobParameters params) {
this.jobParameters = params;
PersistableBundle persistableBundle = params.getExtras();
String strUri = persistableBundle.getString("imageUri");
Uri uri = Uri.parse(strUri);
deleteAsyncTask = (DeleteAsyncTask) new DeleteAsyncTask().execute(uri);
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG, "onStopJob: Job cancelled before completion");
if(null != deleteAsyncTask){
if(!deleteAsyncTask.isCancelled())
deleteAsyncTask.cancel(true);
}
return true;
}
private class DeleteAsyncTask extends AsyncTask<Uri, Integer, String>{
#Override
protected String doInBackground(Uri... uris) {
try {
DocumentsContract.deleteDocument(getContentResolver(), uris[0]);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return "Job Finished!";
}
#Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values);
Log.d(TAG, "onProgressUpdate: i was: " + values[0]);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d(TAG, "onPostExecute: message: " + s);
jobFinished(jobParameters, true);
}
}
}
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);
}
}
};
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!
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
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() {
};
}