diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4bce4cd4..852bd377 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -153,13 +153,16 @@ android { flavorDimensions += "channel" productFlavors { - create("nongoogle") { + create("nonGoogle") { dimension = "channel" isDefault = true } create("google") { dimension = "channel" } + create("noUpdater") { + dimension = "channel" + } } compileOptions { @@ -238,4 +241,7 @@ dependencies { val googleImplementation by configurations googleImplementation(libs.billingclient) + + val noUpdaterImplementation by configurations + noUpdaterImplementation(libs.billingclient) } diff --git a/app/src/main/java/remix/myplayer/App.kt b/app/src/main/java/remix/myplayer/App.kt index 5062d90a..78ebbcd8 100644 --- a/app/src/main/java/remix/myplayer/App.kt +++ b/app/src/main/java/remix/myplayer/App.kt @@ -154,5 +154,7 @@ class App : MultiDexApplication() { //是否是googlePlay版本 val IS_GOOGLEPLAY = !BuildConfig.DEBUG && BuildConfig.FLAVOR == "google" + + val ENABLE_UPDATER = BuildConfig.FLAVOR == "nonGoogle" } } \ No newline at end of file diff --git a/app/src/main/java/remix/myplayer/ui/activity/MainActivity.kt b/app/src/main/java/remix/myplayer/ui/activity/MainActivity.kt index 9b7be8e9..7b6c6936 100644 --- a/app/src/main/java/remix/myplayer/ui/activity/MainActivity.kt +++ b/app/src/main/java/remix/myplayer/ui/activity/MainActivity.kt @@ -28,7 +28,7 @@ import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.soundcloud.android.crop.Crop import remix.myplayer.App -import remix.myplayer.App.Companion.IS_GOOGLEPLAY +import remix.myplayer.App.Companion.ENABLE_UPDATER import remix.myplayer.R import remix.myplayer.bean.misc.CustomCover import remix.myplayer.bean.misc.Library @@ -699,7 +699,7 @@ class MainActivity : MenuActivity(), View.OnClickListener { } private fun checkUpdate() { - if (!IS_GOOGLEPLAY && !alreadyCheck) { + if (ENABLE_UPDATER && !alreadyCheck) { UpdateAgent.forceCheck = false UpdateAgent.listener = UpdateListener(this) alreadyCheck = true diff --git a/app/src/main/java/remix/myplayer/ui/activity/SettingActivity.kt b/app/src/main/java/remix/myplayer/ui/activity/SettingActivity.kt index b9d58290..e8006a60 100644 --- a/app/src/main/java/remix/myplayer/ui/activity/SettingActivity.kt +++ b/app/src/main/java/remix/myplayer/ui/activity/SettingActivity.kt @@ -32,6 +32,7 @@ import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import remix.myplayer.App.Companion.ENABLE_UPDATER import remix.myplayer.App.Companion.IS_GOOGLEPLAY import remix.myplayer.BuildConfig import remix.myplayer.R @@ -406,7 +407,7 @@ class SettingActivity : ToolbarActivity(), ColorChooserDialog.ColorCallback, } }.start() - if (IS_GOOGLEPLAY) { + if (!ENABLE_UPDATER) { binding.settingUpdateContainer.visibility = View.GONE } diff --git a/app/src/noupdater/AndroidManifest.xml b/app/src/noupdater/AndroidManifest.xml new file mode 100644 index 00000000..17b02a56 --- /dev/null +++ b/app/src/noupdater/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/noupdater/kotlin/remix/myplayer/ui/activity/SupportActivity.kt b/app/src/noupdater/kotlin/remix/myplayer/ui/activity/SupportActivity.kt new file mode 100644 index 00000000..b419215b --- /dev/null +++ b/app/src/noupdater/kotlin/remix/myplayer/ui/activity/SupportActivity.kt @@ -0,0 +1,244 @@ +package remix.myplayer.ui.activity + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.GridLayoutManager +import com.android.billingclient.api.* +import com.android.billingclient.api.BillingClient.ProductType +import com.android.billingclient.api.QueryProductDetailsParams.Product +import kotlinx.coroutines.launch +import remix.myplayer.App +import remix.myplayer.R +import remix.myplayer.bean.misc.Purchase +import remix.myplayer.databinding.ActivitySupportDevelopBinding +import remix.myplayer.misc.interfaces.OnItemClickListener +import remix.myplayer.theme.Theme +import remix.myplayer.ui.adapter.PurchaseAdapter +import remix.myplayer.util.AlipayUtil +import remix.myplayer.util.ToastUtil +import remix.myplayer.util.Util +import timber.log.Timber + +class SupportActivity : ToolbarActivity(), BillingClientStateListener, PurchasesUpdatedListener, + ProductDetailsResponseListener { + private lateinit var binding: ActivitySupportDevelopBinding + + private val adapter: PurchaseAdapter by lazy { + PurchaseAdapter(R.layout.item_support) + } + + private val SKU_IDS = arrayListOf("price_3", "price_8", "price_15", "price_25", "price_40") + + private val billingClient by lazy { + BillingClient.newBuilder(this) + .enablePendingPurchases() + .setListener(this) + .build() + } + private val productDetails = ArrayList() + private val googlePlay = App.IS_GOOGLEPLAY + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivitySupportDevelopBinding.inflate(layoutInflater) + setContentView(binding.root) + setUpToolbar(getString(R.string.support_develop)) + + val beans = ArrayList() + if (!googlePlay) { + beans.add(Purchase("wechat", "icon_wechat_donate", getString(R.string.wechat), "")) + beans.add(Purchase("alipay", "icon_alipay_donate", getString(R.string.alipay), "")) + beans.add(Purchase("paypal", "icon_paypal_donate", getString(R.string.paypal), "")) + } + + adapter.setDataList(beans) + adapter.onItemClickListener = object : OnItemClickListener { + override fun onItemLongClick(view: View?, position: Int) { + } + + override fun onItemClick(view: View?, position: Int) { + if (googlePlay) { + launchBillingFlow(productDetails.getOrNull(position) ?: return) + } else { + when (position) { + 0 -> { + //保存微信图片 + launch { + Util.saveToAlbum( + this@SupportActivity, + R.drawable.icon_wechat_qrcode, + "wechat_qrCode.png" + ) + } + } + 1 -> { + Theme.getBaseDialog(this@SupportActivity) + .title(R.string.support_develop) + .positiveText(R.string.jump_alipay_account) + .negativeText(R.string.cancel) + .content(R.string.donate_tip) + .onPositive { _, _ -> AlipayUtil.startAlipayClient(this@SupportActivity as Activity) } + .show() + } + 2 -> { + val intent = Intent("android.intent.action.VIEW") + intent.data = Uri.parse("https://www.paypal.me/rRemix") + Util.startActivitySafely(this@SupportActivity, intent) + } + else -> { + launchBillingFlow(productDetails.getOrNull(position - 3) ?: return) + } + } + } + + } + } + + binding.recyclerView.layoutManager = GridLayoutManager(this, 2) + binding.recyclerView.adapter = adapter + +// loading = Theme.getBaseDialog(this) +// .title(R.string.loading) +// .content(R.string.please_wait) +// .canceledOnTouchOutside(false) +// .progress(true, 0) +// .progressIndeterminateStyle(false).build() + + billingClient.startConnection(this) + + if (!googlePlay) { + binding.ad.visibility = View.VISIBLE + binding.adContent.text = """ + 如果你的手机并未下载过"快手极速版",并且是新用户,可通过以下步骤支持开发者: + 一.在安卓应用商店或AppStore下载"快手极速版" + 二.注册并登陆账号(未登录过的微信\QQ\手机号码任意一种方式均可) + 三.点左上角"三"或者放大镜扫描下方二维码(可长按保存) + 四.半小时之内观看至少一分钟的视频即可帮助开发者获得奖励。另外,如果用户在第二天和连续七天观看一分钟的视频,开发者都可以获得奖励 + """.trimIndent() + binding.adQrcode.setOnLongClickListener { + launch { + Util.saveToAlbum(this@SupportActivity, R.drawable.ad_qrcode, "a_ad_qrCode.png") + } + return@setOnLongClickListener true + } + } else { + binding.ad.visibility = View.GONE + } + } + + private fun launchBillingFlow(productDetails: ProductDetails) { + billingClient.launchBillingFlow( + this, BillingFlowParams.newBuilder() + .setProductDetailsParamsList( + listOf( + BillingFlowParams.ProductDetailsParams.newBuilder() + .setProductDetails(productDetails) + .build() + ) + ) + .build() + ) + } + + override fun onBillingSetupFinished(billingResult: BillingResult) { + Timber.v("onBillingSetupFinished: $billingResult") + if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) { + return + } + + // query product details + val params = QueryProductDetailsParams.newBuilder() + .setProductList(SKU_IDS.map { + Product.newBuilder() + .setProductId(it) + .setProductType(ProductType.INAPP) + .build() + }) + .build() + billingClient.queryProductDetailsAsync(params, this) + + // query purchases +// billingClient.queryPurchasesAsync( +// QueryPurchasesParams.newBuilder().build() +// ) { billingResult1, purchases -> +// if (billingResult1.responseCode == BillingClient.BillingResponseCode.OK && purchases.isNotEmpty()) { +// purchases.forEach { +// handlePurchase(it) +// } +// } +// } + } + + override fun onBillingServiceDisconnected() { + Timber.v("onBillingServiceDisconnected") + } + + override fun onProductDetailsResponse( + result: BillingResult, + details: MutableList + ) { + if (details.isEmpty()) { + return + } + val beans = ArrayList() + details.sortWith { o1, o2 -> + o1!!.oneTimePurchaseOfferDetails!!.priceAmountMicros.compareTo(o2!!.oneTimePurchaseOfferDetails!!.priceAmountMicros) + } + productDetails.addAll(details) + details.forEach { + beans.add( + Purchase( + it.productId, + "", + it.title, + it.oneTimePurchaseOfferDetails!!.formattedPrice + ) + ) + } + adapter.dataList.addAll(beans) + binding.recyclerView.post { + adapter.notifyDataSetChanged() + } + } + + override fun onPurchasesUpdated( + billingResult: BillingResult, + purchases: MutableList? + ) { + Timber.v("onPurchasesUpdated: $billingResult") + if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + for (purchase in purchases) { + handlePurchase(purchase) + } + } else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) { + Timber.v("user cancel") + } else { + Timber.v("other error") +// if (googlePlay) { +// ToastUtil.show( +// this, +// R.string.error_occur, +// "code = ${billingResult.responseCode} msg = ${billingResult.debugMessage}" +// ) +// } + } + } + + private fun handlePurchase(purchase: com.android.billingclient.api.Purchase) { + billingClient.consumeAsync( + ConsumeParams.newBuilder() + .setPurchaseToken(purchase.purchaseToken) + .build() + ) { result, purchaseToken -> + Timber.v("handlePurchase, result: $result") + if (result.responseCode == BillingClient.BillingResponseCode.OK) { + ToastUtil.show(this@SupportActivity, R.string.thank_you) + } else { + ToastUtil.show(this@SupportActivity, R.string.payment_failure) + } + } + } +} \ No newline at end of file