From 5fa3b8febc1c517d3856896f8e95feff140ee09e Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 8 Nov 2021 11:08:52 +0530 Subject: [PATCH] Migrated to Play billing v4 --- app/build.gradle | 2 +- .../java/code/name/monkey/retromusic/App.kt | 4 +- .../retromusic/activities/PurchaseActivity.kt | 84 ++++------------ .../activities/SupportDevelopmentActivity.kt | 98 ++++++------------- 4 files changed, 52 insertions(+), 136 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a9fa3aca..8827023d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -154,7 +154,7 @@ dependencies { implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5' implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3' - implementation 'com.anjlab.android.iab.v3:library:1.1.0' + implementation 'com.anjlab.android.iab.v3:library:2.0.0' implementation 'com.r0adkll:slidableactivity:2.1.0' implementation 'com.heinrichreimersoftware:material-intro:2.0.0' implementation 'com.github.dhaval2404:imagepicker:1.7.1' diff --git a/app/src/main/java/code/name/monkey/retromusic/App.kt b/app/src/main/java/code/name/monkey/retromusic/App.kt index f7f56526..1b46996c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/App.kt +++ b/app/src/main/java/code/name/monkey/retromusic/App.kt @@ -21,7 +21,7 @@ import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager import com.anjlab.android.iab.v3.BillingProcessor -import com.anjlab.android.iab.v3.TransactionDetails +import com.anjlab.android.iab.v3.PurchaseInfo import org.koin.android.ext.koin.androidContext import org.koin.core.context.startKoin @@ -52,7 +52,7 @@ class App : Application() { billingProcessor = BillingProcessor( this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, object : BillingProcessor.IBillingHandler { - override fun onProductPurchased(productId: String, details: TransactionDetails?) {} + override fun onProductPurchased(productId: String, details: PurchaseInfo?) {} override fun onPurchaseHistoryRestored() { Toast.makeText( diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt index 2bd7ce42..1550ee3c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt @@ -14,10 +14,8 @@ */ package code.name.monkey.retromusic.activities -import android.content.Intent import android.content.res.ColorStateList import android.graphics.Color -import android.os.AsyncTask import android.os.Bundle import android.util.Log import android.view.MenuItem @@ -31,14 +29,12 @@ import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsBaseActivity import code.name.monkey.retromusic.databinding.ActivityProVersionBinding import com.anjlab.android.iab.v3.BillingProcessor -import com.anjlab.android.iab.v3.TransactionDetails -import java.lang.ref.WeakReference +import com.anjlab.android.iab.v3.PurchaseInfo class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { private lateinit var binding: ActivityProVersionBinding private lateinit var billingProcessor: BillingProcessor - private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null override fun onCreate(savedInstanceState: Bundle?) { setDrawUnderStatusBar() @@ -58,9 +54,7 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { MaterialUtil.setTint(binding.purchaseButton, true) binding.restoreButton.setOnClickListener { - if (restorePurchaseAsyncTask == null || restorePurchaseAsyncTask!!.status != AsyncTask.Status.RUNNING) { - restorePurchase() - } + restorePurchase() } binding.purchaseButton.setOnClickListener { billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID) @@ -70,13 +64,25 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { } private fun restorePurchase() { - if (restorePurchaseAsyncTask != null) { - restorePurchaseAsyncTask!!.cancel(false) - } - restorePurchaseAsyncTask = RestorePurchaseAsyncTask(this).execute() + Toast.makeText(this, R.string.restoring_purchase, Toast.LENGTH_SHORT) + .show() + billingProcessor.loadOwnedPurchasesFromGoogleAsync(object : + BillingProcessor.IPurchasesResponseListener { + override fun onPurchasesSuccess() { + onPurchaseHistoryRestored() + } + + override fun onPurchasesError() { + Toast.makeText( + this@PurchaseActivity, + R.string.could_not_restore_purchase, + Toast.LENGTH_SHORT + ).show() + } + }) } - override fun onProductPurchased(productId: String, details: TransactionDetails?) { + override fun onProductPurchased(productId: String, details: PurchaseInfo?) { Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show() setResult(RESULT_OK) } @@ -103,12 +109,6 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { binding.purchaseButton.isEnabled = true } - public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) { - super.onActivityResult(requestCode, resultCode, data) - } - } - override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { android.R.id.home -> finish() @@ -121,52 +121,6 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { super.onDestroy() } - private class RestorePurchaseAsyncTask(purchaseActivity: PurchaseActivity) : - AsyncTask() { - - private val buyActivityWeakReference: WeakReference = WeakReference( - purchaseActivity - ) - - override fun onPreExecute() { - super.onPreExecute() - val purchaseActivity = buyActivityWeakReference.get() - if (purchaseActivity != null) { - Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT) - .show() - } else { - cancel(false) - } - } - - override fun doInBackground(vararg params: Void): Boolean? { - val purchaseActivity = buyActivityWeakReference.get() - if (purchaseActivity != null) { - return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle() - } - cancel(false) - return null - } - - override fun onPostExecute(b: Boolean?) { - super.onPostExecute(b) - val purchaseActivity = buyActivityWeakReference.get() - if (purchaseActivity == null || b == null) { - return - } - - if (b) { - purchaseActivity.onPurchaseHistoryRestored() - } else { - Toast.makeText( - purchaseActivity, - R.string.could_not_restore_purchase, - Toast.LENGTH_SHORT - ).show() - } - } - } - companion object { private const val TAG: String = "PurchaseActivity" } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt index cbf6b408..128746fb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt @@ -14,9 +14,7 @@ */ package code.name.monkey.retromusic.activities -import android.content.Intent import android.graphics.Paint -import android.os.AsyncTask import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -27,6 +25,7 @@ import android.widget.TextView import android.widget.Toast import androidx.annotation.LayoutRes import androidx.appcompat.widget.AppCompatImageView +import androidx.core.view.isVisible import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -41,9 +40,8 @@ import code.name.monkey.retromusic.databinding.ActivityDonationBinding import code.name.monkey.retromusic.extensions.textColorPrimary import code.name.monkey.retromusic.extensions.textColorSecondary import com.anjlab.android.iab.v3.BillingProcessor +import com.anjlab.android.iab.v3.PurchaseInfo import com.anjlab.android.iab.v3.SkuDetails -import com.anjlab.android.iab.v3.TransactionDetails -import java.lang.ref.WeakReference import java.util.* class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { @@ -53,11 +51,9 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH companion object { val TAG: String = SupportDevelopmentActivity::class.java.simpleName const val DONATION_PRODUCT_IDS = R.array.donation_ids - private const val TEZ_REQUEST_CODE = 123 } var billingProcessor: BillingProcessor? = null - private var skuDetailsLoadAsyncTask: AsyncTask<*, *, *>? = null override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == android.R.id.home) { @@ -99,13 +95,35 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH } private fun loadSkuDetails() { - if (skuDetailsLoadAsyncTask != null) { - skuDetailsLoadAsyncTask!!.cancel(false) - } - skuDetailsLoadAsyncTask = SkuDetailsLoadAsyncTask(this).execute() + binding.progressContainer.isVisible = true + binding.recyclerView.isVisible = false + val ids = + resources.getStringArray(DONATION_PRODUCT_IDS) + billingProcessor!!.getPurchaseListingDetailsAsync( + ArrayList(listOf(*ids)), + object : BillingProcessor.ISkuDetailsResponseListener { + override fun onSkuDetailsResponse(skuDetails: MutableList?) { + if (skuDetails == null || skuDetails.isEmpty()) { + binding.progressContainer.isVisible = false + return + } + + binding.progressContainer.isVisible = false + binding.recyclerView.apply { + itemAnimator = DefaultItemAnimator() + layoutManager = GridLayoutManager(this@SupportDevelopmentActivity, 2) + adapter = SkuDetailsAdapter(this@SupportDevelopmentActivity, skuDetails) + isVisible = true + } + } + + override fun onSkuDetailsError(error: String?) { + Log.e(TAG, error.toString()) + } + }) } - override fun onProductPurchased(productId: String, details: TransactionDetails?) { + override fun onProductPurchased(productId: String, details: PurchaseInfo?) { // loadSkuDetails(); Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show() } @@ -119,68 +137,12 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show() } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) { - super.onActivityResult(requestCode, resultCode, data) - } - if (requestCode == TEZ_REQUEST_CODE) { - // Process based on the data in response. - // Log.d("result", data!!.getStringExtra("Status")) - } - } - override fun onDestroy() { billingProcessor?.release() - skuDetailsLoadAsyncTask?.cancel(true) super.onDestroy() } } -private class SkuDetailsLoadAsyncTask(supportDevelopmentActivity: SupportDevelopmentActivity) : - AsyncTask>() { - - private val weakReference: WeakReference = WeakReference( - supportDevelopmentActivity - ) - - override fun onPreExecute() { - super.onPreExecute() - val supportDevelopmentActivity = weakReference.get() ?: return - - supportDevelopmentActivity.binding.progressContainer.visibility = View.VISIBLE - supportDevelopmentActivity.binding.recyclerView.visibility = View.GONE - } - - override fun doInBackground(vararg params: Void): List? { - val dialog = weakReference.get() - if (dialog != null) { - val ids = - dialog.resources.getStringArray(SupportDevelopmentActivity.DONATION_PRODUCT_IDS) - return dialog.billingProcessor!!.getPurchaseListingDetails(ArrayList(Arrays.asList(*ids))) - } - cancel(false) - return null - } - - override fun onPostExecute(skuDetails: List?) { - super.onPostExecute(skuDetails) - val dialog = weakReference.get() ?: return - - if (skuDetails == null || skuDetails.isEmpty()) { - dialog.binding.progressContainer.visibility = View.GONE - return - } - - dialog.binding.progressContainer.visibility = View.GONE - dialog.binding.recyclerView.apply { - itemAnimator = DefaultItemAnimator() - layoutManager = GridLayoutManager(dialog, 2) - adapter = SkuDetailsAdapter(dialog, skuDetails) - visibility = View.VISIBLE - } - } -} - class SkuDetailsAdapter( private var donationsDialog: SupportDevelopmentActivity, objects: List @@ -221,7 +183,7 @@ class SkuDetailsAdapter( viewHolder.title.text = skuDetails.title.replace("Music Player - MP3 Player - Retro", "") .trim { it <= ' ' } viewHolder.text.text = skuDetails.description - viewHolder.text.visibility = View.GONE + viewHolder.text.isVisible = false viewHolder.price.text = skuDetails.priceText viewHolder.image.setImageResource(getIcon(i))