mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Fix some issues with reminders and print more logs
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
VERSION_CODE = 39
|
VERSION_CODE = 41
|
||||||
VERSION_NAME = 1.8.0
|
VERSION_NAME = 1.8.2
|
||||||
|
|
||||||
MIN_SDK_VERSION = 21
|
MIN_SDK_VERSION = 21
|
||||||
TARGET_SDK_VERSION = 29
|
TARGET_SDK_VERSION = 29
|
||||||
|
|||||||
@@ -30,12 +30,5 @@ import javax.inject.*
|
|||||||
class HabitLogger
|
class HabitLogger
|
||||||
@Inject constructor() {
|
@Inject constructor() {
|
||||||
|
|
||||||
fun logReminderScheduled(habit: Habit, reminderTime: Long) {
|
|
||||||
val min = Math.min(3, habit.name.length)
|
|
||||||
val name = habit.name.substring(0, min)
|
|
||||||
val df = DateFormats.getBackupDateFormat()
|
|
||||||
val time = df.format(Date(reminderTime))
|
|
||||||
Log.i("ReminderHelper",
|
|
||||||
String.format("Setting alarm (%s): %s", time, name))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,14 @@ import android.content.*
|
|||||||
import android.content.Context.*
|
import android.content.Context.*
|
||||||
import android.os.Build.VERSION.*
|
import android.os.Build.VERSION.*
|
||||||
import android.os.Build.VERSION_CODES.*
|
import android.os.Build.VERSION_CODES.*
|
||||||
|
import android.util.*
|
||||||
import org.isoron.androidbase.*
|
import org.isoron.androidbase.*
|
||||||
import org.isoron.uhabits.*
|
import org.isoron.uhabits.*
|
||||||
import org.isoron.uhabits.core.*
|
import org.isoron.uhabits.core.*
|
||||||
import org.isoron.uhabits.core.models.*
|
import org.isoron.uhabits.core.models.*
|
||||||
import org.isoron.uhabits.core.reminders.*
|
import org.isoron.uhabits.core.reminders.*
|
||||||
|
import org.isoron.uhabits.core.utils.*
|
||||||
|
import java.util.*
|
||||||
import javax.inject.*
|
import javax.inject.*
|
||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
@@ -44,6 +47,13 @@ class IntentScheduler
|
|||||||
context.getSystemService(ALARM_SERVICE) as AlarmManager
|
context.getSystemService(ALARM_SERVICE) as AlarmManager
|
||||||
|
|
||||||
fun schedule(timestamp: Long, intent: PendingIntent) {
|
fun schedule(timestamp: Long, intent: PendingIntent) {
|
||||||
|
Log.d("IntentScheduler",
|
||||||
|
"timestamp=" + timestamp + " current=" + System.currentTimeMillis())
|
||||||
|
if (timestamp < System.currentTimeMillis()) {
|
||||||
|
Log.e("IntentScheduler",
|
||||||
|
"Ignoring attempt to schedule intent in the past.")
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (SDK_INT >= M)
|
if (SDK_INT >= M)
|
||||||
manager.setExactAndAllowWhileIdle(RTC_WAKEUP, timestamp, intent)
|
manager.setExactAndAllowWhileIdle(RTC_WAKEUP, timestamp, intent)
|
||||||
else
|
else
|
||||||
@@ -55,6 +65,19 @@ class IntentScheduler
|
|||||||
timestamp: Long) {
|
timestamp: Long) {
|
||||||
val intent = pendingIntents.showReminder(habit, reminderTime, timestamp)
|
val intent = pendingIntents.showReminder(habit, reminderTime, timestamp)
|
||||||
schedule(reminderTime, intent)
|
schedule(reminderTime, intent)
|
||||||
logger.logReminderScheduled(habit, reminderTime)
|
logReminderScheduled(habit, reminderTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun log(componentName: String, msg: String) {
|
||||||
|
Log.d(componentName, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logReminderScheduled(habit: Habit, reminderTime: Long) {
|
||||||
|
val min = Math.min(5, habit.name.length)
|
||||||
|
val name = habit.name.substring(0, min)
|
||||||
|
val df = DateFormats.getBackupDateFormat()
|
||||||
|
val time = df.format(Date(reminderTime))
|
||||||
|
Log.i("ReminderHelper",
|
||||||
|
String.format("Setting alarm (%s): %s", time, name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,12 @@ class AndroidNotificationTray
|
|||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val ringtoneManager: RingtoneManager
|
private val ringtoneManager: RingtoneManager
|
||||||
) : NotificationTray.SystemTray {
|
) : NotificationTray.SystemTray {
|
||||||
|
|
||||||
private var active = HashSet<Int>()
|
private var active = HashSet<Int>()
|
||||||
|
|
||||||
|
override fun log(msg: String) {
|
||||||
|
Log.d("AndroidNotificationTray", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun removeNotification(id: Int) {
|
override fun removeNotification(id: Int) {
|
||||||
val manager = NotificationManagerCompat.from(context)
|
val manager = NotificationManagerCompat.from(context)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class ReminderController
|
|||||||
|
|
||||||
public void onSnoozeTimePicked(Habit habit, int hour, int minute)
|
public void onSnoozeTimePicked(Habit habit, int hour, int minute)
|
||||||
{
|
{
|
||||||
Long time = DateUtils.getUpcomingTimeInMillis(hour, minute);
|
long time = DateUtils.getUpcomingTimeInMillis(hour, minute);
|
||||||
reminderScheduler.scheduleAtTime(habit, time);
|
reminderScheduler.scheduleAtTime(habit, time);
|
||||||
notificationTray.cancel(habit);
|
notificationTray.cancel(habit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import org.isoron.uhabits.*;
|
|||||||
import org.isoron.uhabits.core.models.*;
|
import org.isoron.uhabits.core.models.*;
|
||||||
import org.isoron.uhabits.core.utils.*;
|
import org.isoron.uhabits.core.utils.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import static android.content.ContentUris.*;
|
import static android.content.ContentUris.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,8 +67,8 @@ public class ReminderReceiver extends BroadcastReceiver
|
|||||||
|
|
||||||
if (intent.getData() != null)
|
if (intent.getData() != null)
|
||||||
habit = habits.getById(parseId(intent.getData()));
|
habit = habits.getById(parseId(intent.getData()));
|
||||||
final Long timestamp = intent.getLongExtra("timestamp", today);
|
final long timestamp = intent.getLongExtra("timestamp", today);
|
||||||
final Long reminderTime = intent.getLongExtra("reminderTime", today);
|
final long reminderTime = intent.getLongExtra("reminderTime", today);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -74,6 +76,12 @@ public class ReminderReceiver extends BroadcastReceiver
|
|||||||
{
|
{
|
||||||
case ACTION_SHOW_REMINDER:
|
case ACTION_SHOW_REMINDER:
|
||||||
if (habit == null) return;
|
if (habit == null) return;
|
||||||
|
Log.d("ReminderReceiver", String.format(
|
||||||
|
Locale.US,
|
||||||
|
"onShowReminder habit=%d timestamp=%d reminderTime=%d",
|
||||||
|
habit.id,
|
||||||
|
timestamp,
|
||||||
|
reminderTime));
|
||||||
reminderController.onShowReminder(habit,
|
reminderController.onShowReminder(habit,
|
||||||
new Timestamp(timestamp), reminderTime);
|
new Timestamp(timestamp), reminderTime);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import org.isoron.uhabits.core.*;
|
|||||||
import org.isoron.uhabits.core.commands.*;
|
import org.isoron.uhabits.core.commands.*;
|
||||||
import org.isoron.uhabits.core.models.*;
|
import org.isoron.uhabits.core.models.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import javax.inject.*;
|
import javax.inject.*;
|
||||||
|
|
||||||
import static org.isoron.uhabits.core.utils.DateUtils.*;
|
import static org.isoron.uhabits.core.utils.DateUtils.*;
|
||||||
@@ -59,22 +61,44 @@ public class ReminderScheduler implements CommandRunner.Listener
|
|||||||
|
|
||||||
public void schedule(@NonNull Habit habit)
|
public void schedule(@NonNull Habit habit)
|
||||||
{
|
{
|
||||||
if (!habit.hasReminder()) return;
|
if (!habit.hasReminder()) {
|
||||||
Long reminderTime = habit.getReminder().getTimeInMillis();
|
sys.log("ReminderScheduler", "habit=" + habit.id + " has no reminder. Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long reminderTime = habit.getReminder().getTimeInMillis();
|
||||||
scheduleAtTime(habit, reminderTime);
|
scheduleAtTime(habit, reminderTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scheduleAtTime(@NonNull Habit habit, @NonNull Long reminderTime)
|
public void scheduleAtTime(@NonNull Habit habit, long reminderTime)
|
||||||
{
|
{
|
||||||
if (reminderTime == null) throw new IllegalArgumentException();
|
sys.log("ReminderScheduler", "Scheduling alarm for habit=" + habit.id);
|
||||||
if (!habit.hasReminder()) return;
|
|
||||||
if (habit.isArchived()) return;
|
if (!habit.hasReminder()) {
|
||||||
|
sys.log("ReminderScheduler", "habit=" + habit.id + " has no reminder. Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (habit.isArchived()) {
|
||||||
|
sys.log("ReminderScheduler", "habit=" + habit.id + " is archived. Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long timestamp = getStartOfDay(removeTimezone(reminderTime));
|
long timestamp = getStartOfDay(removeTimezone(reminderTime));
|
||||||
|
sys.log("ReminderScheduler",
|
||||||
|
String.format(
|
||||||
|
Locale.US,
|
||||||
|
"reminderTime=%d removeTimezone=%d timestamp=%d",
|
||||||
|
reminderTime,
|
||||||
|
removeTimezone(reminderTime),
|
||||||
|
timestamp));
|
||||||
|
|
||||||
sys.scheduleShowReminder(reminderTime, habit, timestamp);
|
sys.scheduleShowReminder(reminderTime, habit, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void scheduleAll()
|
public synchronized void scheduleAll()
|
||||||
{
|
{
|
||||||
|
sys.log("ReminderScheduler", "Scheduling all alarms");
|
||||||
HabitList reminderHabits =
|
HabitList reminderHabits =
|
||||||
habitList.getFiltered(HabitMatcher.WITH_ALARM);
|
habitList.getFiltered(HabitMatcher.WITH_ALARM);
|
||||||
for (Habit habit : reminderHabits)
|
for (Habit habit : reminderHabits)
|
||||||
@@ -101,5 +125,7 @@ public class ReminderScheduler implements CommandRunner.Listener
|
|||||||
public interface SystemScheduler
|
public interface SystemScheduler
|
||||||
{
|
{
|
||||||
void scheduleShowReminder(long reminderTime, Habit habit, long timestamp);
|
void scheduleShowReminder(long reminderTime, Habit habit, long timestamp);
|
||||||
|
|
||||||
|
void log(String componentName, String msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,8 @@ public class NotificationTray
|
|||||||
int notificationId,
|
int notificationId,
|
||||||
Timestamp timestamp,
|
Timestamp timestamp,
|
||||||
long reminderTime);
|
long reminderTime);
|
||||||
|
|
||||||
|
void log(String msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotificationData
|
class NotificationData
|
||||||
@@ -188,9 +190,31 @@ public class NotificationTray
|
|||||||
@Override
|
@Override
|
||||||
public void onPostExecute()
|
public void onPostExecute()
|
||||||
{
|
{
|
||||||
if (todayValue != Checkmark.UNCHECKED) return;
|
systemTray.log("Showing notification for habit=" + habit.id);
|
||||||
if (!shouldShowReminderToday()) return;
|
|
||||||
if (!habit.hasReminder()) return;
|
if (todayValue != Checkmark.UNCHECKED) {
|
||||||
|
systemTray.log(String.format(
|
||||||
|
Locale.US,
|
||||||
|
"Habit %d already checked. Skipping.",
|
||||||
|
habit.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldShowReminderToday()) {
|
||||||
|
systemTray.log(String.format(
|
||||||
|
Locale.US,
|
||||||
|
"Habit %d not supposed to run today. Skipping.",
|
||||||
|
habit.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!habit.hasReminder()) {
|
||||||
|
systemTray.log(String.format(
|
||||||
|
Locale.US,
|
||||||
|
"Habit %d does not have a reminder. Skipping.",
|
||||||
|
habit.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
systemTray.showNotification(habit, getNotificationId(habit), timestamp,
|
systemTray.showNotification(habit, getNotificationId(habit), timestamp,
|
||||||
reminderTime);
|
reminderTime);
|
||||||
|
|||||||
@@ -37,21 +37,11 @@ public abstract class DateUtils
|
|||||||
|
|
||||||
private static Locale fixedLocale = null;
|
private static Locale fixedLocale = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of the day when the new day starts.
|
|
||||||
*/
|
|
||||||
public static final int NEW_DAY_OFFSET = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of milliseconds in one day.
|
* Number of milliseconds in one day.
|
||||||
*/
|
*/
|
||||||
public static final long DAY_LENGTH = 24 * 60 * 60 * 1000;
|
public static final long DAY_LENGTH = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of milliseconds in one hour.
|
|
||||||
*/
|
|
||||||
public static final long HOUR_LENGTH = 60 * 60 * 1000;
|
|
||||||
|
|
||||||
public static long applyTimezone(long localTimestamp)
|
public static long applyTimezone(long localTimestamp)
|
||||||
{
|
{
|
||||||
TimeZone tz = getTimezone();
|
TimeZone tz = getTimezone();
|
||||||
@@ -182,13 +172,12 @@ public abstract class DateUtils
|
|||||||
|
|
||||||
public static long getStartOfToday()
|
public static long getStartOfToday()
|
||||||
{
|
{
|
||||||
return getStartOfDay(getLocalTime() - NEW_DAY_OFFSET * HOUR_LENGTH);
|
return getStartOfDay(getLocalTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long millisecondsUntilTomorrow()
|
public static long millisecondsUntilTomorrow()
|
||||||
{
|
{
|
||||||
return getStartOfToday() + DAY_LENGTH -
|
return getStartOfToday() + DAY_LENGTH - getLocalTime();
|
||||||
(getLocalTime() - NEW_DAY_OFFSET * HOUR_LENGTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GregorianCalendar getStartOfTodayCalendar()
|
public static GregorianCalendar getStartOfTodayCalendar()
|
||||||
@@ -271,7 +260,7 @@ public abstract class DateUtils
|
|||||||
calendar.set(Calendar.HOUR_OF_DAY, hour);
|
calendar.set(Calendar.HOUR_OF_DAY, hour);
|
||||||
calendar.set(Calendar.MINUTE, minute);
|
calendar.set(Calendar.MINUTE, minute);
|
||||||
calendar.set(Calendar.SECOND, 0);
|
calendar.set(Calendar.SECOND, 0);
|
||||||
Long time = calendar.getTimeInMillis();
|
long time = calendar.getTimeInMillis();
|
||||||
|
|
||||||
if (DateUtils.getLocalTime() > time)
|
if (DateUtils.getLocalTime() > time)
|
||||||
time += DateUtils.DAY_LENGTH;
|
time += DateUtils.DAY_LENGTH;
|
||||||
|
|||||||
Reference in New Issue
Block a user