Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.2.1 - hotfix #6

Merged
merged 6 commits into from Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion ads/build.gradle
Expand Up @@ -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()
Expand Down
26 changes: 13 additions & 13 deletions app/build.gradle
Expand Up @@ -42,7 +42,7 @@ android {
applicationId "com.javinator9889.handwashingreminder"
minSdkVersion 16
targetSdkVersion 30
versionCode 143
versionCode 148
versionName "1.2.1-${gitCommitHash}"
multiDexEnabled true
resConfigs "en", "es"
Expand Down Expand Up @@ -109,8 +109,9 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
}
}

apply plugin: 'com.google.gms.google-services'
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'
Expand Down Expand Up @@ -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'
// http://airbnb.io/lottie/#/android?id=getting-started
api 'com.airbnb.android:lottie:3.5.0'
// 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:20.0.2'
implementation 'com.google.firebase:firebase-config-ktx:20.0.2'
implementation 'com.google.firebase:firebase-config-ktx'
// http://airbnb.io/lottie/#/android?id=getting-started
api 'com.airbnb.android:lottie:3.6.0'
// https://mvnrepository.com/artifact/androidx.emoji/emoji/
api 'androidx.emoji:emoji:1.1.0'
api 'androidx.emoji:emoji-appcompat:1.1.0'
Expand Down Expand Up @@ -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'
Expand Up @@ -74,6 +74,7 @@ class LauncherActivity : BaseFragmentActivity<SplashScreenBinding>() {
private val activityIntentDeferred = CompletableDeferred<Intent>()
private val splitInstallManager = SplitInstallManagerFactory.create(app)
private lateinit var binding: SplashScreenBinding

@get:LayoutRes
override val layoutId: Int = R.layout.splash_screen

Expand Down Expand Up @@ -127,14 +128,19 @@ class LauncherActivity : BaseFragmentActivity<SplashScreenBinding>() {
override fun onAnimationStart(animation: Animation?) {
Timber.d("Animation started!")
}

override fun onAnimationRepeat(animation: Animation?) {}
override fun onAnimationEnd(animation: Animation?) {
Timber.d("Animation is completed")
animationLoaded.complete(true)
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 {
Expand Down Expand Up @@ -256,8 +262,10 @@ class LauncherActivity : BaseFragmentActivity<SplashScreenBinding>() {
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)
Expand Down Expand Up @@ -319,6 +327,8 @@ class LauncherActivity : BaseFragmentActivity<SplashScreenBinding>() {
groupName = getString(alarm.groupName)
)
}
Timber.d("Creating periodic work scheduler for ensuring alarms are active")
app.scheduleWorkChecker()
propertiesJob.join()
}

Expand Down
Expand Up @@ -89,7 +89,7 @@ class DiseasesFragment : BaseFragmentView<MainDiseaseViewBinding>(),
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 {
Expand All @@ -110,7 +110,7 @@ class DiseasesFragment : BaseFragmentView<MainDiseaseViewBinding>(),
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")
Expand Down
Expand Up @@ -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() {
Expand Down Expand Up @@ -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<AlarmCheckerWorker>(
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<Unit> {
return scope.async {
withContext(Dispatchers.IO) {
Expand Down
Expand Up @@ -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 = {
Expand Down
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
}
)
)
}
Expand Down
Expand Up @@ -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)
Expand Down
Expand Up @@ -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() {
Expand All @@ -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)
}
}
}
}
}
Expand Up @@ -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(
Expand All @@ -59,19 +62,26 @@ 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() {
for (alarm in Alarms.values())
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)
}
}

Expand Down