From 6f80a9c03051213038780da4366aa92a800b9703 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Sun, 2 Jul 2017 14:00:23 -0400 Subject: [PATCH] Convert intents and notifications to Kotlin --- .../isoron/uhabits/intents/IntentFactory.java | 119 ------------------ .../isoron/uhabits/intents/IntentFactory.kt | 78 ++++++++++++ .../isoron/uhabits/intents/IntentParser.java | 84 ------------- .../isoron/uhabits/intents/IntentParser.kt | 57 +++++++++ .../uhabits/intents/IntentScheduler.java | 75 ----------- .../isoron/uhabits/intents/IntentScheduler.kt | 60 +++++++++ .../uhabits/intents/PendingIntentFactory.java | 118 ----------------- .../uhabits/intents/PendingIntentFactory.kt | 97 ++++++++++++++ .../AndroidNotificationTray.java | 115 ----------------- .../notifications/AndroidNotificationTray.kt | 94 ++++++++++++++ .../uhabits/receivers/WidgetReceiver.java | 9 +- 11 files changed, 392 insertions(+), 514 deletions(-) delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.java b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.java deleted file mode 100644 index 366483156..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker 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. - * - * Loop Habit Tracker 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 . - */ - -package org.isoron.uhabits.intents; - -import android.content.*; -import android.net.*; -import android.support.annotation.*; - -import org.isoron.uhabits.*; -import org.isoron.uhabits.activities.about.*; -import org.isoron.uhabits.activities.habits.show.*; -import org.isoron.uhabits.activities.intro.*; -import org.isoron.uhabits.activities.settings.*; -import org.isoron.uhabits.core.models.*; - -import javax.inject.*; - -public class IntentFactory -{ - @Inject - public IntentFactory() - { - } - - public Intent helpTranslate(Context context) - { - String url = context.getString(R.string.translateURL); - return buildViewIntent(url); - } - - public Intent openDocument() - { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType("*/*"); - return intent; - } - - public Intent rateApp(Context context) - { - String url = context.getString(R.string.playStoreURL); - return buildViewIntent(url); - } - - public Intent sendFeedback(Context context) - { - String url = context.getString(R.string.feedbackURL); - return buildSendToIntent(url); - } - - public Intent startAboutActivity(Context context) - { - return new Intent(context, AboutActivity.class); - } - - public Intent startIntroActivity(Context context) - { - return new Intent(context, IntroActivity.class); - } - - public Intent startSettingsActivity(Context context) - { - return new Intent(context, SettingsActivity.class); - } - - public Intent startShowHabitActivity(Context context, Habit habit) - { - Intent intent = new Intent(context, ShowHabitActivity.class); - intent.setData(Uri.parse(habit.getUriString())); - return intent; - } - - public Intent viewFAQ(Context context) - { - String url = context.getString(R.string.helpURL); - return buildViewIntent(url); - } - - public Intent viewSourceCode(Context context) - { - String url = context.getString(R.string.sourceCodeURL); - return buildViewIntent(url); - } - - @NonNull - private Intent buildSendToIntent(String url) - { - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_SENDTO); - intent.setData(Uri.parse(url)); - return intent; - } - - @NonNull - private Intent buildViewIntent(String url) - { - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - return intent; - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.kt new file mode 100644 index 000000000..fd04ee1a4 --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentFactory.kt @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 . + */ + +package org.isoron.uhabits.intents + +import android.content.* +import android.net.* +import org.isoron.uhabits.* +import org.isoron.uhabits.activities.about.* +import org.isoron.uhabits.activities.habits.show.* +import org.isoron.uhabits.activities.intro.* +import org.isoron.uhabits.activities.settings.* +import org.isoron.uhabits.core.models.* +import javax.inject.* + +class IntentFactory +@Inject constructor() { + + fun helpTranslate(context: Context) = + buildViewIntent(context.getString(R.string.translateURL)) + + fun openDocument() = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "*/*" + } + + fun rateApp(context: Context) = + buildViewIntent(context.getString(R.string.playStoreURL)) + + fun sendFeedback(context: Context) = + buildSendToIntent(context.getString(R.string.feedbackURL)) + + fun startAboutActivity(context: Context) = + Intent(context, AboutActivity::class.java) + + fun startIntroActivity(context: Context) = + Intent(context, IntroActivity::class.java) + + fun startSettingsActivity(context: Context) = + Intent(context, SettingsActivity::class.java) + + fun startShowHabitActivity(context: Context, habit: Habit) = + Intent(context, ShowHabitActivity::class.java).apply { + data = Uri.parse(habit.uriString) + } + + fun viewFAQ(context: Context) = + buildViewIntent(context.getString(R.string.helpURL)) + + fun viewSourceCode(context: Context) = + buildViewIntent(context.getString(R.string.sourceCodeURL)) + + private fun buildSendToIntent(url: String) = Intent().apply { + action = Intent.ACTION_SENDTO + data = Uri.parse(url) + } + + private fun buildViewIntent(url: String) = Intent().apply { + action = Intent.ACTION_VIEW + data = Uri.parse(url) + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.java b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.java deleted file mode 100644 index 2ae83cce0..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker 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. - * - * Loop Habit Tracker 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 . - */ - -package org.isoron.uhabits.intents; - -import android.content.*; -import android.net.*; -import android.support.annotation.*; - -import org.isoron.uhabits.core.*; -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.utils.*; - -import javax.inject.*; - -import static android.content.ContentUris.*; - -@AppScope -public class IntentParser -{ - private HabitList habits; - - @Inject - public IntentParser(@NonNull HabitList habits) - { - this.habits = habits; - } - - public CheckmarkIntentData parseCheckmarkIntent(@NonNull Intent intent) - { - Uri uri = intent.getData(); - if (uri == null) throw new IllegalArgumentException("uri is null"); - - CheckmarkIntentData data = new CheckmarkIntentData(); - data.habit = parseHabit(uri); - data.timestamp = parseTimestamp(intent); - return data; - } - - @NonNull - protected Habit parseHabit(@NonNull Uri uri) - { - Habit habit = habits.getById(parseId(uri)); - if (habit == null) - throw new IllegalArgumentException("habit not found"); - return habit; - } - - @NonNull - protected Long parseTimestamp(@NonNull Intent intent) - { - long today = DateUtils.getStartOfToday(); - Long timestamp = intent.getLongExtra("timestamp", today); - timestamp = DateUtils.getStartOfDay(timestamp); - - if (timestamp < 0 || timestamp > today) - throw new IllegalArgumentException("timestamp is not valid"); - - return timestamp; - } - - public class CheckmarkIntentData - { - public Habit habit; - - public Long timestamp; - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt new file mode 100644 index 000000000..3ce896490 --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentParser.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 . + */ + +package org.isoron.uhabits.intents + +import android.content.* +import android.content.ContentUris.* +import android.net.* +import org.isoron.uhabits.core.* +import org.isoron.uhabits.core.models.* +import org.isoron.uhabits.core.utils.* +import javax.inject.* + +@AppScope +class IntentParser +@Inject constructor(private val habits: HabitList) { + + fun parseCheckmarkIntent(intent: Intent): CheckmarkIntentData { + val uri = intent.data ?: throw IllegalArgumentException("uri is null") + return CheckmarkIntentData(parseHabit(uri), parseTimestamp(intent)) + } + + private fun parseHabit(uri: Uri): Habit { + val habit = habits.getById(parseId(uri)) ?: + throw IllegalArgumentException("habit not found") + return habit + } + + private fun parseTimestamp(intent: Intent): Long { + val today = DateUtils.getStartOfToday() + var timestamp = intent.getLongExtra("timestamp", today) + timestamp = DateUtils.getStartOfDay(timestamp) + + if (timestamp < 0 || timestamp > today) + throw IllegalArgumentException("timestamp is not valid") + + return timestamp + } + + class CheckmarkIntentData(var habit: Habit, var timestamp: Long) +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java deleted file mode 100644 index df604ee0c..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker 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. - * - * Loop Habit Tracker 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 . - */ - -package org.isoron.uhabits.intents; - -import android.app.*; -import android.content.*; -import android.os.*; -import android.support.annotation.*; - -import org.isoron.androidbase.*; -import org.isoron.uhabits.*; -import org.isoron.uhabits.core.*; -import org.isoron.uhabits.core.models.*; - -import javax.inject.*; - -import static android.app.AlarmManager.*; -import static android.content.Context.*; -import static android.os.Build.VERSION_CODES.*; - -@AppScope -public class IntentScheduler - implements org.isoron.uhabits.core.reminders.ReminderScheduler.SystemScheduler -{ - private final AlarmManager manager; - - @NonNull - private final PendingIntentFactory pendingIntents; - - private HabitLogger logger; - - @Inject - public IntentScheduler(@AppContext Context context, - @NonNull PendingIntentFactory pendingIntents, - @NonNull HabitLogger logger) - { - manager = (AlarmManager) context.getSystemService(ALARM_SERVICE); - this.pendingIntents = pendingIntents; - this.logger = logger; - } - - public void schedule(@NonNull Long timestamp, PendingIntent intent) - { - if (Build.VERSION.SDK_INT >= M) - manager.setExactAndAllowWhileIdle(RTC_WAKEUP, timestamp, intent); - else manager.setExact(RTC_WAKEUP, timestamp, intent); - } - - @Override - public void scheduleShowReminder(long reminderTime, - @NonNull Habit habit, - long timestamp) - { - schedule(reminderTime, - pendingIntents.showReminder(habit, reminderTime, timestamp)); - logger.logReminderScheduled(habit, reminderTime); - } -} 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 new file mode 100644 index 000000000..689beb2ec --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/IntentScheduler.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 . + */ + +package org.isoron.uhabits.intents + +import android.app.* +import android.app.AlarmManager.* +import android.content.* +import android.content.Context.* +import android.os.Build.VERSION.* +import android.os.Build.VERSION_CODES.* +import org.isoron.androidbase.* +import org.isoron.uhabits.* +import org.isoron.uhabits.core.* +import org.isoron.uhabits.core.models.* +import org.isoron.uhabits.core.reminders.* +import javax.inject.* + +@AppScope +class IntentScheduler +@Inject constructor( + @AppContext context: Context, + private val pendingIntents: PendingIntentFactory, + private val logger: HabitLogger +) : ReminderScheduler.SystemScheduler { + + private val manager = + context.getSystemService(ALARM_SERVICE) as AlarmManager + + fun schedule(timestamp: Long, intent: PendingIntent) { + if (SDK_INT >= M) + manager.setExactAndAllowWhileIdle(RTC_WAKEUP, timestamp, intent) + else + manager.setExact(RTC_WAKEUP, timestamp, intent) + } + + override fun scheduleShowReminder(reminderTime: Long, + habit: Habit, + timestamp: Long) { + val intent = pendingIntents.showReminder(habit, reminderTime, timestamp) + schedule(reminderTime, intent) + logger.logReminderScheduled(habit, reminderTime) + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java deleted file mode 100644 index 26f87fe76..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker 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. - * - * Loop Habit Tracker 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 . - */ - -package org.isoron.uhabits.intents; - -import android.app.*; -import android.content.*; -import android.net.*; -import android.support.annotation.*; - -import org.isoron.androidbase.*; -import org.isoron.uhabits.core.*; -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.receivers.*; - -import javax.inject.*; - -import static android.app.PendingIntent.*; - -@AppScope -public class PendingIntentFactory -{ - private final Context context; - - private IntentFactory intentFactory; - - @Inject - public PendingIntentFactory(@AppContext Context context, - @NonNull IntentFactory intentFactory) - { - this.context = context; - this.intentFactory = intentFactory; - } - - public PendingIntent addCheckmark(@NonNull Habit habit, - @Nullable Long timestamp) - { - Intent checkIntent = new Intent(context, WidgetReceiver.class); - checkIntent.setData(Uri.parse(habit.getUriString())); - checkIntent.setAction(WidgetReceiver.ACTION_ADD_REPETITION); - if (timestamp != null) checkIntent.putExtra("timestamp", timestamp); - return PendingIntent.getBroadcast(context, 1, checkIntent, - FLAG_UPDATE_CURRENT); - } - - public PendingIntent dismissNotification(@NonNull Habit habit) - { - Intent deleteIntent = new Intent(context, ReminderReceiver.class); - deleteIntent.setAction(WidgetReceiver.ACTION_DISMISS_REMINDER); - deleteIntent.setData(Uri.parse(habit.getUriString())); - return PendingIntent.getBroadcast(context, 0, deleteIntent, - FLAG_UPDATE_CURRENT); - } - - public PendingIntent showHabit(Habit habit) - { - Intent intent = intentFactory.startShowHabitActivity(context, habit); - - return android.support.v4.app.TaskStackBuilder - .create(context) - .addNextIntentWithParentStack(intent) - .getPendingIntent(0, FLAG_UPDATE_CURRENT); - } - - public PendingIntent showReminder(@NonNull Habit habit, - @Nullable Long reminderTime, - long timestamp) - { - Uri uri = Uri.parse(habit.getUriString()); - - Intent intent = new Intent(context, ReminderReceiver.class); - intent.setAction(ReminderReceiver.ACTION_SHOW_REMINDER); - intent.setData(uri); - intent.putExtra("timestamp", timestamp); - intent.putExtra("reminderTime", reminderTime); - int reqCode = ((int) (habit.getId() % Integer.MAX_VALUE)) + 1; - return PendingIntent.getBroadcast(context, reqCode, intent, - FLAG_UPDATE_CURRENT); - } - - public PendingIntent snoozeNotification(@NonNull Habit habit) - { - Uri data = Uri.parse(habit.getUriString()); - Intent snoozeIntent = new Intent(context, ReminderReceiver.class); - snoozeIntent.setData(data); - snoozeIntent.setAction(ReminderReceiver.ACTION_SNOOZE_REMINDER); - return PendingIntent.getBroadcast(context, 0, snoozeIntent, - FLAG_UPDATE_CURRENT); - } - - public PendingIntent toggleCheckmark(@NonNull Habit habit, - @Nullable Long timestamp) - { - Uri data = Uri.parse(habit.getUriString()); - Intent checkIntent = new Intent(context, WidgetReceiver.class); - checkIntent.setData(data); - checkIntent.setAction(WidgetReceiver.ACTION_TOGGLE_REPETITION); - if (timestamp != null) checkIntent.putExtra("timestamp", timestamp); - return PendingIntent.getBroadcast(context, 2, checkIntent, - FLAG_UPDATE_CURRENT); - } -} 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 new file mode 100644 index 000000000..0db84034d --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 . + */ + +package org.isoron.uhabits.intents + +import android.app.* +import android.app.PendingIntent.* +import android.content.* +import android.net.* +import org.isoron.androidbase.* +import org.isoron.uhabits.core.* +import org.isoron.uhabits.core.models.* +import org.isoron.uhabits.receivers.* +import javax.inject.* + +@AppScope +class PendingIntentFactory +@Inject constructor( + @AppContext private val context: Context, + private val intentFactory: IntentFactory) { + + fun addCheckmark(habit: Habit, timestamp: Long?): PendingIntent = + PendingIntent.getBroadcast( + context, 1, + Intent(context, WidgetReceiver::class.java).apply { + data = Uri.parse(habit.uriString) + action = WidgetReceiver.ACTION_ADD_REPETITION + if (timestamp != null) putExtra("timestamp", timestamp) + }, + FLAG_UPDATE_CURRENT) + + fun dismissNotification(habit: Habit): PendingIntent = + PendingIntent.getBroadcast( + context, 0, + Intent(context, ReminderReceiver::class.java).apply { + action = WidgetReceiver.ACTION_DISMISS_REMINDER + data = Uri.parse(habit.uriString) + }, + FLAG_UPDATE_CURRENT) + + fun showHabit(habit: Habit): PendingIntent = + android.support.v4.app.TaskStackBuilder + .create(context) + .addNextIntentWithParentStack( + intentFactory.startShowHabitActivity( + context, habit)) + .getPendingIntent(0, FLAG_UPDATE_CURRENT) + + fun showReminder(habit: Habit, + reminderTime: Long?, + timestamp: Long): PendingIntent = + PendingIntent.getBroadcast( + context, + (habit.getId()!! % Integer.MAX_VALUE).toInt() + 1, + Intent(context, ReminderReceiver::class.java).apply { + action = ReminderReceiver.ACTION_SHOW_REMINDER + data = Uri.parse(habit.uriString) + putExtra("timestamp", timestamp) + putExtra("reminderTime", reminderTime) + }, + FLAG_UPDATE_CURRENT) + + fun snoozeNotification(habit: Habit): PendingIntent = + PendingIntent.getBroadcast( + context, 0, + Intent(context, ReminderReceiver::class.java).apply { + data = Uri.parse(habit.uriString) + action = ReminderReceiver.ACTION_SNOOZE_REMINDER + }, + FLAG_UPDATE_CURRENT) + + fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent = + PendingIntent.getBroadcast( + context, 2, + Intent(context, WidgetReceiver::class.java).apply { + data = Uri.parse(habit.uriString) + action = WidgetReceiver.ACTION_TOGGLE_REPETITION + if (timestamp != null) putExtra("timestamp", timestamp) + }, + FLAG_UPDATE_CURRENT) +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.java b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.java deleted file mode 100644 index 72ca25293..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker 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. - * - * Loop Habit Tracker 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 . - */ - -package org.isoron.uhabits.notifications; - -import android.app.*; -import android.content.*; -import android.graphics.*; -import android.support.annotation.*; -import android.support.v4.app.*; -import android.support.v4.app.NotificationCompat.*; - -import org.isoron.androidbase.*; -import org.isoron.uhabits.R; -import org.isoron.uhabits.core.*; -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.preferences.*; -import org.isoron.uhabits.core.ui.*; -import org.isoron.uhabits.intents.*; - -import javax.inject.*; - -import static android.graphics.BitmapFactory.decodeResource; -import static org.isoron.uhabits.notifications.RingtoneManager.getRingtoneUri; - -@AppScope -public class AndroidNotificationTray implements NotificationTray.SystemTray -{ - @NonNull - private final Context context; - - @NonNull - private final PendingIntentFactory pendingIntents; - - @NonNull - private final Preferences preferences; - - @Inject - public AndroidNotificationTray(@AppContext @NonNull Context context, - @NonNull PendingIntentFactory pendingIntents, - @NonNull Preferences preferences) - { - this.context = context; - this.pendingIntents = pendingIntents; - this.preferences = preferences; - } - - @Override - public void removeNotification(int id) - { - NotificationManagerCompat.from(context).cancel(id); - } - - public void showNotification(@NonNull Habit habit, - int notificationId, - long timestamp, - long reminderTime) - { - Action checkAction = new Action(R.drawable.ic_action_check, - context.getString(R.string.check), - pendingIntents.addCheckmark(habit, timestamp)); - - Action snoozeAction = new Action(R.drawable.ic_action_snooze, - context.getString(R.string.snooze), - pendingIntents.snoozeNotification(habit)); - - Bitmap wearableBg = - decodeResource(context.getResources(), R.drawable.stripe); - - // Even though the set of actions is the same on the phone and - // on the watch, Pebble requires us to add them to the - // WearableExtender. - WearableExtender wearableExtender = new WearableExtender() - .setBackground(wearableBg) - .addAction(checkAction) - .addAction(snoozeAction); - - Notification notification = new NotificationCompat.Builder(context) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle(habit.getName()) - .setContentText(habit.getDescription()) - .setContentIntent(pendingIntents.showHabit(habit)) - .setDeleteIntent(pendingIntents.dismissNotification(habit)) - .addAction(checkAction) - .addAction(snoozeAction) - .setSound(getRingtoneUri(context)) - .extend(wearableExtender) - .setWhen(reminderTime) - .setShowWhen(true) - .setOngoing(preferences.shouldMakeNotificationsSticky()) - .build(); - - NotificationManager notificationManager = - (NotificationManager) context.getSystemService( - Activity.NOTIFICATION_SERVICE); - - notificationManager.notify(notificationId, notification); - } -} 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 new file mode 100644 index 000000000..4581ec0af --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 . + */ + +package org.isoron.uhabits.notifications + +import android.app.* +import android.content.* +import android.graphics.BitmapFactory.* +import android.support.v4.app.* +import android.support.v4.app.NotificationCompat.* +import org.isoron.androidbase.* +import org.isoron.uhabits.R +import org.isoron.uhabits.core.* +import org.isoron.uhabits.core.models.* +import org.isoron.uhabits.core.preferences.* +import org.isoron.uhabits.core.ui.* +import org.isoron.uhabits.intents.* +import org.isoron.uhabits.notifications.RingtoneManager.* +import javax.inject.* + +@AppScope +class AndroidNotificationTray +@Inject constructor( + @param:AppContext private val context: Context, + private val pendingIntents: PendingIntentFactory, + private val preferences: Preferences +) : NotificationTray.SystemTray { + + override fun removeNotification(id: Int) { + NotificationManagerCompat.from(context).cancel(id) + } + + override fun showNotification(habit: Habit, + notificationId: Int, + timestamp: Long, + reminderTime: Long) { + + val checkAction = Action( + R.drawable.ic_action_check, + context.getString(R.string.check), + pendingIntents.addCheckmark(habit, timestamp)) + + val snoozeAction = Action( + R.drawable.ic_action_snooze, + context.getString(R.string.snooze), + pendingIntents.snoozeNotification(habit)) + + val wearableBg = decodeResource(context.resources, R.drawable.stripe) + + // Even though the set of actions is the same on the phone and + // on the watch, Pebble requires us to add them to the + // WearableExtender. + val wearableExtender = WearableExtender() + .setBackground(wearableBg) + .addAction(checkAction) + .addAction(snoozeAction) + + val notification = NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(habit.name) + .setContentText(habit.description) + .setContentIntent(pendingIntents.showHabit(habit)) + .setDeleteIntent(pendingIntents.dismissNotification(habit)) + .addAction(checkAction) + .addAction(snoozeAction) + .setSound(getRingtoneUri(context)) + .extend(wearableExtender) + .setWhen(reminderTime) + .setShowWhen(true) + .setOngoing(preferences.shouldMakeNotificationsSticky()) + .build() + + val notificationManager = context.getSystemService( + Activity.NOTIFICATION_SERVICE) as NotificationManager + + notificationManager.notify(notificationId, notification) + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java index 97bd1f2b1..7074224e8 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java @@ -75,15 +75,18 @@ public class WidgetReceiver extends BroadcastReceiver switch (intent.getAction()) { case ACTION_ADD_REPETITION: - controller.onAddRepetition(data.habit, data.timestamp); + controller.onAddRepetition(data.getHabit(), + data.getTimestamp()); break; case ACTION_TOGGLE_REPETITION: - controller.onToggleRepetition(data.habit, data.timestamp); + controller.onToggleRepetition(data.getHabit(), + data.getTimestamp()); break; case ACTION_REMOVE_REPETITION: - controller.onRemoveRepetition(data.habit, data.timestamp); + controller.onRemoveRepetition(data.getHabit(), + data.getTimestamp()); break; } }