From 94fd303f8ea6edcdd0f8e528cf623615c8aa3619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Thu, 21 Oct 2021 10:51:00 +0200 Subject: [PATCH] Add single support advert (#1484) --- app/build.gradle | 20 ++-- app/src/main/AndroidManifest.xml | 13 ++- .../ui/modules/about/AboutPresenter.kt | 26 ++--- .../ui/modules/dashboard/DashboardAdapter.kt | 3 +- .../settings/advanced/AdvancedFragment.kt | 4 - .../settings/appearance/AppearanceFragment.kt | 4 - .../notifications/NotificationsFragment.kt | 4 - .../ui/modules/settings/sync/SyncFragment.kt | 4 - app/src/main/res/drawable/ic_settings_ads.xml | 22 +++++ app/src/main/res/values/preferences_keys.xml | 1 + app/src/main/res/values/strings.xml | 10 ++ app/src/main/res/xml/scheme_preferences.xml | 30 +++--- .../ui/modules/settings/ads/AdsFragment.kt | 94 +++++++++++++++++++ .../ui/modules/settings/ads/AdsPresenter.kt | 41 ++++++++ .../ui/modules/settings/ads/AdsView.kt | 17 ++++ .../io/github/wulkanowy/utils/AdsHelper.kt | 39 ++++++++ app/src/play/res/xml/scheme_preferences.xml | 39 ++++++++ .../play/res/xml/scheme_preferences_ads.xml | 12 +++ 18 files changed, 324 insertions(+), 59 deletions(-) create mode 100644 app/src/main/res/drawable/ic_settings_ads.xml create mode 100644 app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsFragment.kt create mode 100644 app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt create mode 100644 app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsView.kt create mode 100644 app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt create mode 100644 app/src/play/res/xml/scheme_preferences.xml create mode 100644 app/src/play/res/xml/scheme_preferences_ads.xml diff --git a/app/build.gradle b/app/build.gradle index 90b4cdb9..42177406 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,10 @@ android { resValue "string", "app_name", "Wulkanowy" - manifestPlaceholders = [firebase_enabled: project.hasProperty("enableFirebase")] + manifestPlaceholders = [ + firebase_enabled: project.hasProperty("enableFirebase"), + admob_project_id: "" + ] javaCompileOptions { annotationProcessorOptions { arguments += [ @@ -39,6 +42,8 @@ android { } } + buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null" + if (System.env.SET_BUILD_TIMESTAMP) { buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis()) } else { @@ -82,23 +87,21 @@ android { productFlavors { hms { dimension "platform" - manifestPlaceholders = [ - install_channel: "AppGallery" - ] + manifestPlaceholders = [install_channel: "AppGallery"] } play { dimension "platform" manifestPlaceholders = [ - install_channel: "Google Play" + install_channel : "Google Play", + admob_project_id: System.getenv("ADMOB_PROJECT_ID") ?: "ca-app-pub-3940256099942544~3347511713" ] + buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "\"${System.getenv("SINGLE_SUPPORT_AD_ID") ?: "ca-app-pub-3940256099942544/5354046379"}\"" } fdroid { dimension "platform" - manifestPlaceholders = [ - install_channel: "F-Droid" - ] + manifestPlaceholders = [install_channel: "F-Droid"] } } @@ -233,6 +236,7 @@ dependencies { playImplementation 'com.google.firebase:firebase-crashlytics:' playImplementation 'com.google.android.play:core:1.10.2' playImplementation 'com.google.android.play:core-ktx:1.8.1' + playImplementation 'com.google.android.gms:play-services-ads:20.4.0' hmsImplementation 'com.huawei.hms:hianalytics:6.3.0.301' hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.1.200' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8c7eb852..810d469f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -165,33 +165,32 @@ - - - - - - - + + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index 6bcf5f77..55274934 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -82,18 +82,20 @@ class AboutPresenter @Inject constructor( private fun loadData() { view?.run { - updateData(listOfNotNull( - versionRes, - creatorsRes, - feedbackRes, - faqRes, - discordRes, - facebookRes, - twitterRes, - homepageRes, - licensesRes, - privacyRes - )) + updateData( + listOfNotNull( + versionRes, + creatorsRes, + feedbackRes, + faqRes, + discordRes, + facebookRes, + twitterRes, + homepageRes, + licensesRes, + privacyRes + ) + ) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt index 405bfbc5..440bbd5d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardAdapter.kt @@ -299,7 +299,8 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter + + + + + + diff --git a/app/src/main/res/values/preferences_keys.xml b/app/src/main/res/values/preferences_keys.xml index c512a5f2..1aba7d85 100644 --- a/app/src/main/res/values/preferences_keys.xml +++ b/app/src/main/res/values/preferences_keys.xml @@ -34,4 +34,5 @@ message_send_recipients last_sync_date notifications_piggyback + single_ad_support diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 48c7712d..13030366 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -658,10 +658,19 @@ Reply with message history Show arithmetic average when no weights provided + Support + Watch single ad to support project + Consent to data processing + To view an advertisement you must agree to the data processing terms of our Privacy Policy + Agree + Privacy policy + Ad is loading + Advanced Appearance & Behavior Notifications Synchronization + Advertisements Grades Dashboard @@ -681,6 +690,7 @@ Plus and minus values, average calculation Advanced App version, contributors, social portals, licenses + Displaying advertisements, project support diff --git a/app/src/main/res/xml/scheme_preferences.xml b/app/src/main/res/xml/scheme_preferences.xml index 08621492..5bf7ad8a 100644 --- a/app/src/main/res/xml/scheme_preferences.xml +++ b/app/src/main/res/xml/scheme_preferences.xml @@ -1,33 +1,33 @@ + app:title="@string/pref_appearance_category" /> + app:title="@string/pref_notifications_category" /> + app:title="@string/pref_sync_category" /> + app:title="@string/pref_advanced_category" /> + app:title="@string/about_title" /> diff --git a/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsFragment.kt b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsFragment.kt new file mode 100644 index 00000000..960a54b8 --- /dev/null +++ b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsFragment.kt @@ -0,0 +1,94 @@ +package io.github.wulkanowy.ui.modules.settings.ads + +import android.os.Bundle +import android.view.View +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAd +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import dagger.hilt.android.AndroidEntryPoint +import io.github.wulkanowy.R +import io.github.wulkanowy.ui.base.BaseActivity +import io.github.wulkanowy.ui.base.ErrorDialog +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.openInternetBrowser +import javax.inject.Inject + +@AndroidEntryPoint +class AdsFragment : PreferenceFragmentCompat(), MainView.TitledView, AdsView { + + @Inject + lateinit var presenter: AdsPresenter + + override val titleStringId = R.string.pref_settings_ads_title + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.scheme_preferences_ads, rootKey) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + findPreference(getString(R.string.pref_key_ads_single_support))?.setOnPreferenceClickListener { + presenter.onWatchSingleAdSelected() + true + } + } + + override fun showAd(ad: RewardedInterstitialAd) { + if (isVisible) { + ad.show(requireActivity()) {} + } + } + + override fun showPrivacyPolicyDialog() { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(getString(R.string.pref_ads_privacy_title)) + .setMessage(getString(R.string.pref_ads_privacy_description)) + .setPositiveButton(getString(R.string.pref_ads_privacy_agree)) { _, _ -> presenter.onAgreedPrivacy() } + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .setNeutralButton(getString(R.string.pref_ads_privacy_link)) { _, _ -> presenter.onPrivacySelected() } + .show() + } + + override fun openPrivacyPolicy() { + requireContext().openInternetBrowser( + "https://wulkanowy.github.io/polityka-prywatnosci.html", + ::showMessage + ) + } + + override fun showLoadingSupportAd(show: Boolean) { + findPreference(getString(R.string.pref_key_ads_single_support))?.run { + isEnabled = !show + summary = if (show) getString(R.string.pref_ads_loading) else null + } + } + + override fun showError(text: String, error: Throwable) { + (activity as? BaseActivity<*, *>)?.showError(text, error) + } + + override fun showMessage(text: String) { + (activity as? BaseActivity<*, *>)?.showMessage(text) + } + + override fun showExpiredDialog() { + (activity as? BaseActivity<*, *>)?.showExpiredDialog() + } + + override fun showChangePasswordSnackbar(redirectUrl: String) { + (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) + } + + override fun openClearLoginView() { + (activity as? BaseActivity<*, *>)?.openClearLoginView() + } + + override fun showErrorDetailsDialog(error: Throwable) { + ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) + } +} \ No newline at end of file diff --git a/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt new file mode 100644 index 00000000..fd5cc9b6 --- /dev/null +++ b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt @@ -0,0 +1,41 @@ +package io.github.wulkanowy.ui.modules.settings.ads + +import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.AdsHelper +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +class AdsPresenter @Inject constructor( + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val adsHelper: AdsHelper +) : BasePresenter(errorHandler, studentRepository) { + + override fun onAttachView(view: AdsView) { + super.onAttachView(view) + view.initView() + Timber.i("Settings ads view was initialized") + } + + fun onWatchSingleAdSelected() { + view?.showPrivacyPolicyDialog() + } + + fun onPrivacySelected() { + view?.openPrivacyPolicy() + } + + fun onAgreedPrivacy() { + view?.showLoadingSupportAd(true) + presenterScope.launch { + runCatching { adsHelper.getSupportAd() } + .onFailure(errorHandler::dispatch) + .onSuccess { it?.let { view?.showAd(it) } } + + view?.showLoadingSupportAd(false) + } + } +} \ No newline at end of file diff --git a/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsView.kt b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsView.kt new file mode 100644 index 00000000..25eeaaec --- /dev/null +++ b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsView.kt @@ -0,0 +1,17 @@ +package io.github.wulkanowy.ui.modules.settings.ads + +import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAd +import io.github.wulkanowy.ui.base.BaseView + +interface AdsView : BaseView { + + fun initView() + + fun showAd(ad: RewardedInterstitialAd) + + fun showPrivacyPolicyDialog() + + fun openPrivacyPolicy() + + fun showLoadingSupportAd(show: Boolean) +} \ No newline at end of file diff --git a/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt b/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt new file mode 100644 index 00000000..f363c13f --- /dev/null +++ b/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt @@ -0,0 +1,39 @@ +package io.github.wulkanowy.utils + +import android.content.Context +import com.google.android.gms.ads.AdRequest +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.ads.MobileAds +import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAd +import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAdLoadCallback +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.BuildConfig +import javax.inject.Inject +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +class AdsHelper @Inject constructor(@ApplicationContext private val context: Context) { + + suspend fun getSupportAd(): RewardedInterstitialAd? { + MobileAds.initialize(context) + + val adRequest = AdRequest.Builder().build() + + return suspendCoroutine { + RewardedInterstitialAd.load( + context, + BuildConfig.SINGLE_SUPPORT_AD_ID, + adRequest, + object : RewardedInterstitialAdLoadCallback() { + override fun onAdLoaded(rewardedInterstitialAd: RewardedInterstitialAd) { + it.resume(rewardedInterstitialAd) + } + + override fun onAdFailedToLoad(loadAdError: LoadAdError) { + it.resumeWithException(IllegalArgumentException(loadAdError.message)) + } + }) + } + } +} \ No newline at end of file diff --git a/app/src/play/res/xml/scheme_preferences.xml b/app/src/play/res/xml/scheme_preferences.xml new file mode 100644 index 00000000..05b0bf64 --- /dev/null +++ b/app/src/play/res/xml/scheme_preferences.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/play/res/xml/scheme_preferences_ads.xml b/app/src/play/res/xml/scheme_preferences_ads.xml new file mode 100644 index 00000000..6b3625ca --- /dev/null +++ b/app/src/play/res/xml/scheme_preferences_ads.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file