diff --git a/build.gradle.kts b/build.gradle.kts index 675df891e..a96be9f96 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,8 +18,6 @@ allprojects { mavenCentral() maven(url = "https://plugins.gradle.org/m2/") maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") - maven(url = "https://kotlin.bintray.com/ktor") - maven(url = "https://kotlin.bintray.com/kotlin-js-wrappers") maven(url = "https://jitpack.io") } } diff --git a/uhabits-android/build.gradle.kts b/uhabits-android/build.gradle.kts index 3d97312e4..8e7103475 100644 --- a/uhabits-android/build.gradle.kts +++ b/uhabits-android/build.gradle.kts @@ -18,7 +18,7 @@ */ plugins { - id("com.github.triplet.play") version "3.6.0" + id("com.github.triplet.play") version "3.7.0" id("com.android.application") id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.kapt") @@ -32,13 +32,13 @@ tasks.compileLint { android { - compileSdk = 30 + compileSdk = 31 defaultConfig { versionCode = 20003 versionName = "2.0.3" minSdk = 23 - targetSdk = 30 + targetSdk = 31 applicationId = "org.isoron.uhabits" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -86,10 +86,10 @@ android { } dependencies { - val daggerVersion = "2.40" - val kotlinVersion = "1.5.31" + val daggerVersion = "2.40.3" + val kotlinVersion = "1.6.0" val kxCoroutinesVersion = "1.5.2" - val ktorVersion = "1.6.4" + val ktorVersion = "1.6.6" val espressoVersion = "3.4.0" androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion") @@ -98,7 +98,7 @@ dependencies { androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.1") androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion") androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion") - androidTestImplementation("androidx.annotation:annotation:1.2.0") + androidTestImplementation("androidx.annotation:annotation:1.3.0") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0") androidTestImplementation("androidx.test:rules:1.4.0") diff --git a/uhabits-android/src/main/AndroidManifest.xml b/uhabits-android/src/main/AndroidManifest.xml index b5d06f181..3b0851207 100644 --- a/uhabits-android/src/main/AndroidManifest.xml +++ b/uhabits-android/src/main/AndroidManifest.xml @@ -17,9 +17,10 @@ ~ with this program. If not, see . --> + + @@ -48,11 +49,11 @@ android:name=".activities.habits.list.ListHabitsActivity" android:exported="true" android:label="@string/main_activity_title" - android:launchMode="singleTop"> - + android:launchMode="singleTop" /> @@ -85,6 +86,7 @@ @@ -93,6 +95,7 @@ @@ -101,6 +104,7 @@ @@ -117,9 +121,10 @@ @@ -128,13 +133,14 @@ @@ -152,6 +158,7 @@ @@ -164,6 +171,7 @@ @@ -176,6 +184,7 @@ @@ -188,6 +197,7 @@ @@ -200,6 +210,7 @@ @@ -210,13 +221,17 @@ android:resource="@xml/widget_target_info" /> - + - + @@ -267,7 +282,7 @@ + android:exported="false"> diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt index 5a4c79f1d..089af4af2 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt @@ -25,8 +25,6 @@ import android.app.AlarmManager.RTC_WAKEUP import android.app.PendingIntent import android.content.Context import android.content.Context.ALARM_SERVICE -import android.os.Build.VERSION.SDK_INT -import android.os.Build.VERSION_CODES.M import android.util.Log import org.isoron.uhabits.core.AppScope import org.isoron.uhabits.core.models.Habit @@ -58,10 +56,7 @@ class IntentScheduler ) return SchedulerResult.IGNORED } - if (SDK_INT >= M) - manager.setExactAndAllowWhileIdle(alarmType, timestamp, intent) - else - manager.setExact(alarmType, timestamp, intent) + manager.setExactAndAllowWhileIdle(alarmType, timestamp, intent) return SchedulerResult.OK } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt index 5df329a95..841fa55e6 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt @@ -20,6 +20,7 @@ package org.isoron.uhabits.intents import android.app.PendingIntent +import android.app.PendingIntent.FLAG_IMMUTABLE import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.app.PendingIntent.getBroadcast import android.content.Context @@ -49,7 +50,7 @@ class PendingIntentFactory action = WidgetReceiver.ACTION_ADD_REPETITION if (timestamp != null) putExtra("timestamp", timestamp.unixTime) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun dismissNotification(habit: Habit): PendingIntent = @@ -60,7 +61,7 @@ class PendingIntentFactory action = WidgetReceiver.ACTION_DISMISS_REMINDER data = Uri.parse(habit.uriString) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun removeRepetition(habit: Habit, timestamp: Timestamp?): PendingIntent = @@ -72,7 +73,7 @@ class PendingIntentFactory data = Uri.parse(habit.uriString) if (timestamp != null) putExtra("timestamp", timestamp.unixTime) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun showHabit(habit: Habit): PendingIntent = @@ -84,7 +85,7 @@ class PendingIntentFactory habit ) ) - .getPendingIntent(0, FLAG_UPDATE_CURRENT)!! + .getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)!! fun showReminder( habit: Habit, @@ -100,7 +101,7 @@ class PendingIntentFactory putExtra("timestamp", timestamp) putExtra("reminderTime", reminderTime) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun snoozeNotification(habit: Habit): PendingIntent = @@ -111,7 +112,7 @@ class PendingIntentFactory data = Uri.parse(habit.uriString) action = ReminderReceiver.ACTION_SNOOZE_REMINDER }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent = @@ -123,7 +124,7 @@ class PendingIntentFactory action = WidgetReceiver.ACTION_TOGGLE_REPETITION if (timestamp != null) putExtra("timestamp", timestamp) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun setNumericalValue( @@ -142,7 +143,7 @@ class PendingIntentFactory putExtra("numericalValue", numericalValue) if (timestamp != null) putExtra("timestamp", timestamp) }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) fun updateWidgets(): PendingIntent = @@ -152,6 +153,6 @@ class PendingIntentFactory Intent(context, WidgetReceiver::class.java).apply { action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE }, - FLAG_UPDATE_CURRENT + FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt index 04f3d8d92..3721f04d5 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt @@ -153,13 +153,15 @@ class AndroidNotificationTray if (preferences.shouldMakeNotificationsLed()) builder.setLights(Color.RED, 1000, 1000) - val snoozeAction = Action( - R.drawable.ic_action_snooze, - context.getString(R.string.snooze), - pendingIntents.snoozeNotification(habit) - ) - wearableExtender.addAction(snoozeAction) - builder.addAction(snoozeAction) + if (SDK_INT < Build.VERSION_CODES.S) { + val snoozeAction = Action( + R.drawable.ic_action_snooze, + context.getString(R.string.snooze), + pendingIntents.snoozeNotification(habit) + ) + wearableExtender.addAction(snoozeAction) + builder.addAction(snoozeAction) + } builder.extend(wearableExtender) return builder.build() diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.kt b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.kt index 951b46ae8..6eb10dc7e 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.kt @@ -22,6 +22,8 @@ import android.content.BroadcastReceiver import android.content.ContentUris import android.content.Context import android.content.Intent +import android.os.Build +import android.os.Build.VERSION.SDK_INT import android.util.Log import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.core.models.Habit @@ -76,8 +78,21 @@ class ReminderReceiver : BroadcastReceiver() { } ACTION_SNOOZE_REMINDER -> { if (habit == null) return - Log.d("ReminderReceiver", String.format("onSnoozePressed habit=%d", habit.id)) - reminderController.onSnoozePressed(habit, context) + if (SDK_INT < Build.VERSION_CODES.S) { + Log.d( + "ReminderReceiver", + String.format("onSnoozePressed habit=%d", habit.id) + ) + reminderController.onSnoozePressed(habit, context) + } else { + Log.w( + "ReminderReceiver", + String.format( + "onSnoozePressed habit=%d, should be deactivated in recent versions.", + habit.id + ) + ) + } } Intent.ACTION_BOOT_COMPLETED -> { Log.d("ReminderReceiver", "onBootCompleted") diff --git a/uhabits-core/build.gradle.kts b/uhabits-core/build.gradle.kts index c846a8888..6002df223 100644 --- a/uhabits-core/build.gradle.kts +++ b/uhabits-core/build.gradle.kts @@ -43,11 +43,11 @@ kotlin { val jvmMain by getting { dependencies { implementation(kotlin("stdlib-jdk8")) - compileOnly("com.google.dagger:dagger:2.40") + compileOnly("com.google.dagger:dagger:2.40.3") implementation("com.google.guava:guava:31.0.1-android") - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.5.31") + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2") - implementation("androidx.annotation:annotation:1.2.0") + implementation("androidx.annotation:annotation:1.3.0") implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("com.opencsv:opencsv:5.5.2") implementation("commons-codec:commons-codec:1.15") diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/NotificationTray.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/NotificationTray.kt index 4d6c87fbe..5239ed44b 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/NotificationTray.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/NotificationTray.kt @@ -23,13 +23,11 @@ import org.isoron.uhabits.core.commands.Command import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.CreateRepetitionCommand import org.isoron.uhabits.core.commands.DeleteHabitsCommand -import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.tasks.Task import org.isoron.uhabits.core.tasks.TaskRunner -import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset import java.util.HashMap import java.util.Locale import java.util.Objects @@ -106,17 +104,17 @@ class NotificationTray @Inject constructor( internal class NotificationData(val timestamp: Timestamp, val reminderTime: Long) private inner class ShowNotificationTask(private val habit: Habit, data: NotificationData) : Task { - var todayValue = 0 + var isCompleted = false private val timestamp: Timestamp = data.timestamp private val reminderTime: Long = data.reminderTime + override fun doInBackground() { - val today = getTodayWithOffset() - todayValue = habit.computedEntries.get(today).value + isCompleted = habit.isCompletedToday() } override fun onPostExecute() { systemTray.log("Showing notification for habit=" + habit.id) - if (todayValue != Entry.UNKNOWN) { + if (isCompleted) { systemTray.log( String.format( Locale.US, diff --git a/uhabits-server/build.gradle.kts b/uhabits-server/build.gradle.kts index 2dd787bb4..197fd4c30 100644 --- a/uhabits-server/build.gradle.kts +++ b/uhabits-server/build.gradle.kts @@ -33,9 +33,9 @@ application { } dependencies { - val ktorVersion = "1.6.4" - val kotlinVersion = "1.5.31" - val logbackVersion = "1.2.6" + val ktorVersion = "1.6.6" + val kotlinVersion = "1.6.0" + val logbackVersion = "1.2.7" implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") implementation("io.ktor:ktor-server-netty:$ktorVersion") implementation("ch.qos.logback:logback-classic:$logbackVersion")