279 lines
11 KiB
Java
279 lines
11 KiB
Java
package app.fedilab.fedilabtube;
|
|
/* Copyright 2021 Thomas Schneider
|
|
*
|
|
* This file is a part of TubeLab
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
import android.os.Bundle;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
import androidx.fragment.app.Fragment;
|
|
import androidx.fragment.app.FragmentManager;
|
|
import androidx.fragment.app.FragmentStatePagerAdapter;
|
|
import androidx.viewpager.widget.PagerAdapter;
|
|
import androidx.viewpager.widget.ViewPager;
|
|
|
|
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
|
import com.android.billingclient.api.BillingClient;
|
|
import com.android.billingclient.api.BillingClientStateListener;
|
|
import com.android.billingclient.api.BillingResult;
|
|
import com.android.billingclient.api.ConsumeParams;
|
|
import com.android.billingclient.api.ConsumeResponseListener;
|
|
import com.android.billingclient.api.Purchase;
|
|
import com.android.billingclient.api.PurchasesUpdatedListener;
|
|
import com.android.billingclient.api.SkuDetailsParams;
|
|
import com.google.android.material.snackbar.Snackbar;
|
|
import com.google.android.material.tabs.TabLayout;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
|
|
import app.fedilab.fedilabtube.databinding.ActivityDonationBinding;
|
|
|
|
import app.fedilab.fedilabtube.fragment.MySubscriptionDonationsFragment;
|
|
import app.fedilab.fedilabtube.fragment.DonationsFragment;
|
|
|
|
|
|
public class DonationActivity extends AppCompatActivity implements PurchasesUpdatedListener {
|
|
|
|
|
|
DonationsFragment donationsFragment;
|
|
DonationsFragment subscriptionDonationsFragment;
|
|
MySubscriptionDonationsFragment mySubscriptionDonationsFragment;
|
|
private ActivityDonationBinding binding;
|
|
private BillingClient billingClient;
|
|
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
binding = ActivityDonationBinding.inflate(getLayoutInflater());
|
|
View view = binding.getRoot();
|
|
setContentView(view);
|
|
billingClient = BillingClient.newBuilder(this)
|
|
.setListener(this)
|
|
.enablePendingPurchases()
|
|
.build();
|
|
billingClient.startConnection(new BillingClientStateListener() {
|
|
@Override
|
|
public void onBillingSetupFinished(@NotNull BillingResult billingResult) {
|
|
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
|
// The BillingClient is ready. You can query purchases here.
|
|
donationsFragment.initialized(billingClient);
|
|
subscriptionDonationsFragment.initialized(billingClient);
|
|
|
|
List<Purchase> purchases = queryPurchases();
|
|
if (purchases != null) {
|
|
for (Purchase purchase : purchases) {
|
|
if (!purchase.isAutoRenewing()) {
|
|
ConsumeParams consumeParams =
|
|
ConsumeParams.newBuilder()
|
|
.setPurchaseToken(purchase.getPurchaseToken())
|
|
.build();
|
|
|
|
ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
|
|
//noinspection StatementWithEmptyBody
|
|
if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
|
// Handle the success of the consume operation.
|
|
}
|
|
};
|
|
billingClient.consumeAsync(consumeParams, listener);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onBillingServiceDisconnected() {
|
|
// Try to restart the connection on the next request to
|
|
// Google Play by calling the startConnection() method.
|
|
}
|
|
});
|
|
if (getSupportActionBar() != null)
|
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
donationsFragment = new DonationsFragment();
|
|
Bundle bundle1 = new Bundle();
|
|
bundle1.putSerializable("isSubscriptions", false);
|
|
donationsFragment.setArguments(bundle1);
|
|
|
|
|
|
subscriptionDonationsFragment = new DonationsFragment();
|
|
Bundle bundle2 = new Bundle();
|
|
bundle2.putSerializable("isSubscriptions", true);
|
|
subscriptionDonationsFragment.setArguments(bundle2);
|
|
|
|
mySubscriptionDonationsFragment = new MySubscriptionDonationsFragment();
|
|
|
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.one_time)));
|
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.subscriptions)));
|
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.my_subscriptions)));
|
|
binding.viewpager.setOffscreenPageLimit(3);
|
|
|
|
PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
|
|
binding.viewpager.setAdapter(mPagerAdapter);
|
|
binding.viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
@Override
|
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onPageSelected(int position) {
|
|
TabLayout.Tab tab = binding.tablayout.getTabAt(position);
|
|
if (tab != null)
|
|
tab.select();
|
|
}
|
|
|
|
@Override
|
|
public void onPageScrollStateChanged(int state) {
|
|
|
|
}
|
|
});
|
|
|
|
binding.tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
|
@Override
|
|
public void onTabSelected(TabLayout.Tab tab) {
|
|
binding.viewpager.setCurrentItem(tab.getPosition());
|
|
}
|
|
|
|
@Override
|
|
public void onTabUnselected(TabLayout.Tab tab) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onTabReselected(TabLayout.Tab tab) {
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
private List<Purchase> queryPurchases() {
|
|
Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
|
|
List<Purchase> purchases = purchasesResult.getPurchasesList();
|
|
List<String> isSubscriptions = new ArrayList<>();
|
|
HashMap<String, Purchase> map = new HashMap<>();
|
|
if (purchases != null) {
|
|
for (Purchase purchase : purchases) {
|
|
try {
|
|
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
|
JSONObject purchaseJson = new JSONObject(purchase.getOriginalJson());
|
|
String productId = purchaseJson.getString("productId");
|
|
isSubscriptions.add(productId);
|
|
map.put(productId, purchase);
|
|
}
|
|
} catch (JSONException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
SkuDetailsParams.Builder paramsSub = SkuDetailsParams.newBuilder();
|
|
paramsSub.setSkusList(isSubscriptions).setType(BillingClient.SkuType.SUBS);
|
|
billingClient.querySkuDetailsAsync(paramsSub.build(),
|
|
(billingResult2, skuDetailsList) -> mySubscriptionDonationsFragment.initialized(skuDetailsList, map, billingClient));
|
|
} else {
|
|
mySubscriptionDonationsFragment.initialized(new ArrayList<>(), map, billingClient);
|
|
}
|
|
return purchases;
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
if (item.getItemId() == android.R.id.home) {
|
|
finish();
|
|
return true;
|
|
}
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
|
|
@Override
|
|
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
|
|
String message;
|
|
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
|
|
&& purchases != null) {
|
|
for (Purchase purchase : purchases) {
|
|
if (!purchase.isAutoRenewing()) {
|
|
ConsumeParams consumeParams =
|
|
ConsumeParams.newBuilder()
|
|
.setPurchaseToken(purchase.getPurchaseToken())
|
|
.build();
|
|
|
|
ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
|
|
};
|
|
billingClient.consumeAsync(consumeParams, listener);
|
|
} else {
|
|
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
|
if (!purchase.isAcknowledged()) {
|
|
AcknowledgePurchaseParams acknowledgePurchaseParams =
|
|
AcknowledgePurchaseParams.newBuilder()
|
|
.setPurchaseToken(purchase.getPurchaseToken())
|
|
.build();
|
|
billingClient.acknowledgePurchase(acknowledgePurchaseParams, b -> {
|
|
});
|
|
}
|
|
}
|
|
|
|
queryPurchases();
|
|
}
|
|
}
|
|
message = getString(R.string.donation_succeeded_null);
|
|
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
|
|
message = getString(R.string.donation_cancelled);
|
|
} else {
|
|
message = getString(R.string.toast_error);
|
|
}
|
|
View parentLayout = findViewById(android.R.id.content);
|
|
Snackbar snackbar = Snackbar.make(parentLayout, message, Snackbar.LENGTH_INDEFINITE);
|
|
snackbar.setAction(R.string.close, view -> snackbar.dismiss());
|
|
snackbar.show();
|
|
}
|
|
|
|
|
|
/**
|
|
* Pager adapter for the 2 fragments
|
|
*/
|
|
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
|
|
|
|
ScreenSlidePagerAdapter(FragmentManager fm) {
|
|
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
|
}
|
|
|
|
@NotNull
|
|
@Override
|
|
public Fragment getItem(int position) {
|
|
if (position == 0) {
|
|
return donationsFragment;
|
|
} else if (position == 1) {
|
|
return subscriptionDonationsFragment;
|
|
} else {
|
|
return mySubscriptionDonationsFragment;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public int getCount() {
|
|
return 3;
|
|
}
|
|
}
|
|
}
|