This commit is contained in:
Pavol Franek 2020-03-08 10:47:42 +01:00
parent c3ab1f9330
commit ed18715b39
4 changed files with 98 additions and 80 deletions

View File

@ -10,7 +10,6 @@ import android.media.AudioManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.CountDownTimer import android.os.CountDownTimer
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -26,10 +25,7 @@ import com.simplemobiletools.clock.extensions.*
import com.simplemobiletools.clock.helpers.Config import com.simplemobiletools.clock.helpers.Config
import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID
import com.simplemobiletools.clock.helpers.TIMER_NOTIF_ID import com.simplemobiletools.clock.helpers.TIMER_NOTIF_ID
import com.simplemobiletools.clock.workers.TIMER_WORKER_KEY import com.simplemobiletools.clock.workers.*
import com.simplemobiletools.clock.workers.cancelTimerWorker
import com.simplemobiletools.clock.workers.enqueueTimerWorker
import com.simplemobiletools.clock.workers.timerRequestId
import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM
@ -38,24 +34,53 @@ import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.fragment_timer.view.* import kotlinx.android.synthetic.main.fragment_timer.view.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class TimerFragment : Fragment() { class TimerFragment : Fragment() {
lateinit var view: ViewGroup lateinit var view: ViewGroup
private var timer: CountDownTimer? = null private var timer: CountDownTimer? = null
private var isRunning = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val config = requiredActivity.config
view = (inflater.inflate(R.layout.fragment_timer, container, false) as ViewGroup).apply { view = (inflater.inflate(R.layout.fragment_timer, container, false) as ViewGroup).apply {
val config = requiredActivity.config
val textColor = config.textColor
requiredActivity.updateTextColors(timer_fragment)
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
timer_reset.applyColorFilter(textColor)
timer_initial_time.text = config.timerSeconds.getFormattedDuration()
timer_initial_time.colorLeftDrawable(textColor)
timer_vibrate.isChecked = config.timerVibrate
timer_vibrate.colorLeftDrawable(textColor)
timer_sound.text = config.timerSoundTitle
timer_sound.colorLeftDrawable(textColor)
timer_time.setOnClickListener { timer_time.setOnClickListener {
startTimer(config) if (isRunning) {
pauseTimer(config)
} else {
startTimer(config)
}
} }
timer_play_pause.setOnClickListener { timer_play_pause.setOnClickListener {
startTimer(config) if (isRunning) {
pauseTimer(config)
} else {
startTimer(config)
}
} }
timer_reset.setOnClickListener { timer_reset.setOnClickListener {
cancelTimerWorker() cancelTimerWorker()
requiredActivity.hideTimerNotification()
config.timerTickStamp = 0L
config.timerStartStamp = 0L
requiredActivity.toast(R.string.timer_stopped) requiredActivity.toast(R.string.timer_stopped)
} }
@ -63,7 +88,6 @@ class TimerFragment : Fragment() {
MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { seconds -> MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { seconds ->
val timerSeconds = if (seconds <= 0) 10 else seconds val timerSeconds = if (seconds <= 0) 10 else seconds
config.timerSeconds = timerSeconds config.timerSeconds = timerSeconds
config.timerTimeStamp = System.currentTimeMillis() + timerSeconds
timer_initial_time.text = timerSeconds.getFormattedDuration() timer_initial_time.text = timerSeconds.getFormattedDuration()
} }
} }
@ -92,15 +116,20 @@ class TimerFragment : Fragment() {
} }
WorkManager.getInstance(requiredActivity).getWorkInfosByTagLiveData(TIMER_WORKER_KEY).observe(requiredActivity, Observer { workInfo -> WorkManager.getInstance(requiredActivity).getWorkInfosByTagLiveData(TIMER_WORKER_KEY).observe(requiredActivity, Observer { workInfo ->
workInfo.log("log")
val workerState = workInfo?.firstOrNull()?.state val workerState = workInfo?.firstOrNull()?.state
isRunning = (workerState == WorkInfo.State.ENQUEUED)
updateIcons(isRunning)
timer_reset.beVisibleIf(isRunning)
timer?.cancel()
when (workerState) { when (workerState) {
WorkInfo.State.ENQUEUED -> { WorkInfo.State.ENQUEUED -> {
timer?.cancel() val duration = config.timerSeconds.toLong() * 1000 //MS
timer = object : CountDownTimer(config.timerSeconds.toLong().times(1000), 1000) {
timer = object : CountDownTimer(duration, 1000) {
override fun onTick(millisUntilFinished: Long) { override fun onTick(millisUntilFinished: Long) {
timer_time.text = millisUntilFinished.div(1000).toInt().getFormattedDuration() timer_time.text = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished).toInt().getFormattedDuration()
} }
override fun onFinish() {} override fun onFinish() {}
@ -111,34 +140,46 @@ class TimerFragment : Fragment() {
timer_time.text = 0.getFormattedDuration() timer_time.text = 0.getFormattedDuration()
} }
} }
updateIcons(workerState == WorkInfo.State.ENQUEUED)
timer_reset.beVisibleIf(workerState == WorkInfo.State.ENQUEUED)
}) })
cancelTimerWorker()
} }
return view return view
} }
private fun startTimer(config: Config) { private fun startTimer(config: Config) {
val selectedDuration = config.timerSeconds val isTimerNoTick = config.timerTickStamp == 0L
val formattedTimestamp = config.timerTimeStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong())) if (isTimerNoTick) {
showNotification("(${selectedDuration.getFormattedDuration()}) $formattedTimestamp") config.timerStartStamp = System.currentTimeMillis()
val selectedDuration = config.timerSeconds
val formattedTimestamp = config.timerStartStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
showNotification("(${selectedDuration.getFormattedDuration()}) $formattedTimestamp")
} else {
val duration = config.timerSeconds.toLong() * 1000 //MS
val selectedDuration = (config.timerStartStamp + duration) - (config.timerTickStamp - config.timerStartStamp)
val formattedTimestamp = config.timerStartStamp.timestampFormat("HH:mm:ss")
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
showNotification("(${selectedDuration.toInt().getFormattedDuration()}) $formattedTimestamp")
}
} }
override fun onResume() { private fun pauseTimer(config: Config) {
super.onResume() cancelTimerWorker()
setupViews() requiredActivity.hideTimerNotification()
}
override fun onSaveInstanceState(outState: Bundle) { config.timerTickStamp = System.currentTimeMillis()
super.onSaveInstanceState(outState.apply {})
}
override fun onViewStateRestored(savedInstanceState: Bundle?) { val tick = config.timerTickStamp
super.onViewStateRestored(savedInstanceState) val duration = config.timerSeconds.toLong() * 1000 //MS
savedInstanceState?.apply {} val startedAt = config.timerStartStamp
val distance = duration - (tick - startedAt)
view.timer_time.text = distance.toInt().getFormattedDuration()
} }
fun updateAlarmSound(alarmSound: AlarmSound) { fun updateAlarmSound(alarmSound: AlarmSound) {
@ -147,30 +188,6 @@ class TimerFragment : Fragment() {
view.timer_sound.text = alarmSound.title view.timer_sound.text = alarmSound.title
} }
// private val isRunning
// get(): Boolean =
// WorkManager.getInstance(requiredActivity).getWorkInfosByTagLiveData(TIMER_WORKER_KEY).value?.firstOrNull()?.state == WorkInfo.State.ENQUEUED
private fun setupViews() {
val config = requiredActivity.config
val textColor = config.textColor
view.apply {
requiredActivity.updateTextColors(timer_fragment)
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
timer_reset.applyColorFilter(textColor)
timer_initial_time.text = config.timerSeconds.getFormattedDuration()
timer_initial_time.colorLeftDrawable(textColor)
timer_vibrate.isChecked = config.timerVibrate
timer_vibrate.colorLeftDrawable(textColor)
timer_sound.text = config.timerSoundTitle
timer_sound.colorLeftDrawable(textColor)
}
}
private fun updateIcons(isRunning: Boolean) { private fun updateIcons(isRunning: Boolean) {
val drawableId = if (isRunning) R.drawable.ic_pause_vector else R.drawable.ic_play_vector val drawableId = if (isRunning) R.drawable.ic_pause_vector else R.drawable.ic_play_vector
val iconColor = if (requiredActivity.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else requiredActivity.config.textColor val iconColor = if (requiredActivity.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else requiredActivity.config.textColor

View File

@ -5,7 +5,6 @@ import com.simplemobiletools.commons.extensions.getDefaultAlarmTitle
import com.simplemobiletools.commons.extensions.getDefaultAlarmUri import com.simplemobiletools.commons.extensions.getDefaultAlarmUri
import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM
import com.simplemobiletools.commons.helpers.BaseConfig import com.simplemobiletools.commons.helpers.BaseConfig
import java.util.concurrent.TimeUnit
class Config(context: Context) : BaseConfig(context) { class Config(context: Context) : BaseConfig(context) {
companion object { companion object {
@ -28,9 +27,13 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getInt(TIMER_SECONDS, 300) get() = prefs.getInt(TIMER_SECONDS, 300)
set(lastTimerSeconds) = prefs.edit().putInt(TIMER_SECONDS, lastTimerSeconds).apply() set(lastTimerSeconds) = prefs.edit().putInt(TIMER_SECONDS, lastTimerSeconds).apply()
var timerTimeStamp: Long var timerStartStamp: Long
get() = prefs.getLong(TIMER_TIMESTAMP, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(timerSeconds.toLong())) get() = prefs.getLong(TIMER_START_TIMESTAMP, 0L)
set(timestamp) = prefs.edit().putLong(TIMER_TIMESTAMP, timestamp).apply() set(timestamp) = prefs.edit().putLong(TIMER_START_TIMESTAMP, timestamp).apply()
var timerTickStamp: Long
get() = prefs.getLong(TIMER_TICK_TIMESTAMP, 0L)
set(timestamp) = prefs.edit().putLong(TIMER_TICK_TIMESTAMP, timestamp).apply()
var timerVibrate: Boolean var timerVibrate: Boolean
get() = prefs.getBoolean(TIMER_VIBRATE, false) get() = prefs.getBoolean(TIMER_VIBRATE, false)

View File

@ -8,7 +8,8 @@ const val SHOW_SECONDS = "show_seconds"
const val SELECTED_TIME_ZONES = "selected_time_zones" const val SELECTED_TIME_ZONES = "selected_time_zones"
const val EDITED_TIME_ZONE_TITLES = "edited_time_zone_titles" const val EDITED_TIME_ZONE_TITLES = "edited_time_zone_titles"
const val TIMER_SECONDS = "timer_seconds" const val TIMER_SECONDS = "timer_seconds"
const val TIMER_TIMESTAMP = "timer_timetamp" const val TIMER_START_TIMESTAMP = "timer_timetamp"
const val TIMER_TICK_TIMESTAMP = "timer_tick"
const val TIMER_VIBRATE = "timer_vibrate" const val TIMER_VIBRATE = "timer_vibrate"
const val TIMER_SOUND_URI = "timer_sound_uri" const val TIMER_SOUND_URI = "timer_sound_uri"
const val TIMER_SOUND_TITLE = "timer_sound_title" const val TIMER_SOUND_TITLE = "timer_sound_title"

View File

@ -11,34 +11,31 @@ private const val TIMER_REQUEST_ID = "TIMER_REQUEST_ID"
const val TIMER_WORKER_KEY = "TIMER_WORKER_KEY" const val TIMER_WORKER_KEY = "TIMER_WORKER_KEY"
private fun Fragment.saveTimerRequestId(uuid: UUID) = private fun Fragment.saveTimerRequestId(uuid: UUID) =
preferences.edit().putString(TIMER_REQUEST_ID, uuid.toString()).apply() preferences.edit().putString(TIMER_REQUEST_ID, uuid.toString()).apply()
val Fragment.timerRequestId: UUID? get() = val Fragment.timerRequestId: UUID?
preferences.getString(TIMER_REQUEST_ID, UUID.randomUUID().toString())?.let { UUID.fromString(it) } get() =
preferences.getString(TIMER_REQUEST_ID, UUID.randomUUID().toString())?.let { UUID.fromString(it) }
fun Fragment.cancelTimerWorker() = fun Fragment.cancelTimerWorker() =
WorkManager.getInstance(requiredActivity).cancelAllWorkByTag(TIMER_WORKER_KEY) WorkManager.getInstance(requiredActivity).cancelAllWorkByTag(TIMER_WORKER_KEY)
fun Fragment.enqueueTimerWorker(delay: Long) = fun Fragment.enqueueTimerWorker(delay: Long) =
WorkManager.getInstance(requiredActivity).enqueueUniqueWork(TIMER_WORKER_KEY, ExistingWorkPolicy.REPLACE, timerRequest(delay)) WorkManager.getInstance(requiredActivity).enqueueUniqueWork(TIMER_WORKER_KEY, ExistingWorkPolicy.REPLACE, timerRequest(delay))
private fun Fragment.timerRequest(delay: Long) = private fun Fragment.timerRequest(delay: Long): OneTimeWorkRequest =
OneTimeWorkRequestBuilder<TimerWorker>().setInitialDelay(delay, TimeUnit.MILLISECONDS).addTag(TIMER_WORKER_KEY).build().also { OneTimeWorkRequestBuilder<TimerWorker>().setInitialDelay(delay, TimeUnit.MILLISECONDS).addTag(TIMER_WORKER_KEY).build().also {
saveTimerRequestId(it.id) saveTimerRequestId(it.id)
} }
class TimerWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { class TimerWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result = override fun doWork(): Result =
try { try {
context.showTimerNotification(false) context.showTimerNotification(false)
Result.success() context.config.timerTickStamp = 0L
} catch (exception: Exception) { context.config.timerStartStamp = 0L
Result.failure() Result.success()
} } catch (exception: Exception) {
Result.failure()
override fun onStopped() { }
super.onStopped()
context.hideTimerNotification()
}
} }