Migrated to Play billing v4
This commit is contained in:
parent
824e77f59b
commit
5fa3b8febc
4 changed files with 52 additions and 136 deletions
|
@ -154,7 +154,7 @@ dependencies {
|
||||||
|
|
||||||
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5'
|
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5'
|
||||||
implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3'
|
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.r0adkll:slidableactivity:2.1.0'
|
||||||
implementation 'com.heinrichreimersoftware:material-intro:2.0.0'
|
implementation 'com.heinrichreimersoftware:material-intro:2.0.0'
|
||||||
implementation 'com.github.dhaval2404:imagepicker:1.7.1'
|
implementation 'com.github.dhaval2404:imagepicker:1.7.1'
|
||||||
|
|
|
@ -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.Constants.PRO_VERSION_PRODUCT_ID
|
||||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
|
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
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.android.ext.koin.androidContext
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class App : Application() {
|
||||||
billingProcessor = BillingProcessor(
|
billingProcessor = BillingProcessor(
|
||||||
this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY,
|
this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY,
|
||||||
object : BillingProcessor.IBillingHandler {
|
object : BillingProcessor.IBillingHandler {
|
||||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {}
|
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {}
|
||||||
|
|
||||||
override fun onPurchaseHistoryRestored() {
|
override fun onPurchaseHistoryRestored() {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
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.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
|
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
import com.anjlab.android.iab.v3.BillingProcessor
|
||||||
import com.anjlab.android.iab.v3.TransactionDetails
|
import com.anjlab.android.iab.v3.PurchaseInfo
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
|
|
||||||
class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
|
|
||||||
private lateinit var binding: ActivityProVersionBinding
|
private lateinit var binding: ActivityProVersionBinding
|
||||||
private lateinit var billingProcessor: BillingProcessor
|
private lateinit var billingProcessor: BillingProcessor
|
||||||
private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
|
@ -58,10 +54,8 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
MaterialUtil.setTint(binding.purchaseButton, true)
|
MaterialUtil.setTint(binding.purchaseButton, true)
|
||||||
|
|
||||||
binding.restoreButton.setOnClickListener {
|
binding.restoreButton.setOnClickListener {
|
||||||
if (restorePurchaseAsyncTask == null || restorePurchaseAsyncTask!!.status != AsyncTask.Status.RUNNING) {
|
|
||||||
restorePurchase()
|
restorePurchase()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
binding.purchaseButton.setOnClickListener {
|
binding.purchaseButton.setOnClickListener {
|
||||||
billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID)
|
billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID)
|
||||||
}
|
}
|
||||||
|
@ -70,13 +64,25 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun restorePurchase() {
|
private fun restorePurchase() {
|
||||||
if (restorePurchaseAsyncTask != null) {
|
Toast.makeText(this, R.string.restoring_purchase, Toast.LENGTH_SHORT)
|
||||||
restorePurchaseAsyncTask!!.cancel(false)
|
.show()
|
||||||
}
|
billingProcessor.loadOwnedPurchasesFromGoogleAsync(object :
|
||||||
restorePurchaseAsyncTask = RestorePurchaseAsyncTask(this).execute()
|
BillingProcessor.IPurchasesResponseListener {
|
||||||
|
override fun onPurchasesSuccess() {
|
||||||
|
onPurchaseHistoryRestored()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
override fun onPurchasesError() {
|
||||||
|
Toast.makeText(
|
||||||
|
this@PurchaseActivity,
|
||||||
|
R.string.could_not_restore_purchase,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {
|
||||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
||||||
setResult(RESULT_OK)
|
setResult(RESULT_OK)
|
||||||
}
|
}
|
||||||
|
@ -103,12 +109,6 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
binding.purchaseButton.isEnabled = true
|
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 {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
android.R.id.home -> finish()
|
android.R.id.home -> finish()
|
||||||
|
@ -121,52 +121,6 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RestorePurchaseAsyncTask(purchaseActivity: PurchaseActivity) :
|
|
||||||
AsyncTask<Void, Void, Boolean>() {
|
|
||||||
|
|
||||||
private val buyActivityWeakReference: WeakReference<PurchaseActivity> = 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 {
|
companion object {
|
||||||
private const val TAG: String = "PurchaseActivity"
|
private const val TAG: String = "PurchaseActivity"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -27,6 +25,7 @@ import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
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.textColorPrimary
|
||||||
import code.name.monkey.retromusic.extensions.textColorSecondary
|
import code.name.monkey.retromusic.extensions.textColorSecondary
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
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.SkuDetails
|
||||||
import com.anjlab.android.iab.v3.TransactionDetails
|
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
|
@ -53,11 +51,9 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = SupportDevelopmentActivity::class.java.simpleName
|
val TAG: String = SupportDevelopmentActivity::class.java.simpleName
|
||||||
const val DONATION_PRODUCT_IDS = R.array.donation_ids
|
const val DONATION_PRODUCT_IDS = R.array.donation_ids
|
||||||
private const val TEZ_REQUEST_CODE = 123
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var billingProcessor: BillingProcessor? = null
|
var billingProcessor: BillingProcessor? = null
|
||||||
private var skuDetailsLoadAsyncTask: AsyncTask<*, *, *>? = null
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == android.R.id.home) {
|
if (item.itemId == android.R.id.home) {
|
||||||
|
@ -99,13 +95,35 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSkuDetails() {
|
private fun loadSkuDetails() {
|
||||||
if (skuDetailsLoadAsyncTask != null) {
|
binding.progressContainer.isVisible = true
|
||||||
skuDetailsLoadAsyncTask!!.cancel(false)
|
binding.recyclerView.isVisible = false
|
||||||
}
|
val ids =
|
||||||
skuDetailsLoadAsyncTask = SkuDetailsLoadAsyncTask(this).execute()
|
resources.getStringArray(DONATION_PRODUCT_IDS)
|
||||||
|
billingProcessor!!.getPurchaseListingDetailsAsync(
|
||||||
|
ArrayList(listOf(*ids)),
|
||||||
|
object : BillingProcessor.ISkuDetailsResponseListener {
|
||||||
|
override fun onSkuDetailsResponse(skuDetails: MutableList<SkuDetails>?) {
|
||||||
|
if (skuDetails == null || skuDetails.isEmpty()) {
|
||||||
|
binding.progressContainer.isVisible = false
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
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: PurchaseInfo?) {
|
||||||
// loadSkuDetails();
|
// loadSkuDetails();
|
||||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
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()
|
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() {
|
override fun onDestroy() {
|
||||||
billingProcessor?.release()
|
billingProcessor?.release()
|
||||||
skuDetailsLoadAsyncTask?.cancel(true)
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SkuDetailsLoadAsyncTask(supportDevelopmentActivity: SupportDevelopmentActivity) :
|
|
||||||
AsyncTask<Void, Void, List<SkuDetails>>() {
|
|
||||||
|
|
||||||
private val weakReference: WeakReference<SupportDevelopmentActivity> = 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<SkuDetails>? {
|
|
||||||
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<SkuDetails>?) {
|
|
||||||
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(
|
class SkuDetailsAdapter(
|
||||||
private var donationsDialog: SupportDevelopmentActivity,
|
private var donationsDialog: SupportDevelopmentActivity,
|
||||||
objects: List<SkuDetails>
|
objects: List<SkuDetails>
|
||||||
|
@ -221,7 +183,7 @@ class SkuDetailsAdapter(
|
||||||
viewHolder.title.text = skuDetails.title.replace("Music Player - MP3 Player - Retro", "")
|
viewHolder.title.text = skuDetails.title.replace("Music Player - MP3 Player - Retro", "")
|
||||||
.trim { it <= ' ' }
|
.trim { it <= ' ' }
|
||||||
viewHolder.text.text = skuDetails.description
|
viewHolder.text.text = skuDetails.description
|
||||||
viewHolder.text.visibility = View.GONE
|
viewHolder.text.isVisible = false
|
||||||
viewHolder.price.text = skuDetails.priceText
|
viewHolder.price.text = skuDetails.priceText
|
||||||
viewHolder.image.setImageResource(getIcon(i))
|
viewHolder.image.setImageResource(getIcon(i))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue