Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 93 additions & 29 deletions app/src/main/kotlin/org/fossify/clock/activities/ReminderActivity.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
package org.fossify.clock.activities

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.media.AudioManager
import android.media.MediaPlayer
import android.net.Uri
import android.os.*
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.VibrationEffect
import android.os.Vibrator
import android.provider.AlarmClock
import android.view.MotionEvent
import android.view.WindowManager
import android.view.animation.AnimationUtils
import androidx.core.net.toUri
import org.fossify.clock.R
import org.fossify.clock.databinding.ActivityReminderBinding
import org.fossify.clock.extensions.*
import org.fossify.clock.extensions.cancelAlarmClock
import org.fossify.clock.extensions.config
import org.fossify.clock.extensions.dbHelper
import org.fossify.clock.extensions.getFormattedTime
import org.fossify.clock.extensions.scheduleNextAlarm
import org.fossify.clock.extensions.setupAlarmClock
import org.fossify.clock.extensions.updateWidgets
import org.fossify.clock.helpers.ALARM_ID
import org.fossify.clock.helpers.ALARM_NOTIF_ID
import org.fossify.clock.helpers.getPassedSeconds
import org.fossify.clock.models.Alarm
import org.fossify.commons.extensions.*
import org.fossify.commons.extensions.applyColorFilter
import org.fossify.commons.extensions.beGone
import org.fossify.commons.extensions.getColoredDrawableWithColor
import org.fossify.commons.extensions.getProperBackgroundColor
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.getProperTextColor
import org.fossify.commons.extensions.notificationManager
import org.fossify.commons.extensions.onGlobalLayout
import org.fossify.commons.extensions.performHapticFeedback
import org.fossify.commons.extensions.showPickSecondsDialog
import org.fossify.commons.extensions.updateTextColors
import org.fossify.commons.extensions.viewBinding
import org.fossify.commons.helpers.MINUTE_SECONDS
import org.fossify.commons.helpers.SILENT
import org.fossify.commons.helpers.isOreoMr1Plus
import org.fossify.commons.helpers.isOreoPlus
import java.util.Calendar
import kotlin.math.max
import kotlin.math.min

class ReminderActivity : SimpleActivity() {
companion object {
Expand Down Expand Up @@ -73,11 +95,25 @@ class ReminderActivity : SimpleActivity() {
}

binding.reminderTitle.text = label
binding.reminderText.text = if (isAlarmReminder) getFormattedTime(getPassedSeconds(), false, false) else getString(R.string.time_expired)
binding.reminderText.text = if (isAlarmReminder) {
getFormattedTime(
passedSeconds = getPassedSeconds(),
showSeconds = false,
makeAmPmSmaller = false
)
} else {
getString(R.string.time_expired)
}

val maxDuration = if (isAlarmReminder) {
config.alarmMaxReminderSecs
} else {
config.timerMaxReminderSecs
}

val maxDuration = if (isAlarmReminder) config.alarmMaxReminderSecs else config.timerMaxReminderSecs
maxReminderDurationHandler.postDelayed({
finishActivity()
cancelNotification()
}, maxDuration * 1000L)

setupButtons()
Expand All @@ -95,7 +131,12 @@ class ReminderActivity : SimpleActivity() {
@SuppressLint("ClickableViewAccessibility")
private fun setupAlarmButtons() {
binding.reminderStop.beGone()
binding.reminderDraggableBackground.startAnimation(AnimationUtils.loadAnimation(this, R.anim.pulsing_animation))
binding.reminderDraggableBackground.startAnimation(
AnimationUtils.loadAnimation(
this,
R.anim.pulsing_animation
)
)
binding.reminderDraggableBackground.applyColorFilter(getProperPrimaryColor())

val textColor = getProperTextColor()
Expand Down Expand Up @@ -136,27 +177,27 @@ class ReminderActivity : SimpleActivity() {
}

MotionEvent.ACTION_MOVE -> {
binding.reminderDraggable.x = Math.min(maxDragX, Math.max(minDragX, event.rawX - dragDownX))
binding.reminderDraggable.x = min(
a = maxDragX,
b = max(minDragX, event.rawX - dragDownX)
)

if (binding.reminderDraggable.x >= maxDragX - 50f) {
if (!didVibrate) {
binding.reminderDraggable.performHapticFeedback()
didVibrate = true
finishActivity()
}

if (isOreoPlus()) {
notificationManager.cancelAll()
}
cancelNotification()
} else if (binding.reminderDraggable.x <= minDragX + 50f) {
if (!didVibrate) {
binding.reminderDraggable.performHapticFeedback()
didVibrate = true
snoozeAlarm()
}

if (isOreoPlus()) {
notificationManager.cancelAll()
}
cancelNotification()
}
}
}
Expand All @@ -165,8 +206,16 @@ class ReminderActivity : SimpleActivity() {
}

private fun setupTimerButtons() {
binding.reminderStop.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, getProperPrimaryColor())
arrayOf(binding.reminderSnooze, binding.reminderDraggableBackground, binding.reminderDraggable, binding.reminderDismiss).forEach {
binding.reminderStop.background = resources.getColoredDrawableWithColor(
drawableId = R.drawable.circle_background_filled,
color = getProperPrimaryColor()
)
arrayOf(
binding.reminderSnooze,
binding.reminderDraggableBackground,
binding.reminderDraggable,
binding.reminderDismiss
).forEach {
it.beGone()
}

Expand All @@ -176,14 +225,14 @@ class ReminderActivity : SimpleActivity() {
}

private fun setupEffects() {
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
initialAlarmVolume = audioManager?.getStreamVolume(AudioManager.STREAM_ALARM) ?: 7

val doVibrate = alarm?.vibrate ?: config.timerVibrate
if (doVibrate && isOreoPlus()) {
val pattern = LongArray(2) { 500 }
vibrationHandler.postDelayed({
vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator
vibrator?.vibrate(VibrationEffect.createWaveform(pattern, 0))
}, 500)
}
Expand All @@ -198,14 +247,18 @@ class ReminderActivity : SimpleActivity() {
try {
mediaPlayer = MediaPlayer().apply {
setAudioStreamType(AudioManager.STREAM_ALARM)
setDataSource(this@ReminderActivity, Uri.parse(soundUri))
setDataSource(this@ReminderActivity, soundUri.toUri())
isLooping = true
prepare()
start()
}

if (config.increaseVolumeGradually) {
scheduleVolumeIncrease(MIN_ALARM_VOLUME_FOR_INCREASING_ALARMS.toFloat(), initialAlarmVolume!!.toFloat(), 0)
scheduleVolumeIncrease(
lastVolume = MIN_ALARM_VOLUME_FOR_INCREASING_ALARMS.toFloat(),
maxVolume = initialAlarmVolume!!.toFloat(),
delay = 0
)
}
} catch (e: Exception) {
}
Expand Down Expand Up @@ -253,7 +306,7 @@ class ReminderActivity : SimpleActivity() {
vibrationHandler.removeCallbacksAndMessages(null)
if (!finished) {
finishActivity()
notificationManager.cancel(ALARM_NOTIF_ID)
cancelNotification()
} else {
destroyEffects()
}
Expand All @@ -278,10 +331,17 @@ class ReminderActivity : SimpleActivity() {
} else if (config.useSameSnooze) {
scheduleSnoozedAlarm(config.snoozeTime)
} else {
showPickSecondsDialog(config.snoozeTime * MINUTE_SECONDS, true, cancelCallback = { finishActivity() }) {
config.snoozeTime = it / MINUTE_SECONDS
scheduleSnoozedAlarm(config.snoozeTime)
}
showPickSecondsDialog(
curSeconds = config.snoozeTime * MINUTE_SECONDS,
isSnoozePicker = true,
cancelCallback = {
finishActivity()
},
callback = {
config.snoozeTime = it / MINUTE_SECONDS
scheduleSnoozedAlarm(config.snoozeTime)
}
)
}
}

Expand Down Expand Up @@ -323,14 +383,18 @@ class ReminderActivity : SimpleActivity() {
private fun showOverLockscreen() {
window.addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
)

if (isOreoMr1Plus()) {
setShowWhenLocked(true)
setTurnScreenOn(true)
}
}

private fun cancelNotification() {
notificationManager.cancel(ALARM_NOTIF_ID)
}
}
75 changes: 65 additions & 10 deletions app/src/main/kotlin/org/fossify/clock/extensions/Context.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package org.fossify.clock.extensions

import android.app.*
import android.app.AlarmManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioManager.STREAM_ALARM
import android.media.RingtoneManager
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.os.PowerManager
Expand All @@ -17,21 +20,73 @@ import android.text.style.RelativeSizeSpan
import android.widget.Toast
import androidx.core.app.AlarmManagerCompat
import androidx.core.app.NotificationCompat
import androidx.core.net.toUri
import org.fossify.clock.R
import org.fossify.clock.activities.ReminderActivity
import org.fossify.clock.activities.SnoozeReminderActivity
import org.fossify.clock.activities.SplashActivity
import org.fossify.clock.databases.AppDatabase
import org.fossify.clock.helpers.*
import org.fossify.clock.helpers.ALARM_ID
import org.fossify.clock.helpers.ALARM_NOTIFICATION_CHANNEL_ID
import org.fossify.clock.helpers.Config
import org.fossify.clock.helpers.DBHelper
import org.fossify.clock.helpers.EARLY_ALARM_DISMISSAL_INTENT_ID
import org.fossify.clock.helpers.EDITED_TIME_ZONE_SEPARATOR
import org.fossify.clock.helpers.FORMAT_12H
import org.fossify.clock.helpers.FORMAT_24H
import org.fossify.clock.helpers.MyAnalogueTimeWidgetProvider
import org.fossify.clock.helpers.MyDigitalTimeWidgetProvider
import org.fossify.clock.helpers.NOTIFICATION_ID
import org.fossify.clock.helpers.OPEN_ALARMS_TAB_INTENT_ID
import org.fossify.clock.helpers.OPEN_STOPWATCH_TAB_INTENT_ID
import org.fossify.clock.helpers.OPEN_TAB
import org.fossify.clock.helpers.REMINDER_ACTIVITY_INTENT_ID
import org.fossify.clock.helpers.TAB_ALARM
import org.fossify.clock.helpers.TAB_STOPWATCH
import org.fossify.clock.helpers.TAB_TIMER
import org.fossify.clock.helpers.TIMER_ID
import org.fossify.clock.helpers.TODAY_BIT
import org.fossify.clock.helpers.TOMORROW_BIT
import org.fossify.clock.helpers.TimerHelper
import org.fossify.clock.helpers.formatTime
import org.fossify.clock.helpers.getAllTimeZones
import org.fossify.clock.helpers.getCurrentDayMinutes
import org.fossify.clock.helpers.getDefaultTimeZoneTitle
import org.fossify.clock.helpers.getPassedSeconds
import org.fossify.clock.helpers.getTimeOfNextAlarm
import org.fossify.clock.interfaces.TimerDao
import org.fossify.clock.models.Alarm
import org.fossify.clock.models.MyTimeZone
import org.fossify.clock.models.Timer
import org.fossify.clock.models.TimerState
import org.fossify.clock.receivers.*
import org.fossify.clock.receivers.AlarmReceiver
import org.fossify.clock.receivers.DismissAlarmReceiver
import org.fossify.clock.receivers.EarlyAlarmDismissalReceiver
import org.fossify.clock.receivers.HideAlarmReceiver
import org.fossify.clock.receivers.HideTimerReceiver
import org.fossify.clock.services.SnoozeService
import org.fossify.commons.extensions.*
import org.fossify.commons.helpers.*
import org.fossify.commons.extensions.formatMinutesToTimeString
import org.fossify.commons.extensions.formatSecondsToTimeString
import org.fossify.commons.extensions.getDefaultAlarmSound
import org.fossify.commons.extensions.getLaunchIntent
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.getSelectedDaysString
import org.fossify.commons.extensions.grantReadUriPermission
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.toInt
import org.fossify.commons.extensions.toast
import org.fossify.commons.helpers.EVERY_DAY_BIT
import org.fossify.commons.helpers.FRIDAY_BIT
import org.fossify.commons.helpers.MINUTE_SECONDS
import org.fossify.commons.helpers.MONDAY_BIT
import org.fossify.commons.helpers.SATURDAY_BIT
import org.fossify.commons.helpers.SILENT
import org.fossify.commons.helpers.SUNDAY_BIT
import org.fossify.commons.helpers.THURSDAY_BIT
import org.fossify.commons.helpers.TUESDAY_BIT
import org.fossify.commons.helpers.WEDNESDAY_BIT
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isOreoPlus
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
Expand Down Expand Up @@ -350,7 +405,7 @@ fun Context.getTimerNotification(timer: Timer, pendingIntent: PendingIntent, add
setBypassDnd(true)
enableLights(true)
lightColor = getProperPrimaryColor()
setSound(Uri.parse(soundUri), audioAttributes)
setSound(soundUri.toUri(), audioAttributes)

if (!timer.vibrate) {
vibrationPattern = longArrayOf(0L)
Expand All @@ -375,7 +430,7 @@ fun Context.getTimerNotification(timer: Timer, pendingIntent: PendingIntent, add
.setDefaults(Notification.DEFAULT_LIGHTS)
.setCategory(Notification.CATEGORY_EVENT)
.setAutoCancel(true)
.setSound(Uri.parse(soundUri), STREAM_ALARM)
.setSound(soundUri.toUri(), STREAM_ALARM)
.setChannelId(channelId)
.addAction(
org.fossify.commons.R.drawable.ic_cross_vector,
Expand Down Expand Up @@ -450,7 +505,7 @@ fun Context.getAlarmNotification(pendingIntent: PendingIntent, alarm: Alarm): No
enableLights(true)
lightColor = getProperPrimaryColor()
enableVibration(alarm.vibrate)
setSound(Uri.parse(soundUri), audioAttributes)
setSound(soundUri.toUri(), audioAttributes)
notificationManager.createNotificationChannel(this)
}
}
Expand All @@ -475,7 +530,7 @@ fun Context.getAlarmNotification(pendingIntent: PendingIntent, alarm: Alarm): No
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)

if (soundUri != SILENT) {
builder.setSound(Uri.parse(soundUri), STREAM_ALARM)
builder.setSound(soundUri.toUri(), STREAM_ALARM)
}

if (alarm.vibrate) {
Expand Down
Loading
Loading