From a35318ded23a58c35cca6ba999582244edfe269d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 17 Feb 2024 10:02:58 +0800 Subject: [PATCH] Remove in-app sponsor --- app/build.gradle | 2 - .../java/io/nekohasekai/sfa/bg/BoxService.kt | 5 +- .../io/nekohasekai/sfa/ui/MainActivity.kt | 2 - .../sfa/ui/main/SettingsFragment.kt | 4 +- .../nekohasekai/sfa/vendor/VendorInterface.kt | 2 - .../java/io/nekohasekai/sfa/vendor/Vendor.kt | 7 - .../java/io/nekohasekai/sfa/vendor/Vendor.kt | 180 ------------------ version.properties | 2 +- 8 files changed, 3 insertions(+), 201 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4ae0f9c..16c4609 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -113,8 +113,6 @@ dependencies { } implementation 'com.google.guava:guava:32.1.2-android' playImplementation 'com.google.android.play:app-update-ktx:2.1.0' - playImplementation "com.android.billingclient:billing:6.1.0" - playImplementation "com.android.billingclient:billing-ktx:6.1.0" } if (getProps("APPCENTER_TOKEN") != "") { diff --git a/app/src/main/java/io/nekohasekai/sfa/bg/BoxService.kt b/app/src/main/java/io/nekohasekai/sfa/bg/BoxService.kt index fe7f1d8..03cbbc1 100644 --- a/app/src/main/java/io/nekohasekai/sfa/bg/BoxService.kt +++ b/app/src/main/java/io/nekohasekai/sfa/bg/BoxService.kt @@ -21,7 +21,6 @@ import io.nekohasekai.libbox.Libbox import io.nekohasekai.libbox.PlatformInterface import io.nekohasekai.libbox.SystemProxyStatus import io.nekohasekai.sfa.Application -import io.nekohasekai.sfa.BuildConfig import io.nekohasekai.sfa.R import io.nekohasekai.sfa.constant.Action import io.nekohasekai.sfa.constant.Alert @@ -53,9 +52,7 @@ class BoxService( val tempDir = Application.application.cacheDir tempDir.mkdirs() Libbox.setup(baseDir.path, workingDir.path, tempDir.path, false) - if (!BuildConfig.DEBUG) { - Libbox.redirectStderr(File(workingDir, "stderr.log").path) - } + Libbox.redirectStderr(File(workingDir, "stderr.log").path) initializeOnce = true return } diff --git a/app/src/main/java/io/nekohasekai/sfa/ui/MainActivity.kt b/app/src/main/java/io/nekohasekai/sfa/ui/MainActivity.kt index 7b520e7..dee84c1 100644 --- a/app/src/main/java/io/nekohasekai/sfa/ui/MainActivity.kt +++ b/app/src/main/java/io/nekohasekai/sfa/ui/MainActivity.kt @@ -81,8 +81,6 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback { startIntegration() onNewIntent(intent) - - Vendor.initializeBillingClient(this) } override fun onNewIntent(intent: Intent) { diff --git a/app/src/main/java/io/nekohasekai/sfa/ui/main/SettingsFragment.kt b/app/src/main/java/io/nekohasekai/sfa/ui/main/SettingsFragment.kt index 925daf9..f24bd5a 100644 --- a/app/src/main/java/io/nekohasekai/sfa/ui/main/SettingsFragment.kt +++ b/app/src/main/java/io/nekohasekai/sfa/ui/main/SettingsFragment.kt @@ -104,9 +104,7 @@ class SettingsFragment : Fragment() { startActivity(Intent(requireContext(), DebugActivity::class.java)) } binding.startSponserButton.setOnClickListener { - Vendor.startSponsor(requireActivity()) { - activity.launchCustomTab("https://sekai.icu/sponsor/") - } + activity.launchCustomTab("https://sekai.icu/sponsors/") } lifecycleScope.launch(Dispatchers.IO) { reloadSettings() diff --git a/app/src/main/java/io/nekohasekai/sfa/vendor/VendorInterface.kt b/app/src/main/java/io/nekohasekai/sfa/vendor/VendorInterface.kt index 466013c..0bbc0b4 100644 --- a/app/src/main/java/io/nekohasekai/sfa/vendor/VendorInterface.kt +++ b/app/src/main/java/io/nekohasekai/sfa/vendor/VendorInterface.kt @@ -5,6 +5,4 @@ import android.app.Activity interface VendorInterface { fun checkUpdateAvailable(): Boolean fun checkUpdate(activity: Activity, byUser: Boolean) - fun initializeBillingClient(activity: Activity) - fun startSponsor(activity: Activity, fallback: () -> Unit) } \ No newline at end of file diff --git a/app/src/other/java/io/nekohasekai/sfa/vendor/Vendor.kt b/app/src/other/java/io/nekohasekai/sfa/vendor/Vendor.kt index 121d1e4..4181309 100644 --- a/app/src/other/java/io/nekohasekai/sfa/vendor/Vendor.kt +++ b/app/src/other/java/io/nekohasekai/sfa/vendor/Vendor.kt @@ -11,11 +11,4 @@ object Vendor : VendorInterface { override fun checkUpdate(activity: Activity, byUser: Boolean) { } - override fun initializeBillingClient(activity: Activity) { - } - - override fun startSponsor(activity: Activity, fallback: () -> Unit) { - fallback() - } - } \ No newline at end of file diff --git a/app/src/play/java/io/nekohasekai/sfa/vendor/Vendor.kt b/app/src/play/java/io/nekohasekai/sfa/vendor/Vendor.kt index 2b8d620..6769cdd 100644 --- a/app/src/play/java/io/nekohasekai/sfa/vendor/Vendor.kt +++ b/app/src/play/java/io/nekohasekai/sfa/vendor/Vendor.kt @@ -1,40 +1,15 @@ package io.nekohasekai.sfa.vendor import android.app.Activity -import android.app.ProgressDialog import android.content.Context import android.util.Log -import com.android.billingclient.api.AcknowledgePurchaseParams -import com.android.billingclient.api.BillingClient -import com.android.billingclient.api.BillingClientStateListener -import com.android.billingclient.api.BillingFlowParams -import com.android.billingclient.api.BillingResult -import com.android.billingclient.api.ProductDetails -import com.android.billingclient.api.Purchase -import com.android.billingclient.api.QueryProductDetailsParams -import com.android.billingclient.api.QueryPurchasesParams -import com.android.billingclient.api.queryProductDetails -import com.android.billingclient.api.queryPurchasesAsync import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.play.core.appupdate.AppUpdateManagerFactory import com.google.android.play.core.appupdate.AppUpdateOptions import com.google.android.play.core.install.model.AppUpdateType import com.google.android.play.core.install.model.InstallStatus import com.google.android.play.core.install.model.UpdateAvailability -import io.nekohasekai.sfa.Application import io.nekohasekai.sfa.R -import io.nekohasekai.sfa.ktx.errorDialogBuilder -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import java.util.concurrent.atomic.AtomicInteger -import kotlin.coroutines.resume -import kotlin.coroutines.suspendCoroutine object Vendor : VendorInterface { @@ -94,164 +69,9 @@ object Vendor : VendorInterface { } } - private lateinit var billingClient: BillingClient - override fun initializeBillingClient(activity: Activity) { - billingClient = - BillingClient.newBuilder(Application.application).setListener { result, purchases -> - onPurchasesUpdated(activity, result, purchases) - }.enablePendingPurchases().build() - } - - private fun requireConnection(callback: (String?) -> Unit) { - when (billingClient.connectionState) { - BillingClient.ConnectionState.CONNECTED -> callback(null) - else -> { - billingClient.startConnection(object : BillingClientStateListener { - override fun onBillingSetupFinished(result: BillingResult) { - if (result.responseCode == BillingClient.BillingResponseCode.OK) { - callback(null) - } else { - callback(result.toString()) - } - } - - override fun onBillingServiceDisconnected() { - } - }) - } - } - } - - override fun startSponsor(activity: Activity, fallback: () -> Unit) { - val dialog = ProgressDialog(activity) - dialog.setMessage(activity.getString(R.string.loading)) - dialog.show() - requireConnection { - if (it != null) { - activity.errorDialogBuilder(it).show() - return@requireConnection - } - GlobalScope.launch(Dispatchers.IO) { - acknowledgeSponsor() - startSponsor0(activity, dialog, fallback) - } - } - } - - private suspend fun startSponsor0( - activity: Activity, - dialog: ProgressDialog, - fallback: () -> Unit, - ) { - val params = QueryProductDetailsParams.newBuilder().setProductList( - listOf( - QueryProductDetailsParams.Product.newBuilder().setProductId("sponsor_circle_1") - .setProductType(BillingClient.ProductType.SUBS).build(), - QueryProductDetailsParams.Product.newBuilder().setProductId("sponsor_circle_10") - .setProductType(BillingClient.ProductType.SUBS).build(), - QueryProductDetailsParams.Product.newBuilder() - .setProductId("sponsor_circle_100") - .setProductType(BillingClient.ProductType.SUBS).build(), - ) - ).build() - val (result, products) = billingClient.queryProductDetails(params) - withContext(Dispatchers.Main) { - dialog.dismiss() - } - if (result.responseCode != BillingClient.BillingResponseCode.OK || products.isNullOrEmpty()) { - withContext(Dispatchers.Main) { - activity.errorDialogBuilder(result.toString()).show() - } - return - } - val selecting = products.sortedBy { it.productId.substringAfterLast("_").toInt() } - val selected = AtomicInteger(0) - withContext(Dispatchers.Main) { - MaterialAlertDialogBuilder(activity).setTitle(R.string.sponsor_play) - .setSingleChoiceItems(selecting.map { it.title.removeSuffix(" (sing-box)") } - .toMutableList().also { - it.add(activity.getString(R.string.other_methods)) - }.toTypedArray(), 0 - ) { _, which -> - selected.set(which) - }.setNeutralButton(android.R.string.cancel, null) - .setPositiveButton(R.string.action_start) { _, _ -> - if (selected.get() == selecting.size) { - fallback() - return@setPositiveButton - } - startSponsor1(activity, selecting[selected.get()]) - }.show() - } - } - - private fun startSponsor1(activity: Activity, product: ProductDetails) { - val paramsList = listOf( - BillingFlowParams.ProductDetailsParams.newBuilder().setProductDetails(product) - .setOfferToken(product.subscriptionOfferDetails!![0].offerToken).build() - ) - val flowParams = - BillingFlowParams.newBuilder().setProductDetailsParamsList(paramsList).build() - val result = billingClient.launchBillingFlow(activity, flowParams) - if (result.responseCode != BillingClient.BillingResponseCode.OK) { - activity.errorDialogBuilder(result.toString()).show() - } - } - private fun Context.showNoUpdatesDialog() { MaterialAlertDialogBuilder(this).setTitle(io.nekohasekai.sfa.R.string.check_update) .setMessage(R.string.no_updates_available).setPositiveButton(R.string.ok, null).show() } - private fun onPurchasesUpdated( - activity: Activity, result: BillingResult, purchases: List? - ) { - if (result.responseCode != BillingClient.BillingResponseCode.OK || purchases.isNullOrEmpty()) { - return - } - requireConnection { - if (it != null) GlobalScope.launch(Dispatchers.Main) { - val dialog = ProgressDialog(activity) - dialog.setMessage(activity.getString(R.string.loading)) - dialog.show() - val errorMessage = acknowledgeSponsor0(purchases) - dialog.dismiss() - if (errorMessage != null) { - activity.errorDialogBuilder(errorMessage).show() - } - } - } - } - - private suspend fun acknowledgeSponsor() { - val result = billingClient.queryPurchasesAsync( - QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS) - .build() - ) - if (result.purchasesList.isNotEmpty()) { - acknowledgeSponsor0(result.purchasesList) - } - } - - private suspend fun acknowledgeSponsor0(purchases: List): String? = coroutineScope { - val deferred = mutableListOf>() - for (purchase in purchases) { - deferred += async(Dispatchers.IO) { - suspendCoroutine { continuation -> - billingClient.acknowledgePurchase( - AcknowledgePurchaseParams.newBuilder() - .setPurchaseToken(purchase.purchaseToken).build() - ) { - if (it.responseCode == BillingClient.BillingResponseCode.OK) { - continuation.resume(null) - } else { - continuation.resume(it.toString()) - } - } - } - } - } - deferred.awaitAll().filterNotNull().firstOrNull() - } - } \ No newline at end of file diff --git a/version.properties b/version.properties index 46b7927..2eddf53 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,3 @@ -VERSION_CODE=260 +VERSION_CODE=262 VERSION_NAME=1.8.6 GO_VERSION=go1.22.0