Skip to content

Commit

Permalink
Update 5.1_r1
Browse files Browse the repository at this point in the history
  • Loading branch information
D4rK7355608 committed Jul 11, 2023
1 parent e49c91b commit 0aa61bf
Show file tree
Hide file tree
Showing 69 changed files with 2,601 additions and 2,311 deletions.
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Version 5.0_r4:
- Made minor under-the-hood improvements for a better overall app experience.
# Version 5.1_r1:
- Added a new GDPR message to comply with Google Play policy.
- Added a new help center, with more comprehensive documentation and support options.
- Made minor project structure enhancements for better readability and maintainability.
- Made various under-the-hood improvements for a better overall app experience.

# Version 5.0_r3:
- Made minor under-the-hood improvements for a better overall app experience.
Expand Down
20 changes: 10 additions & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId 'com.d4rk.androidtutorials'
minSdkVersion 26
targetSdkVersion 33
versionCode 54
versionName '5.0_r4'
versionCode 56
versionName '5.1_r1'
archivesBaseName = "${applicationId}-v${versionName}"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
resourceConfigurations += ['en', 'de', 'es', 'fr', 'hi', 'hu', 'in', 'it', 'ja', 'ro', 'ru', 'tr', 'sv', 'bg', 'pl', 'uk']
Expand Down Expand Up @@ -53,28 +53,28 @@ android {
}
dependencies {
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.google.android.gms:play-services-ads:22.0.0'
implementation 'com.google.android.gms:play-services-ads:22.2.0'
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.1'
implementation 'com.google.android.play:review-ktx:2.0.1'
implementation 'com.google.android.play:app-update-ktx:2.0.1'
implementation 'com.google.android.play:app-update-ktx:2.1.0'
implementation 'com.google.firebase:firebase-crashlytics-ktx:18.3.7'
implementation 'com.google.firebase:firebase-analytics-ktx:21.2.2'
implementation 'com.google.firebase:firebase-perf:20.3.2'
implementation 'com.google.firebase:firebase-analytics-ktx:21.3.0'
implementation 'com.google.firebase:firebase-perf:20.3.3'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-ktx:1.10.0'
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.core:core-splashscreen:1.0.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation 'androidx.navigation:navigation-fragment-ktx:2.6.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.6.0'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-process:2.6.1'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.airbnb.android:lottie:6.0.0'
implementation 'com.airbnb.android:lottie:6.0.1'
implementation 'com.github.KieronQuinn:MonetCompat:0.4.1'
implementation 'me.zhanghai.android.fastscroll:library:1.2.0'
implementation 'me.zhanghai.android.materialratingbar:library:1.4.0'
Expand Down
13 changes: 4 additions & 9 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</intent>
</queries>
<application
android:name=".ads.Ads"
android:name=".ads.managers.AppOpenAdManager"
android:label="@string/app_name"
android:description="@string/app_description"
android:icon="@mipmap/ic_launcher"
Expand Down Expand Up @@ -257,11 +257,6 @@
android:exported="false"
android:label="@string/version_control"
android:parentActivityName=".ui.android.basics.shortcuts.tabs.VersionControlShortcutsActivity"/>
<activity
android:name=".ui.settings.feedback.FeedbackActivity"
android:label="@string/feedback"
android:exported="true"
android:parentActivityName=".ui.settings.feedback.FeedbackActivity"/>
<activity
android:name=".ui.android.buttons.buttons.ButtonsCodeActivity"
android:exported="false"
Expand All @@ -277,10 +272,10 @@
</intent-filter>
</activity>
<activity
android:name=".ui.settings.faq.FaqActivity"
android:name=".ui.settings.help.HelpActivity"
android:label="@string/help"
android:exported="false"
android:label="@string/faq"
android:parentActivityName=".ui.settings.faq.FaqActivity"/>
android:parentActivityName=".ui.settings.help.HelpActivity"/>
<activity
android:name=".ui.android.buttons.toggle.ToggleActivity"
android:label="@string/toggle"
Expand Down
105 changes: 35 additions & 70 deletions app/src/main/kotlin/com/d4rk/androidtutorials/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
package com.d4rk.androidtutorials
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.NotificationCompat
import androidx.core.os.LocaleListCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.fragment.NavHostFragment
Expand All @@ -20,6 +13,8 @@ import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.d4rk.androidtutorials.databinding.ActivityMainBinding
import com.d4rk.androidtutorials.notifications.AppUpdateNotificationsManager
import com.d4rk.androidtutorials.notifications.AppUsageNotificationsManager
import com.d4rk.androidtutorials.ui.settings.SettingsActivity
import com.d4rk.androidtutorials.ui.startup.StartupActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
Expand All @@ -30,51 +25,42 @@ import com.google.android.play.core.install.model.ActivityResult
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var prefs: SharedPreferences
private lateinit var appUpdateManager: AppUpdateManager
private val requestUpdateCode = 1
private var startFragmentId = R.id.navigation_home
private lateinit var appUpdateNotificationsManager: AppUpdateNotificationsManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
applyAppSettings()
appUpdateManager = AppUpdateManagerFactory.create(this)
prefs = getSharedPreferences("startup", MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val themeKey = getString(R.string.key_theme)
val labelKey = getString(R.string.key_bottom_navigation_bar_labels)
val defaultTabKey = getString(R.string.key_default_tab)
val defaultTabValue = getString(R.string.default_value_tab)
val defaultTabValues = resources.getStringArray(R.array.preference_default_tab_values)
appUpdateNotificationsManager = AppUpdateNotificationsManager(this)

}
private fun applyAppSettings() {
val themeValues = resources.getStringArray(R.array.preference_theme_values)
val themeDefaultValue = getString(R.string.default_value_theme)
val bottomNavigationBarLabelsValues = resources.getStringArray(R.array.preference_bottom_navigation_bar_labels_values)
val labelDefaultValue = getString(R.string.default_value_bottom_navigation_bar_labels)
val nightMode = when (sharedPreferences.getString(themeKey, themeDefaultValue)) {
themeValues[0] -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
themeValues[1] -> AppCompatDelegate.MODE_NIGHT_NO
themeValues[2] -> AppCompatDelegate.MODE_NIGHT_YES
themeValues[3] -> AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
when (PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.key_theme), getString(R.string.default_value_theme))) {
themeValues[0] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
themeValues[1] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
themeValues[2] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
themeValues[3] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)
}
val languageCode = sharedPreferences?.getString(getString(R.string.key_language), getString(R.string.default_value_language))
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(languageCode))
AppCompatDelegate.setDefaultNightMode(nightMode)
binding.navView.labelVisibilityMode = when (sharedPreferences.getString(labelKey, labelDefaultValue)) {
val bottomNavigationBarLabelsValues = resources.getStringArray(R.array.preference_bottom_navigation_bar_labels_values)
binding.navView.labelVisibilityMode = when (PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.key_bottom_navigation_bar_labels), getString(R.string.default_value_bottom_navigation_bar_labels))) {
bottomNavigationBarLabelsValues[0] -> NavigationBarView.LABEL_VISIBILITY_LABELED
bottomNavigationBarLabelsValues[1] -> NavigationBarView.LABEL_VISIBILITY_SELECTED
bottomNavigationBarLabelsValues[2] -> NavigationBarView.LABEL_VISIBILITY_UNLABELED
else -> NavigationBarView.LABEL_VISIBILITY_AUTO
}
val defaultTabValues = resources.getStringArray(R.array.preference_default_tab_values)
val navController by lazy {
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment
navHostFragment.navController
}
startFragmentId = when (sharedPreferences.getString(defaultTabKey, defaultTabValue)) {
val startFragmentId = when (PreferenceManager.getDefaultSharedPreferences(this).getString(getString(R.string.key_default_tab), getString(R.string.default_value_tab))) {
defaultTabValues[0] -> R.id.navigation_home
defaultTabValues[1] -> R.id.navigation_android_studio
defaultTabValues[2] -> R.id.navigation_about
Expand All @@ -87,38 +73,8 @@ class MainActivity : AppCompatActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_home, R.id.navigation_android_studio, R.id.navigation_about))
setupActionBarWithNavController(navController, appBarConfiguration)
val prefs = getSharedPreferences("app_usage", MODE_PRIVATE)
val lastUsedTimestamp = prefs.getLong("last_used", 0)
val currentTimestamp = System.currentTimeMillis()
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (currentTimestamp - lastUsedTimestamp > 3 * 24 * 60 * 60 * 1000) {
val appUsageChannelId = "app_usage_channel"
val appUsageChannel = NotificationChannel(appUsageChannelId, getString(R.string.app_usage_notifications), NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(appUsageChannel)
val builder = NotificationCompat.Builder(this, appUsageChannelId)
.setSmallIcon(R.drawable.ic_notification_important)
.setContentTitle(getString(R.string.notification_last_time_used_title))
.setContentText(getString(R.string.summary_notification_last_time_used))
.setAutoCancel(true)
notificationManager.notify(0, builder.build())
}
prefs.edit().putLong("last_used", currentTimestamp).apply()
val appUpdateInfoTask = AppUpdateManagerFactory.create(this).appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
val updateChannelId = "update_channel"
val updateChannel = NotificationChannel(updateChannelId, getString(R.string.update_notifications), NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(updateChannel)
val updateBuilder = NotificationCompat.Builder(this, updateChannelId)
.setSmallIcon(R.drawable.ic_notification_update)
.setContentTitle(getString(R.string.notification_update_title))
.setContentText(getString(R.string.summary_notification_update))
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 0, Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName")), PendingIntent.FLAG_IMMUTABLE))
notificationManager.notify(0, updateBuilder.build())
}
}
val languageCode = PreferenceManager.getDefaultSharedPreferences(this)?.getString(getString(R.string.key_language), getString(R.string.default_value_language))
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(languageCode))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
Expand Down Expand Up @@ -148,19 +104,28 @@ class MainActivity : AppCompatActivity() {
}
override fun onResume() {
super.onResume()
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val preferenceFirebase = prefs.getBoolean(getString(R.string.key_firebase), true)
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(preferenceFirebase)
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(preferenceFirebase)
if (prefs.getBoolean("value", true)) {
prefs.edit().putBoolean("value", false).apply()
startActivity(Intent(this, StartupActivity::class.java))
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(getString(R.string.key_firebase), true)) {
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(false)
} else {
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(true)
}
val appUsageNotificationsManager = AppUsageNotificationsManager(this)
appUsageNotificationsManager.checkAndSendAppUsageNotification()
appUpdateNotificationsManager.checkAndSendUpdateNotification()
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
@Suppress("DEPRECATION")
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.FLEXIBLE, this, requestUpdateCode)
}
}
startupScreen()
}
private fun startupScreen() {
val startupPreference = getSharedPreferences("startup", MODE_PRIVATE)
if (startupPreference.getBoolean("value", true)) {
startupPreference.edit().putBoolean("value", false).apply()
startActivity(Intent(this, StartupActivity::class.java))
}
}
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@file:Suppress("DEPRECATION")
package com.d4rk.androidtutorials.ads
package com.d4rk.androidtutorials.ads.managers
import android.app.Activity
import android.app.Application
import android.content.Context
Expand All @@ -15,17 +15,16 @@ import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.appopen.AppOpenAd
import com.google.android.gms.ads.appopen.AppOpenAd.AppOpenAdLoadCallback
import java.util.Date
private const val AD_UNIT_ID = "ca-app-pub-5294151573817700/1738685282"
@Suppress("SameParameterValue")
class Ads : MultiDexApplication(), Application.ActivityLifecycleCallbacks, LifecycleObserver {
class AppOpenAdManager : MultiDexApplication(), Application.ActivityLifecycleCallbacks, LifecycleObserver {
private lateinit var appOpenAdManager: AppOpenAdManager
private var currentActivity: Activity? = null
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(this)
MobileAds.initialize(this)
MobileAds.initialize(this)
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
appOpenAdManager = AppOpenAdManager()
}
Expand Down Expand Up @@ -58,22 +57,23 @@ class Ads : MultiDexApplication(), Application.ActivityLifecycleCallbacks, Lifec
}
isLoadingAd = true
val request = AdRequest.Builder().build()
AppOpenAd.load(
context,
AD_UNIT_ID,
request,
AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
object : AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
appOpenAd = ad
isLoadingAd = false
loadTime = Date().time
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
}
}
)
AppOpenAd.load(
context,
AD_UNIT_ID,
request,
AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
appOpenAd = ad
isLoadingAd = false
loadTime = Date().time
}

override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
}
}
)
}
private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
val dateDifference: Long = Date().time - loadTime
Expand Down
Loading

0 comments on commit 0aa61bf

Please sign in to comment.