I'm trying to implment in app puchase/billing in my app so when the user buys the item i remove the ads. I have and example code that is working with SKU = "android.test.purchased". Now my question is how can I link the app to my items - I have uploaded new apk with billing enabled, created and published the item one hour ago, but when I try to buy the item I get this:
here is my code:
public class RemoveAds extends AthanBaseActivity implements OnClickListener {
private static final String TAG = "inappbilling";
IabHelper mHelper;
//ID from playstore 16xxxx15_removeads.
//android.test.purchased
static final String ITEM_SKU = "com.myapppackage.16xxxx15_removeads.";
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.remove_ads);
findViewById( R.id.remove_ads_).setOnClickListener(this);
setupInAppPurchase();
}
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);
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null)
mHelper.dispose();
mHelper = null;
}
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
Toast.makeText(RemoveAds.this, "SUCCESS", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(RemoveAds.this, "ERROR purchase",
Toast.LENGTH_LONG).show();
// handle error
}
}
};
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);
}
}
};
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void setupInAppPurchase() {
String base64EncodedPublicKey = "MIIBIjANBgkqhkcccxxxxxdomr somelongstringdfsdfsdfsfsdofksdofkdsMXz0R4EJuw7YZkQ8jMPemymSbQGtLllH+fu85hfQIDAQAB";
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");
}
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.remove_ads_:
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "mypurchasetoken");
break;
}
}
}
You cannot make purchases if the primary account on your real android device is same as your developer account.
Related
How can I buy one thing multiple times? Here is my code:
// [...]
String base64EncodedPublicKey =
"MIIB...;
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new
IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Toast.makeText(gift.this, "Setup no Success", Toast.LENGTH_SHORT).show();
Log.d(TAG, "In-app Billing setup failed: " + result);
} else {
Toast.makeText(gift.this, "Setup Success", Toast.LENGTH_SHORT).show();
}
}
});
}
public void insert(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()) {
Toast.makeText(gift.this, "Error 1", Toast.LENGTH_SHORT).show();
}
else if (purchase.getSku().equals(ITEM_SKU)) {
consumeItem();
Toast.makeText(gift.this, "OK 1", Toast.LENGTH_SHORT).show();
// mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
}
};
public void consumeItem() {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
Toast.makeText(gift.this, "Error 2", Toast.LENGTH_SHORT).show();
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
mConsumeFinishedListener);
Toast.makeText(gift.this, "OK 2", Toast.LENGTH_SHORT).show();
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
Toast.makeText(gift.this, "Success 1", Toast.LENGTH_SHORT).show();
// mHelper.consumeAsync(purchase, mConsumeFinishedListener);
} else {
Toast.makeText(gift.this, "Error 3", Toast.LENGTH_SHORT).show();
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
}
When I click on my button it says: "payment successful" and after that when I click on my button again it does not do anything.
I have 2 questions:
How to buy a single in-app-purchase multiple times?
How can I display a Toast after the payment was successful?
Thanks for answers.
The purchase must be consumed after every purchase, then it can be purchased again. If you are able to purchase the item once but not again, then almost assuredly the problem is that you are not consuming it correctly.
There doesn't appear to be any problem with your code, Toast.makeText(...) should work fine.
I followed a tutorial online. I have all this code coming before my onCreate
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
btnPurchase.setEnabled(false);
btnStats.setBackgroundResource(R.drawable.purchasepressed);
test.setText("IT WORKS!!!");
} else {
// handle error
}
}
};
public void consumeItem() throws IabHelper.IabAsyncInProgressException {
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
try {
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) throws IabHelper.IabAsyncInProgressException {
if (result.isFailure()) {
// Handle failure
} else {
mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU), mConsumeFinishedListener);
}
}
};
public void buyClick(View view) throws IabHelper.IabAsyncInProgressException {
mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
mPurchaseFinishedListener, "mypurchasetoken");
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,
Purchase purchase) throws IabHelper.IabAsyncInProgressException {
if (result.isFailure()) {
// Handle error
return;
} else if (purchase.getSku().equals(ITEM_SKU)) {
btnPurchase.setEnabled(false);
btnPurchase.setBackgroundResource(R.drawable.purchasepressed);
test.setText("IT WORKS!!!");
}
}
};
I was under the impression that after purchase.getSKU().equals(ITEM_SKU)
you put whatever code should be executed if the purchase was successful.
As you can see here, if the purchase is successful, my purchase button should be disabled and change its background image. Also I added a test text label to see if the error was somewhere else in my code.
When I run the code on my phone, I get the purchase dialog and the success, but the button and text don't change.
Please help.
I am trying to display an user who posted something to the app, I have been able to retrieve the Content of the post but not the user. However the User is being saved because in my IOS version I can Clearly see the Posts I have made to test the App out. I need to display the user however the user Pointer<_user>does not save as a string.
How would I get the username behind the pointer?
IOS Version:
var findUser:PFQuery = PFUser.query()
findUser.whereKey("objectId", equalTo: posts.objectForKey("user").objectId)
Posts Class:
#ParseClassName("Posts")
public class Posts extends ParseObject {
public ParseUser getUser() {
return getParseUser("user");
}
public void setUser(ParseUser value) {
put("user", value);
}
public String getContent(){
return getString("content");
}
public void setContent(String content){
put("content", content);
}
#Override
public String toString(){
return getString("user") + "\n" + getString("content");
}
}
List Activity:
List<Posts> posts = new ArrayList<Posts>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parse_list);
ParseQuery<Posts> query = new ParseQuery<Posts>("Posts");
query.orderByDescending("createdAt");
query.findInBackground(new FindCallback<Posts>() {
#Override
public void done(List<Posts> list, ParseException e) {
if (e != null) {
Toast.makeText(ParseListActivity.this, "Error " + e, Toast.LENGTH_SHORT).show();
}
for (Posts post : list) {
Posts newPost = new Posts();
newPost.setUser(post.getUser());
newPost.setContent(post.getContent());
posts.add(newPost);
}
ArrayAdapter<Posts> adapter = new ArrayAdapter<Posts>(ParseListActivity.this, android.R.layout.simple_list_item_1, posts);
setListAdapter(adapter);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
/*
* Creating posts and refreshing the list will be controlled from the Action
* Bar.
*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh: {
updatePostList();
break;
}
case R.id.action_new: {
newPost();
break;
}
}
return super.onOptionsItemSelected(item);
}
private void newPost() {
Intent i = new Intent(this, newPost.class);
startActivityForResult(i, 0);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
// If a new post has been added, update
// the list of posts
updatePostList();
}
}
private void updatePostList() {
ParseQuery<Posts> query = new ParseQuery<Posts>("Posts");
query.orderByDescending("createdAt");
query.findInBackground(new FindCallback<Posts>() {
#Override
public void done(List<Posts> list, ParseException e) {
if (e != null) {
Toast.makeText(ParseListActivity.this, "Error " + e, Toast.LENGTH_SHORT).show();
}
for (Posts post : list) {
Posts newPost = new Posts();
newPost.setContent(post.getContent());
posts.add(newPost);
}
ArrayAdapter<Posts> adapter = new ArrayAdapter<Posts>(ParseListActivity.this, android.R.layout.simple_list_item_1, posts);
setListAdapter(adapter);
}
});
}
}
Im trying to add in app billing that will allow the user to make a purchase as many times as they like (no limit). Therefore it must be consumed. The first time I run the code on a new device it works fine and the test purchase is made successfully. However it fails to be consumed and doesnt let me make another purchase. The problem seems to be in this method, as it always ends up with result.isFailure() thus, the purchase is not consumed (and can only be made once).
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Toast.makeText(getApplicationContext(), "Failed to make purchase.", Toast.LENGTH_LONG).show();
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
consumeItem();
}
}
};
Does anyone know how I can fix the problem?
Here is the rest of the code:
Preference removeAds = (Preference) findPreference("inAppBilling");
removeAds.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mHelper.launchPurchaseFlow(About.this, ITEM_SKU, 10001, mPurchaseFinishedListener, "mypurchasetoken");
return true;
}
});
#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()) {
Toast.makeText(getApplicationContext(), "Failed to make purchase.", Toast.LENGTH_LONG).show();
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
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), mConsumeFinishedListener);
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
CustomAlerts.showBasicAlert("Thanks", "We appreciate your support.", About.this);
} else {
// handle error
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
You need to query the users inventory on app start. If there are any purchased but not yet redeemed products in it, you can just redeem them at this point. Here's the docu for retrieving it.
I have this code.. The only working here is the Login... I want to achieve the Publish to wall or feed dialog.. I have here the code for the wall post but It still not working.. Any help will be appreciated... I followed this link for my Login
[a link] http://www.kpbird.com/2013/03/android-login-using-facebook-sdk-30.html
I am trying to embed the post status in this Login..
public class FacebookActivity extends FragmentActivity {
private Button publishButton;
private String TAG = "FacebookActivity";
private TextView lblEmail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook_activity);
lblEmail = (TextView) findViewById(R.id.lblEmail);
LoginButton authButton = (LoginButton) findViewById(R.id.authButton);
authButton.setOnErrorListener(new OnErrorListener(){
#Override
public void onError(FacebookException error) {
Log.i(TAG, "Error " + error.getMessage());
}
// TODO Auto-generated method stub
});
// set permission list, Don't forget to add email
authButton.setReadPermissions(Arrays.asList("basic_info","email"));
// session state call back event
authButton.setSessionStatusCallback(new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.i(TAG,"Access Token"+ session.getAccessToken());
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,Response response) {
if (user != null) {
Log.i(TAG,"User ID "+ user.getId());
Log.i(TAG,"Email "+ user.asMap().get("email"));
lblEmail.setText(user.asMap().get("email").toString());
}
}
});
publishButton.setVisibility(View.VISIBLE);
}
else if (state.isClosed()) {
publishButton.setVisibility(View.INVISIBLE);
}
}
});
publishButton = (Button) findViewById(R.id.publishButton);
publishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
publishFeedDialog();
}
});
}
private void publishFeedDialog() {
Bundle params = new Bundle();
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
params.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(getActivity(),
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(getActivity(),
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(getActivity().getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.build();
feedDialog.show();
}
protected ContextWrapper getActivity() {
// TODO Auto-generated method stub
return null;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
}