i implemented google in app billing and added a subscription using google documentation, the first try i pressed the button but launchpurchaseflow was not launched with no reason apparently because the debug console said nothing about that, then i tried to close and open again the app and that time was launched successfully, but when i tried again the launch didn't happen, sometimes happen sometimes not. Below is my code
public class Screenmain extends AppCompatActivity {
private InterstitialAd mIterstitialAd;
private Button Premium;
private BillingClient billingClient;
Prefs prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screenmain);
Premium = (Button) findViewById(R.id.premium);
prefs = new Prefs(this);
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(new PurchasesUpdatedListener() {
#Override
public void onPurchasesUpdated(#NonNull BillingResult billingResult, #Nullable List<Purchase> list) {
if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK&&list!=null){
for (Purchase purchase : list){
verifySubPurchase(purchase);
}
}
}
}).build();
establishConnection();
if (prefs.getPremium() != 0){
premtext.setText("you are already subscribed, thank you very much");
}else {
premtext.setText("Subscribe to not show ads and help the app");
}
setAds();
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(#NonNull InitializationStatus initializationStatus) {
}
});
checkSubscription();
}
public void establishConnection(){
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingServiceDisconnected() {
establishConnection();
}
#Override
public void onBillingSetupFinished(#NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
showProducts();
}
}
});
}
public void showProducts(){
List<String> skuList = new ArrayList<>();
skuList.add("sub_premium");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(#NonNull BillingResult billingResult, #Nullable List<SkuDetails> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list!=null){
for (SkuDetails skuDetails : list){
if (skuDetails.getSku().equals("sub_premium")){
Premium.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
launchPurchaseFlow(skuDetails);
}
});
}
}
}
}
});
}
public void launchPurchaseFlow(SkuDetails skuDetails){
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
billingClient.launchBillingFlow(Screenmain.this, billingFlowParams);
}
public void verifySubPurchase(Purchase purchase){
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams
.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
#Override
public void onAcknowledgePurchaseResponse(#NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
Toast.makeText(Screenmain.this, "You are now a premium user, thank you very much", Toast.LENGTH_LONG).show();
prefs.setPremium(1);
}
}
});
}
#Override
protected void onResume() {
super.onResume();
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() {
#Override
public void onQueryPurchasesResponse(#NonNull BillingResult billingResult, #NonNull List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
for (Purchase purchase : list){
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()){
verifySubPurchase(purchase);
}
}
}
}
});
}
public void checkSubscription(){
billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener((billingResult, list) -> {}).build();
final BillingClient finalBillingClient = billingClient;
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingServiceDisconnected() {
}
#Override
public void onBillingSetupFinished(#NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
finalBillingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, (billingResult1, list) -> {
if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null){
int i = 0;
for (Purchase purchase : list){
if (purchase.getSkus().get(i).equals("sub_premium")){
prefs.setPremium(1);
}else {
prefs.setPremium(0);
}
i++;
}
}
});
}
}
});
}
#Override
protected void onRestart() {
super.onRestart();
checkSubscription();
}
public void setAds(){
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(this, "ca-app-pub-4616222415041493/5164995253", adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
super.onAdLoaded(interstitialAd);
mIterstitialAd = interstitialAd;
}
});
}
Related
I was using google app billing v3. I upgraded it to v4. GetSku() gave an error when I upgraded.
Doing this with getSkus() and "purchase.getSkus().contains(getResources().getString(R.string.Product_ID)) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED" fixed the error.
When I click and open the premium purchase page for the first time, the products and prices do not appear. When I leave the page and enter the 2nd and 3rd time, the products and prices appear. Both in-app product selling and subscription part have the same problem. The codes are the same.
I was not having this issue in v3. I had this problem after upgrading to v4. Where could the problem be?
private BillingClient billingClient;
ConsumeResponseListener listener ;
RecyclerView recyclerView;
Context context = this;
recyclerView = findViewById(R.id.recyler_product);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
recyclerView.setLayoutManager(layoutManager);
setupBillingClient();
private void loadProductToRecyclerView(List<SkuDetails> list) {
MyProductAdapter adapter = new MyProductAdapter(this,list,billingClient);
recyclerView.setAdapter(adapter);
}
private void setupBillingClient() {
listener = new ConsumeResponseListener() {
#Override
public void onConsumeResponse(BillingResult billingResult, String s) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
{
// "Consume OK"
}
}
};
billingClient = BillingClientSetup.getInstance(this,this);
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
{
// "Succes to connect billing"
List<Purchase> purchases = billingClient.queryPurchases(BillingClient.SkuType.INAPP)
.getPurchasesList();
handleItemAlreadyPuchase(purchases);
loadAllPurchasePackage();
}
else
Toast.makeText(context,
billingResult.getResponseCode(), Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingServiceDisconnected() {
Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
}
});
}
public void loadAllPurchasePackage(){
if (billingClient.isReady())
{
SkuDetailsParams params= SkuDetailsParams.newBuilder()
.setSkusList(Arrays.asList("product_example_1","product_example_2","product_example_3"))
.setType(BillingClient.SkuType.INAPP)
.build();
billingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK)
{
loadProductToRecyclerView(list);
}
else
Toast.makeText(context, "Failed:"+billingResult.getResponseCode(), Toast.LENGTH_SHORT).show();
}
});
}
}
private void handleItemAlreadyPuchase(List<Purchase> purchases) {
StringBuilder purchasedItem = new StringBuilder(txtpremium.getText()); // empty
for (Purchase purchase : purchases)
{
// if (purchase.getSku().equals("product_example_1")) // consume item
// if (purchase.getSkus().equals("product_example_1")) // consume item
if (purchase.getSkus().contains(getResources().getString(R.string.Product_ID)) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) // consume item
{
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.consumeAsync(consumeParams,listener);
product1savedatabase();
}
// if (purchase.getSku().equals("product_example_2")) // consume item
if (purchase.getSkus().contains(getResources().getString(R.string.Product_ID2)) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) // consume item
{
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.consumeAsync(consumeParams,listener);
product2savedatabase();
}
// purchasedItem.append("\n"+purchase.getSku())
purchasedItem.append("\n"+purchase.getSkus()).append("\n");
}
txtpremium.setVisibility(View.VISIBLE);
}
#Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
&& list != null){
handleItemAlreadyPuchase(list);
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED)
Toast.makeText(this, "Purchase canceled
", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "Failed:"+billingResult.getResponseCode(), Toast.LENGTH_SHORT).show();
}
MyProductAdapter :
public class MyProductAdapter extends RecyclerView.Adapter<MyProductAdapter .MyViewHolder> {
AppCompatActivity appCompatActivity ;
List<SkuDetails> skuDetailsList;
BillingClient billingClient;
public MyProductAdapter (AppCompatActivity appCompatActivity, List<SkuDetails> skuDetailsList, BillingClient billingClient) {
this.appCompatActivity = appCompatActivity;
this.skuDetailsList = skuDetailsList;
this.billingClient = billingClient;
}
#NonNull
#Override
public MyProductAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
return new MyProductAdapter.MyViewHolder(LayoutInflater.from(appCompatActivity.getBaseContext())
.inflate(R.layout.layout_product_display,parent,false));
}
#Override
public void onBindViewHolder(#NonNull MyProductAdapter.MyViewHolder myViewHolder, int position) {
myViewHolder.txt_product_name.setText(skuDetailsList.get(position).getTitle().substring(0,8));
myViewHolder.txt_price.setText(skuDetailsList.get(position).getPrice());
myViewHolder.setListener(new IRecylerClickListener() {
#Override
public void onClick(View view, int position) {
// //Launch billing flow
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetailsList.get(position))
.build();
int reponse = billingClient.launchBillingFlow(appCompatActivity,billingFlowParams)
.getResponseCode();
switch (reponse)
{
case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE:
Toast.makeText(appCompatActivity, "BILLING UNAVAILABLE", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
Toast.makeText(appCompatActivity, "DEVELOPER ERROR", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED:
Toast.makeText(appCompatActivity, "FEATURE NOT SUPPORTED", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
Toast.makeText(appCompatActivity, "ITEM ALREADY OWNED", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED:
Toast.makeText(appCompatActivity, "SERVICE DISCONNECTED", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.SERVICE_TIMEOUT:
Toast.makeText(appCompatActivity, "SERVICE TIMEOUT", Toast.LENGTH_LONG).show();
break;
case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE:
Toast.makeText(appCompatActivity, "ITEM UNAVAILABLE", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
});
}
#Override
public int getItemCount() {
return skuDetailsList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txt_product_name, txt_price , txt_description ;
IRecylerClickListener listener;
public void setListener(IRecylerClickListener listener) {
this.listener = listener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
txt_price = itemView.findViewById(R.id.txt_pricealtin);
txt_product_name = itemView.findViewById(R.id.txt_product_namealtin);
itemView.setOnClickListener(this);
}
public void onClick(View view){
listener.onClick(view,getAdapterPosition());
}
}
While the Payments Successful dialog is not closed, the user closes the application, as a result, the money is withdrawn and Google considers the transaction USER_CANCELED how to make it work even if the user kills the application ?
public class MyFragment extends Fragment{
private MyPresenter presenter;
boolean needUpdateCoins = false;
private BillingClient mBillingClient;
private Map<String, SkuDetails> mSkuDetailsMap;
private static final String 1_SKU_ID = "1";
private static final String 2_SKU_ID = "2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new MyPresenter(this);
initBillingClient();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.Myfragment, container, false);
unbinder = ButterKnife.bind(this, view);
mSkuDetailsMap = new HashMap<>();
return view;
}
private void initBillingClient(){
mBillingClient = BillingClient.newBuilder(getActivity())
.enablePendingPurchases().setListener((billingResult, purchases) -> {
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
for(Purchase purchase:purchases){
handlePurchase(purchase);
}
}
}).build();
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
querySkuDetails();
}
}
#Override
public void onBillingServiceDisconnected() {}
});
}
private void querySkuDetails() {
SkuDetailsParams.Builder skuDetailsParamsBuilder = SkuDetailsParams.newBuilder();
List<String> skuList = new ArrayList<>();
skuList.add(1_SKU_ID);
skuList.add(2_SKU_ID);
skuDetailsParamsBuilder.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(skuDetailsParamsBuilder.build(), (billingResult, skuDetailsList) -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (SkuDetails skuDetails : skuDetailsList) {
mSkuDetailsMap.put(skuDetails.getSku(), skuDetails);
}
}
});
}
void handlePurchase(Purchase purchase) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
if (!purchase.isAcknowledged()) {
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.setDeveloperPayload(purchase.getDeveloperPayload())
.build();
ConsumeResponseListener consumeResponseListener = (billingResult, purchaseToken) -> {
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
payComplete(purchase.getOrderId(), purchase.getPackageName(), purchase.getSku(), purchase.getPurchaseTime(), purchase.getPurchaseState(), purchase.getPurchaseToken());
}
};
mBillingClient.consumeAsync(consumeParams, consumeResponseListener);
}
}
}
public void launchBilling(String skuId) {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(mSkuDetailsMap.get(skuId))
.build();
mBillingClient.launchBillingFlow(getActivity(), billingFlowParams);
}
#Override
public void coinPackClick(CoinPack pack) {
String skuId = String.valueOf(pack.getId());
launchBilling(skuId);
}
private void payComplete(String orderId, String packageName, String productId, Long purchaseTime, int purchaseState, String purchaseToken){
presenter.buyCoin(orderId, packageName, productId, purchaseTime, purchaseState, purchaseToken);
}
Maybe I'm doing something wrong. Tell me, do you have any thoughts or opinions looking at this code?
When I just initiate the billing client for the inApp purchase, the app crash immediately at this line:
billingClient = BillingClient.newBuilder(Profileowner.this).setListener(this).build();
I have implemented the PurchasesUpdatedListener and went through the https://developer.android.com/google/play/billing/billing_library_overview
full code for billing below:
public void billing(){
//List<SkuDetails> skuDetailsList = null;
billingClient = BillingClient.newBuilder(Profileowner.this).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
Toast.makeText(getApplication(),"success to connect billing",Toast.LENGTH_SHORT).show();
}
else Toast.makeText(getApplication(),"fail to connect billing",Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingServiceDisconnected() {
Toast.makeText(getApplication(),"you are disconnected",Toast.LENGTH_SHORT).show();
}
});
//add a pay button
ImageButton pay = (ImageButton) findViewById(R.id.pay);
pay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (billingClient.isReady()){
SkuDetailsParams params = SkuDetailsParams.newBuilder()
.setSkusList(Arrays.asList("premium_3"))
.setType(BillingClient.SkuType.SUBS)
.build();
billingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
//something to add here
loadSkus(skuDetailsList);
}
else {
Toast.makeText(getApplication(),"cant query product",Toast.LENGTH_SHORT).show();
}
}
});
}
else {
Toast.makeText(getApplication(),"billing clinet not ready",Toast.LENGTH_SHORT).show();
}
}
});
}
private void loadSkus(List<SkuDetails> skuDetailsList) {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetailsList.get(0))
.build();
billingClient.launchBillingFlow(this, billingFlowParams);
}
I am working with paging library and I am struggling with the LiveData PagedList.
My paginated list is working properly but there is an scenario where it is not. I have RecyclerView + SwipeRefreshLayout when data is already shown in the list and I disable network and I try to swipe refresh all the data in the list is removed. How can I avoid that?
public class InterestsViewModel extends ViewModel {
private LiveData<PagedList<InterestItem>> mListInterests;
private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
private static final int PAGE_SIZE = 15;
private GroupsInterestsDataSourceFactory mGroupsInterestsDataSourceFactory;
public InterestsViewModel() {
Executor executor = Executors.newFixedThreadPool(5);
mGroupsInterestsDataSourceFactory = new GroupsInterestsDataSourceFactory(mCompositeDisposable);
PagedList.Config config = new PagedList.Config.Builder()
.setPageSize(PAGE_SIZE)
.setInitialLoadSizeHint(PAGE_SIZE)
.setEnablePlaceholders(true)
.build();
mListInterests = new LivePagedListBuilder<>(mGroupsInterestsDataSourceFactory,config)
.setFetchExecutor(executor)
.build();
}
public void retry() {
mGroupsInterestsDataSourceFactory.getGroupsInterestsDataSource().getValue().retry();
}
public void refresh() {
mGroupsInterestsDataSourceFactory.getGroupsInterestsDataSource().getValue().invalidate();
}
public LiveData<NetworkState> getNetworkState() {
return Transformations.switchMap(mGroupsInterestsDataSourceFactory.getGroupsInterestsDataSource(), new Function<GroupsInterestsDataSource, LiveData<NetworkState>>() {
#Override
public LiveData<NetworkState> apply(GroupsInterestsDataSource input) {
return input.getNetworkState();
}
});
}
public LiveData<NetworkState> getRefreshState() {
return Transformations.switchMap(mGroupsInterestsDataSourceFactory.getGroupsInterestsDataSource(), new Function<GroupsInterestsDataSource, LiveData<NetworkState>>() {
#Override
public LiveData<NetworkState> apply(GroupsInterestsDataSource input) {
return input.getInitialLoad();
}
});
}
public LiveData<PagedList<InterestItem>> getListInterests() {
return mListInterests;
}
#Override
protected void onCleared() {
super.onCleared();
mCompositeDisposable.dispose();
}
}
From the the fragment:
private void initAdapter() {
mAdapter = new InterestsAdapter(this);
mListInterest.setAdapter(mAdapter);
mInterestsViewModel.getListInterests().observe(this, new Observer<PagedList<InterestItem>>() {
#Override
public void onChanged(#Nullable PagedList<InterestItem> interestItems) {
mAdapter.submitList(interestItems);
}
});
mInterestsViewModel.getNetworkState().observe(this, new Observer<NetworkState>() {
#Override
public void onChanged(#Nullable NetworkState networkState) {
mAdapter.setNetworkState(networkState);
}
});
mInterestsViewModel.getRefreshState().observe(this, new Observer<NetworkState>() {
#Override
public void onChanged(#Nullable NetworkState networkState) {
if (networkState != null) {
if (mAdapter.getCurrentList() != null) {
if (networkState.getStatus()
== NetworkState.LOADED.getStatus() || networkState.getStatus()
== Status.FAILED)
mIsRefreshing = false;
if (mAdapter.getCurrentList().size() > 0) {
mSwipeRLInterests.setRefreshing(networkState.getStatus()
== NetworkState.LOADING.getStatus());
}
}
setInitialLoadingState(networkState);
}
}
});
}
#Override
public void retry() {
mInterestsViewModel.retry();
}
private void initSwipeToRefresh() {
mSwipeRLInterests.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mIsRefreshing = true;
mInterestsViewModel.refresh();
}
});
mSwipeRLInterests.setColorSchemeColors(getResources().getColor(R.color.colorPrimaryDark)
, getResources().getColor(R.color.colorPrimary)
, getResources().getColor(R.color.colorPrimaryDark));
}
I use this code for in-app billing in my project, this code works well but I can not check which item is purchased.
This is my code:
public class MainActivity extends AppCompatActivity implements PurchasesUpdatedListener {
private BillingClient mBillingClient;
#BindView(R.id.btn_three_buy_health)
Button btn_three_buy_health;
#BindView(R.id.btn_ten_buy_health)
Button btn_ten_buy_health;
#BindView(R.id.btn_twenty_buy_health)
Button btn_twenty_buy_health;
#BindView(R.id.btn_fifty_buy_health)
Button btn_fifty_buy_health;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mBillingClient = BillingClient.newBuilder(this).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponseCode) {
if (billingResponseCode == BillingClient.BillingResponse.OK) {
enableOrDisableButtons(true);
} else {
enableOrDisableButtons(false);
}
}
#Override
public void onBillingServiceDisconnected() {
enableOrDisableButtons(false);
}
});
}
private void enableOrDisableButtons(boolean isEnabled) {
btn_three_buy_health.setEnabled(isEnabled);
btn_ten_buy_health.setEnabled(isEnabled);
btn_twenty_buy_health.setEnabled(isEnabled);
btn_fifty_buy_health.setEnabled(isEnabled);
}
#Optional
#OnClick(R.id.btn_three_buy_health)
void buyThreeHealth(View view) {
buyProduct("5_buy_health");
}
#Optional
#OnClick(R.id.btn_ten_buy_health)
void buyTenHealth(View view) {
buyProduct("10_buy_health");
}
#Optional
#OnClick(R.id.btn_twenty_buy_health)
void buyTwentyHealth(View view) {
buyProduct("20_buy_health");
}
#Optional
#OnClick(R.id.btn_fifty_buy_health)
void buyFiftyHealth(View view) {
buySubscription("50_buy_health");
}
private void buyProduct(String skuId) {
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSku(skuId)
.setType(BillingClient.SkuType.INAPP)
.build();
mBillingClient.launchBillingFlow(this, flowParams);
}
private void buySubscription(String skuId) {
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSku(skuId)
.setType(BillingClient.SkuType.SUBS)
.build();
mBillingClient.launchBillingFlow(this, flowParams);
}
#Override
public void onPurchasesUpdated(int responseCode, #Nullable List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK
&& purchases != null) {
for (final Purchase purchase : purchases) {
mBillingClient.consumeAsync(purchase.getPurchaseToken(), new ConsumeResponseListener() {
#Override
public void onConsumeResponse(int responseCode, String purchaseToken) {
if (responseCode == BillingClient.BillingResponse.OK) {
Toast.makeText(MainActivity.this, "You bought health", Toast.LENGTH_SHORT).show();
}
}
});
}
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
billingCanceled();
} else {
billingCanceled();
}
}
private void billingCanceled() {
}
}
how Can I check whick item is purchased.
this toast appears in all purchases
Toast.makeText(MainActivity.this, "You bought health", Toast.LENGTH_SHORT).show();
but I want it to be like this
if a person buy 10 health toast should be like this
Toast.makeText(MainActivity.this, "You bought 10 health", Toast.LENGTH_SHORT).show();
if a person buy 20 health toast should be like this
Toast.makeText(MainActivity.this, "You bought 20 health", Toast.LENGTH_SHORT).show();
Also How to check if a user has a subscription when app start?
if the user has a subscription, the toast should appear in the beginning "You are gold member"
Sorry for my bad English.
Thanks.