From 0b2aa1efa5c3e826dd081874ecb115fd035f3b45 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 00:11:47 +0530 Subject: [PATCH 1/7] updated `.gitignore` --- app/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/.gitignore b/app/.gitignore index 42afabf..77f70dc 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,3 @@ -/build \ No newline at end of file +/build +/release +google-services.json \ No newline at end of file From 1ffdc4c589287e95959616fb39645415ad9530c7 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 00:16:18 +0530 Subject: [PATCH 2/7] added firebase - Analytics - Crashlytics --- app/build.gradle | 15 ++++++++++++--- app/src/main/java/zechs/drive/stream/ThisApp.kt | 11 ++++++++++- build.gradle | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d9f910d..0ba0df9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,8 @@ plugins { id "androidx.navigation.safeargs.kotlin" id "kotlin-kapt" id "dagger.hilt.android.plugin" + id "com.google.gms.google-services" + id "com.google.firebase.crashlytics" } android { @@ -65,10 +67,17 @@ dependencies { implementation project(path: ":mpv") def exoplayer_version = "2.18.7" - def moshi_version = '1.15.0' + def moshi_version = "1.15.0" def retrofit_version = "2.9.0" def room_version = "2.5.1" + // Firebase + implementation platform("com.google.firebase:firebase-bom:32.1.0") + // Analytics + implementation "com.google.firebase:firebase-analytics-ktx" + // Crashlytics + implementation "com.google.firebase:firebase-crashlytics-ktx" + // Room implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-ktx:$room_version" @@ -111,8 +120,8 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1" // Dagger hilt - implementation 'com.google.dagger:hilt-android:2.46.1' - kapt 'com.google.dagger:hilt-compiler:2.46.1' + implementation "com.google.dagger:hilt-android:2.46.1" + kapt "com.google.dagger:hilt-compiler:2.46.1" // Splash implementation "androidx.core:core-splashscreen:1.0.1" diff --git a/app/src/main/java/zechs/drive/stream/ThisApp.kt b/app/src/main/java/zechs/drive/stream/ThisApp.kt index ff79101..874f89e 100644 --- a/app/src/main/java/zechs/drive/stream/ThisApp.kt +++ b/app/src/main/java/zechs/drive/stream/ThisApp.kt @@ -1,7 +1,16 @@ package zechs.drive.stream import android.app.Application +import com.google.firebase.crashlytics.ktx.crashlytics +import com.google.firebase.ktx.Firebase import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class ThisApp : Application() \ No newline at end of file +class ThisApp : Application() { + + override fun onCreate() { + super.onCreate() + Firebase.crashlytics.setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG) + } + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0c418eb..ba8523e 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,8 @@ buildscript { dependencies { classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.6.0" classpath "com.google.dagger:hilt-android-gradle-plugin:2.45" + classpath "com.google.gms:google-services:4.3.15" + classpath "com.google.firebase:firebase-crashlytics-gradle:2.9.6" } } From 8dd2be2b5ef153904c13b1890d33e2e49cbcdf94 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 00:19:54 +0530 Subject: [PATCH 3/7] implemented enable/disable ads setting --- .../zechs/drive/stream/utils/AppSettings.kt | 17 +++++++ app/src/main/res/layout/fragment_settings.xml | 46 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 65 insertions(+) diff --git a/app/src/main/java/zechs/drive/stream/utils/AppSettings.kt b/app/src/main/java/zechs/drive/stream/utils/AppSettings.kt index 88e23af..9deb55b 100644 --- a/app/src/main/java/zechs/drive/stream/utils/AppSettings.kt +++ b/app/src/main/java/zechs/drive/stream/utils/AppSettings.kt @@ -24,6 +24,7 @@ class AppSettings @Inject constructor( const val APP_THEME = "APP_THEME" const val VIDEO_PLAYER = "VIDEO_PLAYER" const val LAST_UPDATED = "LAST_UPDATED" + const val ENABLE_ADS = "ENABLE_ADS" } private val sessionStore = appContext.dataStore @@ -84,6 +85,22 @@ class AppSettings @Inject constructor( Log.d(TAG, "fetchLastUpdated: $parsed") return parsed } + + suspend fun saveEnableAds(enable: Boolean) { + val dataStoreKey = stringPreferencesKey(ENABLE_ADS) + sessionStore.edit { settings -> + settings[dataStoreKey] = enable.toString() + } + Log.d(TAG, "saveEnableAds: $enable") + } + + suspend fun fetchEnableAds(): Boolean { + val dataStoreKey = stringPreferencesKey(ENABLE_ADS) + val preferences = sessionStore.data.first() + val enable = preferences[dataStoreKey] ?: return true + Log.d(TAG, "fetchEnableAds: $enable") + return enable.toBoolean() + } } enum class AppTheme( diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 3207031..206279a 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -117,6 +117,52 @@ + + + + + + + + + + + + + + + + Check for updates ExoPlayer MPV + Enable Ads + Support the developer by enabling ads \ No newline at end of file From 2fef67840b88d2b440045073995d8a85419d8f43 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 00:20:06 +0530 Subject: [PATCH 4/7] added AdMob --- app/build.gradle | 2 ++ app/src/main/java/zechs/drive/stream/ThisApp.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 0ba0df9..1492c33 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,6 +77,8 @@ dependencies { implementation "com.google.firebase:firebase-analytics-ktx" // Crashlytics implementation "com.google.firebase:firebase-crashlytics-ktx" + // Admob + implementation "com.google.android.gms:play-services-ads:22.1.0" // Room implementation "androidx.room:room-runtime:$room_version" diff --git a/app/src/main/java/zechs/drive/stream/ThisApp.kt b/app/src/main/java/zechs/drive/stream/ThisApp.kt index 874f89e..20dff6f 100644 --- a/app/src/main/java/zechs/drive/stream/ThisApp.kt +++ b/app/src/main/java/zechs/drive/stream/ThisApp.kt @@ -1,6 +1,7 @@ package zechs.drive.stream import android.app.Application +import com.google.android.gms.ads.MobileAds import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase import dagger.hilt.android.HiltAndroidApp @@ -11,6 +12,7 @@ class ThisApp : Application() { override fun onCreate() { super.onCreate() Firebase.crashlytics.setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG) + MobileAds.initialize(this) } } \ No newline at end of file From 70dc55084cfc7aa153330163d51f132a06e6f5af Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 02:35:27 +0530 Subject: [PATCH 5/7] implemented ads --- app/build.gradle | 7 ++++ app/src/main/AndroidManifest.xml | 4 ++- .../drive/stream/ui/main/MainActivity.kt | 33 +++++++++++++++++++ .../drive/stream/ui/main/MainViewModel.kt | 18 ++++++++++ .../java/zechs/drive/stream/utils/AdUnits.kt | 10 ++++++ app/src/main/res/layout/activity_main.xml | 9 +++-- 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/zechs/drive/stream/utils/AdUnits.kt diff --git a/app/build.gradle b/app/build.gradle index 1492c33..be17530 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,6 +8,10 @@ plugins { id "com.google.firebase.crashlytics" } +def localPropertiesFile = rootProject.file("local.properties") +def localProperties = new Properties() +localProperties.load(new FileInputStream(localPropertiesFile)) + android { namespace "zechs.drive.stream" @@ -27,6 +31,9 @@ android { archivesBaseName = "${applicationId}-${versionCode}" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + resValue "string", "ad_app_id", localProperties['ad.appid'] + buildConfigField "String", "ad_home_banner", localProperties['ad.home.banner'] } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0b84399..965dfb0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,7 +56,9 @@ android:supportsPictureInPicture="true" android:theme="@style/Theme.Fullscreen" tools:targetApi="n" /> - + \ No newline at end of file diff --git a/app/src/main/java/zechs/drive/stream/ui/main/MainActivity.kt b/app/src/main/java/zechs/drive/stream/ui/main/MainActivity.kt index 7e9b3c3..39d8ad3 100644 --- a/app/src/main/java/zechs/drive/stream/ui/main/MainActivity.kt +++ b/app/src/main/java/zechs/drive/stream/ui/main/MainActivity.kt @@ -25,12 +25,17 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment +import com.google.android.gms.ads.AdRequest +import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.AdView import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import zechs.drive.stream.BuildConfig import zechs.drive.stream.R import zechs.drive.stream.data.model.LatestRelease import zechs.drive.stream.databinding.ActivityMainBinding +import zechs.drive.stream.utils.AdUnits import zechs.drive.stream.utils.AppTheme import zechs.drive.stream.utils.ext.navigateSafe import zechs.drive.stream.utils.state.Resource @@ -79,6 +84,7 @@ class MainActivity : AppCompatActivity() { themeObserver() updateObserver() redirectOnLogin() + setupAds() } private fun themeObserver() { @@ -140,6 +146,7 @@ class MainActivity : AppCompatActivity() { sendUpdateNotification(release) } } + is Resource.Error -> Log.d(TAG, it.message!!) else -> {} } @@ -244,4 +251,30 @@ class MainActivity : AppCompatActivity() { } AppCompatDelegate.setDefaultNightMode(mode) } + + private fun setupAds() { + val linearLayout = binding.linearLayout + var adView: AdView? = null + val adId = if (BuildConfig.DEBUG) AdUnits.DEBUG_BANNER else AdUnits.RELEASE_BANNER + + viewModel.showAds.observe(this) { enabled -> + if (enabled) { + Log.d(TAG, "setupAds(), Loading AdView...") + adView = AdView(this@MainActivity) + adView!!.apply { + setAdSize(AdSize.BANNER) + adUnitId = adId + loadAd(AdRequest.Builder().build()) + } + linearLayout.addView(adView) + } else { + if (adView == null) return@observe + Log.d(TAG, "setupAds(), Removing AdView...") + linearLayout.removeView(adView) + adView!!.destroy() + adView = null + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/zechs/drive/stream/ui/main/MainViewModel.kt b/app/src/main/java/zechs/drive/stream/ui/main/MainViewModel.kt index 09c8d75..db35bd0 100755 --- a/app/src/main/java/zechs/drive/stream/ui/main/MainViewModel.kt +++ b/app/src/main/java/zechs/drive/stream/ui/main/MainViewModel.kt @@ -49,9 +49,16 @@ class MainViewModel @Inject constructor( var isChecking = false private set + private val _showAds = MutableLiveData() + val showAds: LiveData = _showAds + + var adsEnabled = false + private set + init { viewModelScope.launch { getTheme() + getEnableAds() val status = getLoginStatus() if (status) { getPlayer() @@ -107,4 +114,15 @@ class MainViewModel @Inject constructor( getPlayer() } + private suspend fun getEnableAds() { + val fetchEnableAds = appSettings.fetchEnableAds() + adsEnabled = fetchEnableAds + _showAds.postValue(fetchEnableAds) + } + + fun setEnableAds(enable: Boolean) = viewModelScope.launch { + appSettings.saveEnableAds(enable) + getEnableAds() + } + } diff --git a/app/src/main/java/zechs/drive/stream/utils/AdUnits.kt b/app/src/main/java/zechs/drive/stream/utils/AdUnits.kt new file mode 100644 index 0000000..9e08ef7 --- /dev/null +++ b/app/src/main/java/zechs/drive/stream/utils/AdUnits.kt @@ -0,0 +1,10 @@ +package zechs.drive.stream.utils + +import zechs.drive.stream.BuildConfig + +class AdUnits { + companion object { + const val DEBUG_BANNER = "ca-app-pub-3940256099942544/6300978111" + const val RELEASE_BANNER = BuildConfig.ad_home_banner + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index bdbedf3..c1ab2e2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,17 +1,20 @@ - - \ No newline at end of file + \ No newline at end of file From be54abce02ab1964ef9ae0bc430bdd312ef1e8e8 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 02:36:05 +0530 Subject: [PATCH 6/7] added enable/disable ads setting --- .../zechs/drive/stream/ui/settings/SettingsFragment.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt b/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt index 8e3d233..08634a4 100644 --- a/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt @@ -56,6 +56,7 @@ class SettingsFragment : BaseFragment() { setupThemeMenu() setupDefaultPlayerMenu() setupCheckForUpdates() + setupAdsSetting() } private fun setupThemeMenu() { @@ -157,6 +158,14 @@ class SettingsFragment : BaseFragment() { } + private fun setupAdsSetting() { + binding.switchAdsSupport.isChecked = mainViewModel.adsEnabled + binding.settingAdsSupport.setOnClickListener { + binding.switchAdsSupport.isChecked = !binding.switchAdsSupport.isChecked + mainViewModel.setEnableAds(binding.switchAdsSupport.isChecked) + } + } + private fun showSnackBar(message: String) { Snackbar.make( binding.root, From 67fcedf958af66d613f8b7860c25810f75bda493 Mon Sep 17 00:00:00 2001 From: zechs Date: Sun, 25 Jun 2023 16:04:55 +0530 Subject: [PATCH 7/7] user confirmation before disabling ads --- .../stream/ui/settings/SettingsFragment.kt | 22 +++++++++++++++++-- app/src/main/res/values/strings.xml | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt b/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt index 08634a4..2d090ba 100644 --- a/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/zechs/drive/stream/ui/settings/SettingsFragment.kt @@ -1,6 +1,7 @@ package zechs.drive.stream.ui.settings import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -161,8 +162,25 @@ class SettingsFragment : BaseFragment() { private fun setupAdsSetting() { binding.switchAdsSupport.isChecked = mainViewModel.adsEnabled binding.settingAdsSupport.setOnClickListener { - binding.switchAdsSupport.isChecked = !binding.switchAdsSupport.isChecked - mainViewModel.setEnableAds(binding.switchAdsSupport.isChecked) + if (binding.switchAdsSupport.isChecked) { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(getString(R.string.disable_ads)) + .setMessage(getString(R.string.disable_ads_message)) + .setNegativeButton(getString(R.string.no)) { dialog, _ -> + dialog.dismiss() + } + .setPositiveButton(getString(R.string.yes)) { dialog, _ -> + dialog.dismiss() + Log.d(TAG, "Disabling ads") + binding.switchAdsSupport.isChecked = false + mainViewModel.setEnableAds(false) + } + .show() + } else { + binding.switchAdsSupport.isChecked = true + mainViewModel.setEnableAds(true) + showSnackBar(getString(R.string.thank_you_for_supporting_the_app)) + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d7f996c..5466297 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -69,4 +69,7 @@ MPV Enable Ads Support the developer by enabling ads + Disable Ads + Are you sure you want to disable ads?\n\nThis will remove all ads from the app. Ads help support the development of this app. + Thank you for supporting the app! \ No newline at end of file