mirror of
https://github.com/SimpleMobileTools/Simple-Clock.git
synced 2025-04-24 23:18:43 +02:00
wip
This commit is contained in:
parent
afaa3f470c
commit
046f0323d1
@ -54,6 +54,16 @@ android {
|
|||||||
checkReleaseBuilds false
|
checkReleaseBuilds false
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
targetCompatibility = 1.8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
freeCompilerArgs = ["-XXLanguage:+NewInference"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -61,4 +71,8 @@ dependencies {
|
|||||||
implementation 'com.facebook.stetho:stetho:1.5.0'
|
implementation 'com.facebook.stetho:stetho:1.5.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
|
||||||
implementation 'com.shawnlin:number-picker:2.4.6'
|
implementation 'com.shawnlin:number-picker:2.4.6'
|
||||||
|
implementation "androidx.preference:preference:1.1.0"
|
||||||
|
implementation "androidx.work:work-runtime-ktx:2.3.2"
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.appwidget.AppWidgetManager
|
|||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@ -15,6 +16,7 @@ import android.text.style.RelativeSizeSpan
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.app.AlarmManagerCompat
|
import androidx.core.app.AlarmManagerCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.simplemobiletools.clock.R
|
import com.simplemobiletools.clock.R
|
||||||
import com.simplemobiletools.clock.activities.ReminderActivity
|
import com.simplemobiletools.clock.activities.ReminderActivity
|
||||||
import com.simplemobiletools.clock.activities.SnoozeReminderActivity
|
import com.simplemobiletools.clock.activities.SnoozeReminderActivity
|
||||||
@ -382,3 +384,5 @@ fun Context.checkAlarmsWithDeletedSoundUri(uri: String) {
|
|||||||
dbHelper.updateAlarm(it)
|
dbHelper.updateAlarm(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Context.preferences: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.simplemobiletools.clock.extensions
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
|
||||||
|
val Fragment.requiredActivity: FragmentActivity get() = this.activity!!
|
||||||
|
|
||||||
|
val Fragment.preferences: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences(requiredActivity)
|
@ -4,6 +4,7 @@ import android.annotation.TargetApi
|
|||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
|
import android.app.NotificationManager.IMPORTANCE_HIGH
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@ -12,11 +13,16 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
|
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
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.work.WorkInfo
|
||||||
|
import androidx.work.WorkManager
|
||||||
import com.simplemobiletools.clock.R
|
import com.simplemobiletools.clock.R
|
||||||
import com.simplemobiletools.clock.activities.ReminderActivity
|
import com.simplemobiletools.clock.activities.ReminderActivity
|
||||||
import com.simplemobiletools.clock.activities.SimpleActivity
|
import com.simplemobiletools.clock.activities.SimpleActivity
|
||||||
@ -24,53 +30,65 @@ import com.simplemobiletools.clock.dialogs.MyTimePickerDialogDialog
|
|||||||
import com.simplemobiletools.clock.extensions.*
|
import com.simplemobiletools.clock.extensions.*
|
||||||
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.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
|
||||||
import com.simplemobiletools.commons.helpers.isOreoPlus
|
import com.simplemobiletools.commons.helpers.isOreoPlus
|
||||||
import com.simplemobiletools.commons.models.AlarmSound
|
import com.simplemobiletools.commons.models.AlarmSound
|
||||||
|
import kotlinx.android.synthetic.main.fragment_timer.*
|
||||||
import kotlinx.android.synthetic.main.fragment_timer.view.*
|
import kotlinx.android.synthetic.main.fragment_timer.view.*
|
||||||
|
import kotlinx.android.synthetic.main.fragment_timer.view.timer_time
|
||||||
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class TimerFragment : Fragment() {
|
class TimerFragment : Fragment() {
|
||||||
|
|
||||||
private val UPDATE_INTERVAL = 1000L
|
private val UPDATE_INTERVAL = 1000L
|
||||||
private val WAS_RUNNING = "was_running"
|
private val WAS_RUNNING = "was_running"
|
||||||
private val CURRENT_TICKS = "current_ticks"
|
private val CURRENT_TICKS = "current_ticks"
|
||||||
private val TOTAL_TICKS = "total_ticks"
|
private val TOTAL_TICKS = "total_ticks"
|
||||||
|
|
||||||
private var isRunning = false
|
private var isRunning = false
|
||||||
private var uptimeAtStart = 0L
|
|
||||||
private var initialSecs = 0
|
private var initialSecs = 0
|
||||||
private var totalTicks = 0
|
private var totalTicks = 0
|
||||||
private var currentTicks = 0
|
private var currentTicks = 0
|
||||||
private var updateHandler = Handler()
|
|
||||||
private var isForegrounded = true
|
|
||||||
|
|
||||||
lateinit var view: ViewGroup
|
lateinit var view: ViewGroup
|
||||||
|
|
||||||
|
@InternalCoroutinesApi
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
val config = context!!.config
|
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 {
|
||||||
timer_time.setOnClickListener {
|
timer_time.setOnClickListener {
|
||||||
togglePlayPause()
|
val selectedDuration = config.timerSeconds
|
||||||
|
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
|
||||||
|
showNotification(selectedDuration.getFormattedDuration())
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_play_pause.setOnClickListener {
|
timer_play_pause.setOnClickListener {
|
||||||
togglePlayPause()
|
val selectedDuration = config.timerSeconds
|
||||||
|
enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong()))
|
||||||
|
showNotification(selectedDuration.getFormattedDuration())
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_reset.setOnClickListener {
|
timer_reset.setOnClickListener {
|
||||||
context!!.hideTimerNotification()
|
cancelTimerWorker()
|
||||||
resetTimer()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_initial_time.setOnClickListener {
|
timer_initial_time.setOnClickListener {
|
||||||
MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) {
|
MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { seconds ->
|
||||||
val seconds = if (it <= 0) 10 else it
|
val timerSeconds = if (seconds <= 0) 10 else seconds
|
||||||
config.timerSeconds = seconds
|
config.timerSeconds = timerSeconds
|
||||||
timer_initial_time.text = seconds.getFormattedDuration()
|
timer_initial_time.text = timerSeconds.getFormattedDuration()
|
||||||
if (!isRunning) {
|
|
||||||
resetTimer()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,28 +99,47 @@ class TimerFragment : Fragment() {
|
|||||||
|
|
||||||
timer_sound.setOnClickListener {
|
timer_sound.setOnClickListener {
|
||||||
SelectAlarmSoundDialog(activity as SimpleActivity, config.timerSoundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID,
|
SelectAlarmSoundDialog(activity as SimpleActivity, config.timerSoundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID,
|
||||||
ALARM_SOUND_TYPE_ALARM, true, onAlarmPicked = {
|
ALARM_SOUND_TYPE_ALARM, true,
|
||||||
if (it != null) {
|
onAlarmPicked = { sound ->
|
||||||
updateAlarmSound(it)
|
if (sound != null) {
|
||||||
}
|
updateAlarmSound(sound)
|
||||||
}, onAlarmSoundDeleted = {
|
}
|
||||||
if (config.timerSoundUri == it.uri) {
|
},
|
||||||
val defaultAlarm = context.getDefaultAlarmSound(ALARM_SOUND_TYPE_ALARM)
|
onAlarmSoundDeleted = { sound ->
|
||||||
updateAlarmSound(defaultAlarm)
|
if (config.timerSoundUri == sound.uri) {
|
||||||
}
|
val defaultAlarm = context.getDefaultAlarmSound(ALARM_SOUND_TYPE_ALARM)
|
||||||
context.checkAlarmsWithDeletedSoundUri(it.uri)
|
updateAlarmSound(defaultAlarm)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
context.checkAlarmsWithDeletedSoundUri(sound.uri)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initialSecs = config.timerSeconds
|
initialSecs = config.timerSeconds
|
||||||
updateDisplayedText()
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
WorkManager.getInstance(activity!!).getWorkInfoByIdLiveData(timerRequestId)
|
||||||
super.onStart()
|
.observe(this, Observer { workInfo ->
|
||||||
isForegrounded = true
|
Log.e("test", workInfo.toString())
|
||||||
|
|
||||||
|
when (workInfo.state) {
|
||||||
|
WorkInfo.State.SUCCEEDED -> {
|
||||||
|
showNotification("-")
|
||||||
|
}
|
||||||
|
WorkInfo.State.FAILED -> {}
|
||||||
|
WorkInfo.State.CANCELLED -> {}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
val a = lifecycleScope.launch {
|
||||||
|
(config.timerSeconds downTo 0).asFlow().onEach { delay(1000) }.collect {
|
||||||
|
Log.e("test", it.toString())
|
||||||
|
timer_time.text = it.getFormattedDuration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -110,28 +147,12 @@ class TimerFragment : Fragment() {
|
|||||||
setupViews()
|
setupViews()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
isForegrounded = false
|
|
||||||
context!!.hideNotification(TIMER_NOTIF_ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
if (isRunning && activity?.isChangingConfigurations == false) {
|
|
||||||
context?.toast(R.string.timer_stopped)
|
|
||||||
}
|
|
||||||
isRunning = false
|
|
||||||
updateHandler.removeCallbacks(updateRunnable)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
outState.apply {
|
super.onSaveInstanceState(outState.apply {
|
||||||
putBoolean(WAS_RUNNING, isRunning)
|
putBoolean(WAS_RUNNING, isRunning)
|
||||||
putInt(TOTAL_TICKS, totalTicks)
|
putInt(TOTAL_TICKS, totalTicks)
|
||||||
putInt(CURRENT_TICKS, currentTicks)
|
putInt(CURRENT_TICKS, currentTicks)
|
||||||
}
|
})
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||||
@ -140,25 +161,21 @@ class TimerFragment : Fragment() {
|
|||||||
isRunning = getBoolean(WAS_RUNNING, false)
|
isRunning = getBoolean(WAS_RUNNING, false)
|
||||||
totalTicks = getInt(TOTAL_TICKS, 0)
|
totalTicks = getInt(TOTAL_TICKS, 0)
|
||||||
currentTicks = getInt(CURRENT_TICKS, 0)
|
currentTicks = getInt(CURRENT_TICKS, 0)
|
||||||
|
|
||||||
if (isRunning) {
|
|
||||||
uptimeAtStart = SystemClock.uptimeMillis() - currentTicks * UPDATE_INTERVAL
|
|
||||||
updateTimerState(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateAlarmSound(alarmSound: AlarmSound) {
|
fun updateAlarmSound(alarmSound: AlarmSound) {
|
||||||
context!!.config.timerSoundTitle = alarmSound.title
|
requiredActivity.config.timerSoundTitle = alarmSound.title
|
||||||
context!!.config.timerSoundUri = alarmSound.uri
|
requiredActivity.config.timerSoundUri = alarmSound.uri
|
||||||
view.timer_sound.text = alarmSound.title
|
view.timer_sound.text = alarmSound.title
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupViews() {
|
private fun setupViews() {
|
||||||
val config = context!!.config
|
val config = requiredActivity.config
|
||||||
val textColor = config.textColor
|
val textColor = config.textColor
|
||||||
|
|
||||||
view.apply {
|
view.apply {
|
||||||
context!!.updateTextColors(timer_fragment)
|
requiredActivity.updateTextColors(timer_fragment)
|
||||||
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
|
timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor())
|
||||||
timer_reset.applyColorFilter(textColor)
|
timer_reset.applyColorFilter(textColor)
|
||||||
|
|
||||||
@ -173,84 +190,19 @@ class TimerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateIcons()
|
updateIcons()
|
||||||
updateDisplayedText()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun togglePlayPause() {
|
|
||||||
isRunning = !isRunning
|
|
||||||
updateTimerState(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateTimerState(setUptimeAtStart: Boolean) {
|
|
||||||
updateIcons()
|
|
||||||
context!!.hideTimerNotification()
|
|
||||||
|
|
||||||
if (isRunning) {
|
|
||||||
updateHandler.post(updateRunnable)
|
|
||||||
view.timer_reset.beVisible()
|
|
||||||
if (setUptimeAtStart) {
|
|
||||||
uptimeAtStart = SystemClock.uptimeMillis()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateHandler.removeCallbacksAndMessages(null)
|
|
||||||
currentTicks = 0
|
|
||||||
totalTicks--
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateIcons() {
|
private fun updateIcons() {
|
||||||
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 (context!!.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else context!!.config.textColor
|
val iconColor = if (requiredActivity.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else requiredActivity.config.textColor
|
||||||
view.timer_play_pause.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, iconColor))
|
view.timer_play_pause.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, iconColor))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetTimer() {
|
|
||||||
updateHandler.removeCallbacks(updateRunnable)
|
|
||||||
isRunning = false
|
|
||||||
currentTicks = 0
|
|
||||||
totalTicks = 0
|
|
||||||
initialSecs = context!!.config.timerSeconds
|
|
||||||
updateDisplayedText()
|
|
||||||
updateIcons()
|
|
||||||
view.timer_reset.beGone()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateDisplayedText(): Boolean {
|
|
||||||
val diff = initialSecs - totalTicks
|
|
||||||
var formattedDuration = Math.abs(diff).getFormattedDuration()
|
|
||||||
|
|
||||||
if (diff < 0) {
|
|
||||||
formattedDuration = "-$formattedDuration"
|
|
||||||
if (!isForegrounded) {
|
|
||||||
resetTimer()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
view.timer_time.text = formattedDuration
|
|
||||||
if (diff == 0) {
|
|
||||||
if (context?.isScreenOn() == true) {
|
|
||||||
context!!.showTimerNotification(false)
|
|
||||||
Handler().postDelayed({
|
|
||||||
context?.hideTimerNotification()
|
|
||||||
}, context?.config!!.timerMaxReminderSecs * 1000L)
|
|
||||||
} else {
|
|
||||||
Intent(context, ReminderActivity::class.java).apply {
|
|
||||||
activity?.startActivity(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (diff > 0 && !isForegrounded && isRunning) {
|
|
||||||
showNotification(formattedDuration)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
private fun showNotification(formattedDuration: String) {
|
private fun showNotification(formattedDuration: String) {
|
||||||
val channelId = "simple_alarm_timer"
|
val channelId = "simple_alarm_timer"
|
||||||
val label = getString(R.string.timer)
|
val label = getString(R.string.timer)
|
||||||
val notificationManager = context!!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val notificationManager = requiredActivity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
if (isOreoPlus()) {
|
if (isOreoPlus()) {
|
||||||
val importance = NotificationManager.IMPORTANCE_HIGH
|
val importance = NotificationManager.IMPORTANCE_HIGH
|
||||||
NotificationChannel(channelId, label, importance).apply {
|
NotificationChannel(channelId, label, importance).apply {
|
||||||
@ -260,29 +212,62 @@ class TimerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val builder = NotificationCompat.Builder(context)
|
val builder = NotificationCompat.Builder(context)
|
||||||
.setContentTitle(label)
|
.setContentTitle(label)
|
||||||
.setContentText(formattedDuration)
|
.setContentText(formattedDuration)
|
||||||
.setSmallIcon(R.drawable.ic_timer)
|
.setSmallIcon(R.drawable.ic_timer)
|
||||||
.setContentIntent(context!!.getOpenTimerTabIntent())
|
.setContentIntent(context!!.getOpenTimerTabIntent())
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setSound(null)
|
.setSound(null)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setChannelId(channelId)
|
.setChannelId(channelId)
|
||||||
|
|
||||||
builder.setVisibility(Notification.VISIBILITY_PUBLIC)
|
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
notificationManager.notify(TIMER_NOTIF_ID, builder.build())
|
notificationManager.notify(TIMER_NOTIF_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val updateRunnable = object : Runnable {
|
|
||||||
override fun run() {
|
|
||||||
if (isRunning) {
|
|
||||||
if (updateDisplayedText()) {
|
|
||||||
currentTicks++
|
|
||||||
totalTicks++
|
|
||||||
updateHandler.postAtTime(this, uptimeAtStart + currentTicks * UPDATE_INTERVAL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private fun resetTimer() {
|
||||||
|
// updateHandler.removeCallbacks(updateRunnable)
|
||||||
|
// isRunning = false
|
||||||
|
// currentTicks = 0
|
||||||
|
// totalTicks = 0
|
||||||
|
// initialSecs = context!!.config.timerSeconds
|
||||||
|
// updateDisplayedText()
|
||||||
|
// updateIcons()
|
||||||
|
// view.timer_reset.beGone()
|
||||||
|
// requiredActivity.hideTimerNotification()
|
||||||
|
// context!!.hideNotification(TIMER_NOTIF_ID)
|
||||||
|
// context?.toast(R.string.timer_stopped)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private fun updateDisplayedText(): Boolean {
|
||||||
|
// val diff = initialSecs - totalTicks
|
||||||
|
// var formattedDuration = Math.abs(diff).getFormattedDuration()
|
||||||
|
//
|
||||||
|
// if (diff < 0) {
|
||||||
|
// formattedDuration = "-$formattedDuration"
|
||||||
|
// if (!isForegrounded) {
|
||||||
|
// resetTimer()
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// view.timer_time.text = formattedDuration
|
||||||
|
// if (diff == 0) {
|
||||||
|
// if (context?.isScreenOn() == true) {
|
||||||
|
// context!!.showTimerNotification(false)
|
||||||
|
// Handler().postDelayed({
|
||||||
|
// context?.hideTimerNotification()
|
||||||
|
// }, context?.config!!.timerMaxReminderSecs * 1000L)
|
||||||
|
// } else {
|
||||||
|
// Intent(context, ReminderActivity::class.java).apply {
|
||||||
|
// activity?.startActivity(this)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (diff > 0 && !isForegrounded && isRunning) {
|
||||||
|
// showNotification(formattedDuration)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.simplemobiletools.clock.workers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.work.*
|
||||||
|
import com.simplemobiletools.clock.extensions.preferences
|
||||||
|
import com.simplemobiletools.clock.extensions.requiredActivity
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
private const val TIMER_REQUEST_ID = "TIMER_REQUEST_ID"
|
||||||
|
private const val TIMER_WORKER_KEY = "TIMER_WORKER_KEY"
|
||||||
|
|
||||||
|
private fun Fragment.saveTimerRequestId(uuid: UUID) =
|
||||||
|
preferences.edit().putString(TIMER_REQUEST_ID, uuid.toString()).apply()
|
||||||
|
|
||||||
|
val Fragment.timerRequestId: UUID get() =
|
||||||
|
UUID.fromString(preferences.getString(TIMER_REQUEST_ID, UUID.randomUUID().toString()))
|
||||||
|
|
||||||
|
fun Fragment.cancelTimerWorker() =
|
||||||
|
WorkManager.getInstance(requiredActivity).apply {
|
||||||
|
timerRequestId.let(::cancelWorkById)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Fragment.enqueueTimerWorker(delay: Long) =
|
||||||
|
WorkManager.getInstance(requiredActivity).enqueueUniqueWork(TIMER_WORKER_KEY, ExistingWorkPolicy.REPLACE, timerRequest(delay))
|
||||||
|
|
||||||
|
private fun Fragment.timerRequest(delay: Long) =
|
||||||
|
OneTimeWorkRequestBuilder<TimerWorker>().setInitialDelay(delay, TimeUnit.MILLISECONDS).build().also {
|
||||||
|
saveTimerRequestId(it.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimerWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
|
||||||
|
override fun doWork(): Result =
|
||||||
|
try {
|
||||||
|
Result.success()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Result.failure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user