From a39197a8abff925df08be6a669a8acc50d3e70dc Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 12:03:08 +0100 Subject: [PATCH 1/6] UpdateReceiver: do not delete old alarms, if exist --- app/build.gradle | 8 +++--- .../jobs/UpdateReceiver.kt | 26 ------------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 921d097..0aa0437 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ android { applicationId "com.javinator9889.handwashingreminder" minSdkVersion 16 targetSdkVersion 30 - versionCode 143 + versionCode 144 versionName "1.2.1-${gitCommitHash}" multiDexEnabled true resConfigs "en", "es" @@ -110,7 +110,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { } dependencies { - def room_version = "2.2.5" + def room_version = "2.2.6" implementation fileTree(dir: 'libs', include: ['*.jar']) api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" api 'androidx.appcompat:appcompat:1.2.0' @@ -154,10 +154,10 @@ dependencies { // https://kotlinlang.org/docs/reference/reflection.html implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" // https://firebase.google.com/docs/android/setup#add-sdks - api 'com.google.firebase:firebase-common-ktx:19.4.0' + api 'com.google.firebase:firebase-common-ktx:19.5.0' api 'com.google.firebase:firebase-analytics:18.0.0' api 'com.google.firebase:firebase-crashlytics:17.3.0' - api 'com.google.firebase:firebase-perf:19.0.10' + api 'com.google.firebase:firebase-perf:19.0.11' implementation 'com.google.firebase:firebase-auth:20.0.1' // http://airbnb.io/lottie/#/android?id=getting-started api 'com.airbnb.android:lottie:3.5.0' diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/UpdateReceiver.kt b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/UpdateReceiver.kt index 7c747a1..6627b93 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/UpdateReceiver.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/UpdateReceiver.kt @@ -18,15 +18,10 @@ */ package com.javinator9889.handwashingreminder.jobs -import android.app.NotificationManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.javinator9889.handwashingreminder.BuildConfig import com.javinator9889.handwashingreminder.jobs.alarms.AlarmHandler -import com.javinator9889.handwashingreminder.utils.ACTIVITY_CHANNEL_ID -import com.javinator9889.handwashingreminder.utils.AndroidVersion -import com.javinator9889.handwashingreminder.utils.isAtLeast import timber.log.Timber class UpdateReceiver : BroadcastReceiver() { @@ -36,27 +31,6 @@ class UpdateReceiver : BroadcastReceiver() { with(AlarmHandler(context)) { scheduleAllAlarms() } - // Here, we need to remove all the notifications channels - // previously created as they have changed - if (BuildConfig.VERSION_CODE in 141..142 && isAtLeast(AndroidVersion.O)) { - val notificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - for (id in setOf( - "notifications:breakfast", - "notifications:lunch", - "notifications:dinner", - ACTIVITY_CHANNEL_ID - )) { - notificationManager.deleteNotificationChannel(id) - } - for (id in setOf( - "alarms:breakfast", - "alarms:lunch", - "alarms:dinner" - )) { - notificationManager.deleteNotificationChannelGroup(id) - } - } } } } \ No newline at end of file From d046318d8b39c41175eee22f3d2ed5e873732592 Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 12:24:40 +0100 Subject: [PATCH 2/6] Notifications: dynamic notification ID when creating new notifications --- app/build.gradle | 2 +- .../gms/activity/ActivityReceiver.kt | 19 +++------- .../jobs/HandsWashedReceiver.kt | 2 + .../workers/ScheduledNotificationWorker.kt | 22 +++-------- .../notifications/NotificationsHandler.kt | 37 ++++++++++++------- 5 files changed, 37 insertions(+), 45 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0aa0437..c746f9a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ android { applicationId "com.javinator9889.handwashingreminder" minSdkVersion 16 targetSdkVersion 30 - versionCode 144 + versionCode 145 versionName "1.2.1-${gitCommitHash}" multiDexEnabled true resConfigs "en", "es" diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityReceiver.kt b/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityReceiver.kt index d176828..4620355 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityReceiver.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityReceiver.kt @@ -18,7 +18,6 @@ */ package com.javinator9889.handwashingreminder.gms.activity -import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -34,7 +33,6 @@ import com.javinator9889.handwashingreminder.emoji.EmojiLoader import com.javinator9889.handwashingreminder.jobs.HANDS_WASHED_ACTION import com.javinator9889.handwashingreminder.jobs.HANDS_WASHED_CODE import com.javinator9889.handwashingreminder.jobs.HandsWashedReceiver -import com.javinator9889.handwashingreminder.jobs.NOTIFICATION_ID_KEY import com.javinator9889.handwashingreminder.jobs.alarms.AlarmHandler import com.javinator9889.handwashingreminder.jobs.alarms.Alarms import com.javinator9889.handwashingreminder.notifications.Action @@ -159,28 +157,21 @@ class ActivityReceiver : BroadcastReceiver() { content = emojiCompat.process(content) } catch (_: IllegalStateException) { } - val washedPendingIntent = PendingIntent.getBroadcast( - context, - HANDS_WASHED_CODE, - Intent(context, HandsWashedReceiver::class.java).apply { - action = HANDS_WASHED_ACTION - putExtra(NOTIFICATION_ID_KEY, 2) - }, - PendingIntent.FLAG_UPDATE_CURRENT - ) withContext(Dispatchers.Main) { notificationsHandler.createNotification( iconDrawable = R.drawable.ic_stat_handwashing, largeIcon = R.drawable.handwashing_app_logo, title = title, content = content, - longContent = content, - notificationId = 2, priority = NotificationCompat.PRIORITY_MAX, + longContent = content, action = Action( R.drawable.ic_stat_handwashing, context.getText(R.string.just_washed), - washedPendingIntent + HANDS_WASHED_CODE, + Intent(context, HandsWashedReceiver::class.java).apply { + action = HANDS_WASHED_ACTION + } ) ) } diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/HandsWashedReceiver.kt b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/HandsWashedReceiver.kt index 40f3101..c835810 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/HandsWashedReceiver.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/HandsWashedReceiver.kt @@ -34,11 +34,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext internal const val HANDS_WASHED_CODE = 128 +internal const val HANDS_WASHED_SCHED_CODE = 129 internal const val HANDS_WASHED_ACTION = "com.javinator9889.handwashingreminder.HANDSWASHED_EVENT" internal const val NOTIFICATION_ID_KEY = "com.javinator9889.handwashingreminder.NID" + class HandsWashedReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val emojiLoader = EmojiLoader.loadAsync(context) diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/ScheduledNotificationWorker.kt b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/ScheduledNotificationWorker.kt index e4cf5ad..6e2cd17 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/ScheduledNotificationWorker.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/ScheduledNotificationWorker.kt @@ -18,7 +18,6 @@ */ package com.javinator9889.handwashingreminder.jobs.workers -import android.app.PendingIntent import android.content.Context import android.content.Intent import androidx.annotation.ArrayRes @@ -27,10 +26,7 @@ import androidx.core.app.NotificationCompat import com.javinator9889.handwashingreminder.R import com.javinator9889.handwashingreminder.application.HandwashingApplication import com.javinator9889.handwashingreminder.emoji.EmojiLoader -import com.javinator9889.handwashingreminder.jobs.HANDS_WASHED_ACTION -import com.javinator9889.handwashingreminder.jobs.HANDS_WASHED_CODE -import com.javinator9889.handwashingreminder.jobs.HandsWashedReceiver -import com.javinator9889.handwashingreminder.jobs.NOTIFICATION_ID_KEY +import com.javinator9889.handwashingreminder.jobs.* import com.javinator9889.handwashingreminder.jobs.alarms.AlarmHandler import com.javinator9889.handwashingreminder.jobs.alarms.Alarms import com.javinator9889.handwashingreminder.notifications.Action @@ -70,27 +66,21 @@ abstract class ScheduledNotificationWorker(context: Context) { content = emojiCompat.process(content) } catch (_: IllegalStateException) { } - val washedPendingIntent = PendingIntent.getBroadcast( - context, - HANDS_WASHED_CODE, - Intent(context, HandsWashedReceiver::class.java).apply { - action = HANDS_WASHED_ACTION - putExtra(NOTIFICATION_ID_KEY, 1) - }, - PendingIntent.FLAG_UPDATE_CURRENT - ) withContext(Dispatchers.Main) { notificationsHandler.createNotification( iconDrawable = R.drawable.ic_stat_handwashing, largeIcon = R.drawable.handwashing_app_logo, title = title, content = content, - longContent = content, priority = NotificationCompat.PRIORITY_MAX, + longContent = content, action = Action( R.drawable.ic_stat_handwashing, getString(R.string.just_washed), - washedPendingIntent + HANDS_WASHED_SCHED_CODE, + Intent(context, HandsWashedReceiver::class.java).apply { + action = HANDS_WASHED_ACTION + } ) ) } diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt b/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt index 5b1c3f7..387060e 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt @@ -37,11 +37,13 @@ import com.javinator9889.handwashingreminder.R import com.javinator9889.handwashingreminder.activities.FAST_START_KEY import com.javinator9889.handwashingreminder.activities.LauncherActivity import com.javinator9889.handwashingreminder.activities.PENDING_INTENT_CODE +import com.javinator9889.handwashingreminder.jobs.NOTIFICATION_ID_KEY import com.javinator9889.handwashingreminder.jobs.ShareReceiver import com.javinator9889.handwashingreminder.utils.AndroidVersion import com.javinator9889.handwashingreminder.utils.Preferences import com.javinator9889.handwashingreminder.utils.isAtLeast import com.javinator9889.handwashingreminder.utils.notNull +import java.util.concurrent.atomic.AtomicInteger class NotificationsHandler( private val context: Context, @@ -51,6 +53,10 @@ class NotificationsHandler( groupId: String = "", groupName: String = "" ) { + companion object NotificationId { + val id = AtomicInteger(0) + } + private val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private val vibrationPattern = longArrayOf(300L, 300L, 300L, 300L) @@ -79,8 +85,7 @@ class NotificationsHandler( @StringRes content: Int, priority: Int = NotificationCompat.PRIORITY_DEFAULT, @StringRes longContent: Int = -1, - action: Action? = null, - notificationId: Int = -1 + action: Action? = null ) { val longContentProcessed = if (longContent != -1) context.getText(longContent) else null @@ -91,8 +96,7 @@ class NotificationsHandler( context.getText(content), priority, longContentProcessed, - action, - notificationId + action ) } @@ -103,8 +107,7 @@ class NotificationsHandler( content: CharSequence, priority: Int = NotificationCompat.PRIORITY_DEFAULT, longContent: CharSequence? = null, - action: Action? = null, - notificationId: Int = -1 + action: Action? = null ) { val bitmapIcon = if (isAtLeast(AndroidVersion.JELLY_BEAN_MR2)) { if (isAtLeast(AndroidVersion.P)) { @@ -127,8 +130,7 @@ class NotificationsHandler( content, priority, longContent, - action, - notificationId + action ) } @@ -139,8 +141,7 @@ class NotificationsHandler( content: CharSequence, priority: Int = NotificationCompat.PRIORITY_DEFAULT, longContent: CharSequence? = null, - action: Action? = null, - notificationId: Int = -1 + action: Action? = null ) { val notifyIntent = Intent(context, LauncherActivity::class.java).apply { flags = @@ -159,6 +160,7 @@ class NotificationsHandler( Intent(context, ShareReceiver::class.java), 0 ) + val notificationId = id.getAndIncrement() with(NotificationCompat.Builder(context, channelId)) { setSmallIcon(iconDrawable) setLargeIcon(largeIcon) @@ -168,7 +170,14 @@ class NotificationsHandler( setVibrate(vibrationPattern) setContentIntent(notifyPendingIntent) action?.let { - addAction(action.drawable, action.text, action.pendingIntent) + action.intent.putExtra(NOTIFICATION_ID_KEY, notificationId) + val pendingIntent = PendingIntent.getBroadcast( + context, + action.requestCode, + action.intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + addAction(action.drawable, action.text, pendingIntent) } addAction( R.drawable.ic_share_black, @@ -182,8 +191,7 @@ class NotificationsHandler( build() }.let { with(NotificationManagerCompat.from(context)) { - val id = if (notificationId == -1) 1 else notificationId - notify(id, it) + notify(notificationId, it) } } } @@ -224,5 +232,6 @@ class NotificationsHandler( data class Action( @DrawableRes val drawable: Int, val text: CharSequence, - val pendingIntent: PendingIntent + val requestCode: Int, + val intent: Intent ) \ No newline at end of file From 9be25fcdb1a58a65e88c1ce45c0d2b5f0e06d9a0 Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 12:57:22 +0100 Subject: [PATCH 3/6] WorkManager: check if alarms are active every hour using WorkManager --- app/build.gradle | 2 +- .../activities/LauncherActivity.kt | 2 + .../application/HandwashingApplication.kt | 38 ++++++++++++++++ .../jobs/alarms/AlarmHandler.kt | 20 ++++++--- .../jobs/workers/AlarmCheckerWorker.kt | 43 +++++++++++++++++++ 5 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/AlarmCheckerWorker.kt diff --git a/app/build.gradle b/app/build.gradle index c746f9a..2f45c98 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ android { applicationId "com.javinator9889.handwashingreminder" minSdkVersion 16 targetSdkVersion 30 - versionCode 145 + versionCode 146 versionName "1.2.1-${gitCommitHash}" multiDexEnabled true resConfigs "en", "es" diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt index 18ab4d5..692c7b6 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt @@ -319,6 +319,8 @@ class LauncherActivity : BaseFragmentActivity() { groupName = getString(alarm.groupName) ) } + Timber.d("Creating periodic work scheduler for ensuring alarms are active") + app.scheduleWorkChecker() propertiesJob.join() } diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt b/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt index ba1bf55..c83710a 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt @@ -22,16 +22,21 @@ import android.content.Context import android.content.SharedPreferences import androidx.multidex.MultiDex import androidx.preference.PreferenceManager +import androidx.work.* import com.google.android.play.core.splitcompat.SplitCompat import com.google.firebase.FirebaseApp import com.google.firebase.crashlytics.FirebaseCrashlytics import com.javinator9889.handwashingreminder.gms.ads.AdLoader +import com.javinator9889.handwashingreminder.jobs.workers.AlarmCheckerWorker +import com.javinator9889.handwashingreminder.utils.AndroidVersion import com.javinator9889.handwashingreminder.utils.LogReportTree +import com.javinator9889.handwashingreminder.utils.isAtLeast import com.javinator9889.handwashingreminder.utils.isDebuggable import javinator9889.localemanager.application.BaseApplication import javinator9889.localemanager.utils.languagesupport.LanguagesSupport.Language import kotlinx.coroutines.* import timber.log.Timber +import java.util.concurrent.TimeUnit class HandwashingApplication : BaseApplication() { @@ -66,6 +71,39 @@ class HandwashingApplication : BaseApplication() { firebaseInitDeferred = initFirebaseAppAsync() } + internal fun scheduleWorkChecker() { + val constraints = Constraints.Builder().run { + setRequiredNetworkType(NetworkType.NOT_REQUIRED) + setRequiresBatteryNotLow(false) + setRequiresCharging(false) + if (isAtLeast(AndroidVersion.O)) + setRequiresDeviceIdle(false) + setRequiresStorageNotLow(false) + build() + } + val work = + PeriodicWorkRequestBuilder( + 1, TimeUnit.HOURS, + 15, TimeUnit.MINUTES + ).run { + setBackoffCriteria( + BackoffPolicy.EXPONENTIAL, + OneTimeWorkRequest.MIN_BACKOFF_MILLIS, + TimeUnit.MILLISECONDS + ) + setConstraints(constraints) + addTag("Alarm Checker") + build() + } + with(WorkManager.getInstance(this)) { + enqueueUniquePeriodicWork( + "Alarm checker job", + ExistingPeriodicWorkPolicy.KEEP, + work + ) + } + } + private fun initFirebaseAppAsync(): Deferred { return scope.async { withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/alarms/AlarmHandler.kt b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/alarms/AlarmHandler.kt index 34f1282..ca5d6b8 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/alarms/AlarmHandler.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/alarms/AlarmHandler.kt @@ -41,7 +41,10 @@ class AlarmHandler(private val context: Context) { fun scheduleAlarm(alarm: Alarms) { try { cancelAlarm(alarm) - val pendingIntent = createPendingIntentForAlarm(alarm) + val pendingIntent = createPendingIntentForAlarm( + alarm, + PendingIntent.FLAG_UPDATE_CURRENT + )!! val alarmTime = getTimeForAlarm(alarm) val scheduleTime = timeAt(alarmTime.hour, alarmTime.minute) AlarmManagerCompat.setExactAndAllowWhileIdle( @@ -59,8 +62,9 @@ class AlarmHandler(private val context: Context) { } fun cancelAlarm(alarm: Alarms) { - val pendingIntent = createPendingIntentForAlarm(alarm) - alarmManager.cancel(pendingIntent) + val pendingIntent = + createPendingIntentForAlarm(alarm, PendingIntent.FLAG_NO_CREATE) + pendingIntent?.let { alarmManager.cancel(it) } } fun cancelAllAlarms() { @@ -68,10 +72,16 @@ class AlarmHandler(private val context: Context) { cancelAlarm(alarm) } - private fun createPendingIntentForAlarm(alarm: Alarms): PendingIntent { + fun isAlarmAlive(alarm: Alarms) = + createPendingIntentForAlarm(alarm, PendingIntent.FLAG_NO_CREATE) != null + + private fun createPendingIntentForAlarm( + alarm: Alarms, + flags: Int = 0 + ): PendingIntent? { return with(Intent(context, AlarmReceiver::class.java)) { putExtra(IDENTIFIER, alarm.identifier) - PendingIntent.getBroadcast(context, alarm.code, this, 0) + PendingIntent.getBroadcast(context, alarm.code, this, flags) } } diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/AlarmCheckerWorker.kt b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/AlarmCheckerWorker.kt new file mode 100644 index 0000000..d698d6d --- /dev/null +++ b/app/src/main/java/com/javinator9889/handwashingreminder/jobs/workers/AlarmCheckerWorker.kt @@ -0,0 +1,43 @@ +/* + * Copyright © 2021 - present | Handwashing reminder by Javinator9889 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + * + * Created by Javinator9889 on 2/01/21 - Handwashing reminder. + */ +package com.javinator9889.handwashingreminder.jobs.workers + +import android.content.Context +import androidx.work.Worker +import androidx.work.WorkerParameters +import com.javinator9889.handwashingreminder.jobs.alarms.AlarmHandler +import com.javinator9889.handwashingreminder.jobs.alarms.Alarms +import timber.log.Timber + +class AlarmCheckerWorker(context: Context, workerParameters: WorkerParameters) : + Worker(context, workerParameters) { + private val alarmHandler = AlarmHandler(context) + + override fun doWork(): Result = + try { + for (alarm in Alarms.values()) { + if (!alarmHandler.isAlarmAlive(alarm)) + alarmHandler.scheduleAlarm(alarm) + } + Result.success() + } catch (e: Throwable) { + Timber.e(e, "Unexpected error while checking alive alarms!") + Result.retry() + } +} \ No newline at end of file From 2261fe61537aeccc8d78b8b5901731ae1c9ce19d Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 13:14:25 +0100 Subject: [PATCH 4/6] Preferences: added option to skip intro animations --- app/build.gradle | 2 +- .../activities/LauncherActivity.kt | 14 +++++++++++--- .../views/fragments/diseases/DiseasesFragment.kt | 4 ++-- .../handwashingreminder/data/SettingsLoader.kt | 4 ++++ .../handwashingreminder/utils/Constants.kt | 1 + app/src/main/res/values-es/strings.xml | 6 +++++- app/src/main/res/values/strings.xml | 4 ++++ app/src/main/res/xml/preferences.xml | 7 +++++++ 8 files changed, 35 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2f45c98..fe36219 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ android { applicationId "com.javinator9889.handwashingreminder" minSdkVersion 16 targetSdkVersion 30 - versionCode 146 + versionCode 147 versionName "1.2.1-${gitCommitHash}" multiDexEnabled true resConfigs "en", "es" diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt index 692c7b6..0f5935d 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/activities/LauncherActivity.kt @@ -74,6 +74,7 @@ class LauncherActivity : BaseFragmentActivity() { private val activityIntentDeferred = CompletableDeferred() private val splitInstallManager = SplitInstallManagerFactory.create(app) private lateinit var binding: SplashScreenBinding + @get:LayoutRes override val layoutId: Int = R.layout.splash_screen @@ -127,6 +128,7 @@ class LauncherActivity : BaseFragmentActivity() { override fun onAnimationStart(animation: Animation?) { Timber.d("Animation started!") } + override fun onAnimationRepeat(animation: Animation?) {} override fun onAnimationEnd(animation: Animation?) { Timber.d("Animation is completed") @@ -134,7 +136,11 @@ class LauncherActivity : BaseFragmentActivity() { binding.logo.playAnimation() } }) - if (isThereAnySpecialEvent && !isDebuggable()) { + val introAnimationDisabled = sharedPreferences.getBoolean( + Preferences.INTRO_ANIMATIONS, + false + ) + if (isThereAnySpecialEvent && !isDebuggable() && !introAnimationDisabled) { Timber.d("Starting custom animation...") binding.logo.setAnimation(AnimatedResources.STAY_SAFE_STAY_HOME.res) binding.logo.addLottieOnCompositionLoadedListener { @@ -256,8 +262,10 @@ class LauncherActivity : BaseFragmentActivity() { if (Ads.MODULE_NAME in splitInstallManager.installedModules && sharedPreferences.getBoolean(ADS_ENABLED, true) ) { - val className = "${Ads.PACKAGE_NAME}.${Ads - .CLASS_NAME}\$${Ads.PROVIDER_NAME}" + val className = "${Ads.PACKAGE_NAME}.${ + Ads + .CLASS_NAME + }\$${Ads.PROVIDER_NAME}" val adProvider = Class.forName(className).kotlin .objectInstance as AdLoader.Provider app.adLoader = adProvider.instance(context) diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/activities/views/fragments/diseases/DiseasesFragment.kt b/app/src/main/java/com/javinator9889/handwashingreminder/activities/views/fragments/diseases/DiseasesFragment.kt index 48d1726..1649b74 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/activities/views/fragments/diseases/DiseasesFragment.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/activities/views/fragments/diseases/DiseasesFragment.kt @@ -89,7 +89,7 @@ class DiseasesFragment : BaseFragmentView(), lifecycleScope.launchWhenStarted { loadingRecyclerViewBinding.loading.visibility = View.VISIBLE handwashBinding.countLoader.visibility = View.VISIBLE - informationViewModel.parsedHTMLText.observe(viewLifecycleOwner) { + informationViewModel.parsedHTMLText.observe(owner = viewLifecycleOwner) { if (it.isEmpty()) return@observe lifecycleScope.launch { @@ -110,7 +110,7 @@ class DiseasesFragment : BaseFragmentView(), loadingRecyclerViewBinding.container.visibility = View.VISIBLE } } - handwashingViewModel.allData.observe(viewLifecycleOwner) { + handwashingViewModel.allData.observe(owner = viewLifecycleOwner) { lifecycleScope.launch { dataSet?.let { set -> Timber.d("Adding new items to dataSet") diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/data/SettingsLoader.kt b/app/src/main/java/com/javinator9889/handwashingreminder/data/SettingsLoader.kt index fc55104..f32d2b4 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/data/SettingsLoader.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/data/SettingsLoader.kt @@ -318,6 +318,10 @@ class SettingsLoader( Preferences.PERFORMANCE_ANIMATIONS, Ionicons.Icon.ion_battery_low ).also { deferreds.add(it) } + setupPreferenceAsync( + Preferences.INTRO_ANIMATIONS, + Ionicons.Icon.ion_play + ).also { deferreds.add(it) } setupPreferenceAsync( "notifications:settings", onClickListener = { diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt b/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt index 3b6ab6f..548ad7a 100644 --- a/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt +++ b/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt @@ -44,6 +44,7 @@ object Preferences { const val INITIAL_TUTORIAL_DONE = "app:tutorial:is_done" const val ACTIVITY_MINIMUM_TIME = "activity:gms:minimumInterval" const val PERFORMANCE_ANIMATIONS = "app:performance:animations" + const val INTRO_ANIMATIONS = "app:performance:intro_animation" } object TimeConfig { diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6bc1bbe..5ff926e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -34,7 +34,7 @@ público hay mucha gente y no sabes si están enfermos o no 😷.\n Incluso en tu propio coche pueden haber enfermedades en los pomos o en el volante 🚗, así que lávate las manos lo antes que puedas - para evitar enfermedades 💦👏 + para evitar enfermedades 💦👏 Política de privacidad Términos y condiciones @@ -299,6 +299,10 @@ Actualmente, las animaciones están activadas. Ten en cuenta que esto puede afectar tanto al rendimiento como a la batería No se mostrará ninguna animación + Deshabilita las animaciones al inicio + Si, al abrir la aplicación, hay algún evento especial, se muestra una animación. + Desmarca esta opción para saltarla + No se mostrarán animaciones al iniciar la aplicación Error al cargar información sobre las noticias Ajustes de notificaciones ¡Acabo de lavarlas! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d257f50..ba41a30 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -327,6 +327,10 @@ Currently, the app will play some animations. Keep in mind that it can affect both performance and battery life No animations will be played + Disable app\'s intro animations + When opening the app, if there is an special + event, an animation is displayed. Uncheck this to skip that animation + No animations will be played while opening the app Error while loading news data Edit notification settings Just washed them! diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index a091e21..9518834 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -79,6 +79,13 @@ android:summaryOff="@string/animations_off" android:summaryOn="@string/animations_on" android:title="@string/disable_animations" /> + + From 214fdfc49d403cb8e8ebdeadef328de4177d2007 Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 14:16:07 +0100 Subject: [PATCH 5/6] dependencies: changed Firebase versions for compatibility in between them --- app/build.gradle | 6 +++--- appintro/src/main/AndroidManifest.xml | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fe36219..030fb49 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -154,13 +154,13 @@ dependencies { // https://kotlinlang.org/docs/reference/reflection.html implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" // https://firebase.google.com/docs/android/setup#add-sdks - api 'com.google.firebase:firebase-common-ktx:19.5.0' + api 'com.google.firebase:firebase-common-ktx:19.4.0' api 'com.google.firebase:firebase-analytics:18.0.0' api 'com.google.firebase:firebase-crashlytics:17.3.0' - api 'com.google.firebase:firebase-perf:19.0.11' + api 'com.google.firebase:firebase-perf:19.0.10' implementation 'com.google.firebase:firebase-auth:20.0.1' // http://airbnb.io/lottie/#/android?id=getting-started - api 'com.airbnb.android:lottie:3.5.0' + api 'com.airbnb.android:lottie:3.6.0' // https://firebase.google.com/docs/remote-config/use-config-android implementation 'com.google.firebase:firebase-config:20.0.2' implementation 'com.google.firebase:firebase-config-ktx:20.0.2' diff --git a/appintro/src/main/AndroidManifest.xml b/appintro/src/main/AndroidManifest.xml index fe7cc77..8b3d881 100644 --- a/appintro/src/main/AndroidManifest.xml +++ b/appintro/src/main/AndroidManifest.xml @@ -12,17 +12,12 @@ - - - - - From cb493c3d986e958de2800ba95fc09d2e2157a14f Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Sat, 2 Jan 2021 14:24:39 +0100 Subject: [PATCH 6/6] dependencies: using Firebase BoM for managing versions --- ads/build.gradle | 2 +- app/build.gradle | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ads/build.gradle b/ads/build.gradle index ff843f9..e6bf5f6 100644 --- a/ads/build.gradle +++ b/ads/build.gradle @@ -41,7 +41,7 @@ dependencies { implementation project(':app') // https://firebase.google.com/docs/admob/android/quick-start#import_the_mobile_ads_sdk - implementation 'com.google.firebase:firebase-ads:19.6.0' + implementation 'com.google.firebase:firebase-ads' } repositories { mavenCentral() diff --git a/app/build.gradle b/app/build.gradle index 030fb49..2f3af40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ android { applicationId "com.javinator9889.handwashingreminder" minSdkVersion 16 targetSdkVersion 30 - versionCode 147 + versionCode 148 versionName "1.2.1-${gitCommitHash}" multiDexEnabled true resConfigs "en", "es" @@ -109,6 +109,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { } } +apply plugin: 'com.google.gms.google-services' dependencies { def room_version = "2.2.6" implementation fileTree(dir: 'libs', include: ['*.jar']) @@ -153,17 +154,17 @@ dependencies { implementation 'androidx.collection:collection-ktx:1.1.0' // https://kotlinlang.org/docs/reference/reflection.html implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - // https://firebase.google.com/docs/android/setup#add-sdks - api 'com.google.firebase:firebase-common-ktx:19.4.0' - api 'com.google.firebase:firebase-analytics:18.0.0' - api 'com.google.firebase:firebase-crashlytics:17.3.0' - api 'com.google.firebase:firebase-perf:19.0.10' - implementation 'com.google.firebase:firebase-auth:20.0.1' + // https://firebase.google.com/docs/android/setup#analytics-enabled + api platform('com.google.firebase:firebase-bom:26.1.1') + // https://firebase.google.com/docs/android/setup#available-libraries + api 'com.google.firebase:firebase-analytics-ktx' + api 'com.google.firebase:firebase-crashlytics-ktx' + api 'com.google.firebase:firebase-perf-ktx' + implementation 'com.google.firebase:firebase-auth-ktx' + // https://firebase.google.com/docs/remote-config/use-config-android + implementation 'com.google.firebase:firebase-config-ktx' // http://airbnb.io/lottie/#/android?id=getting-started api 'com.airbnb.android:lottie:3.6.0' - // https://firebase.google.com/docs/remote-config/use-config-android - implementation 'com.google.firebase:firebase-config:20.0.2' - implementation 'com.google.firebase:firebase-config-ktx:20.0.2' // https://mvnrepository.com/artifact/androidx.emoji/emoji/ api 'androidx.emoji:emoji:1.1.0' api 'androidx.emoji:emoji-appcompat:1.1.0' @@ -210,4 +211,3 @@ dependencies { // https://developer.android.com/jetpack/androidx/releases/work#declaring_dependencies implementation "androidx.work:work-runtime-ktx:2.4.0" } -apply plugin: 'com.google.gms.google-services'