mirror of
				https://github.com/SimpleMobileTools/Simple-Clock.git
				synced 2025-06-05 22:19:17 +02:00 
			
		
		
		
	wip
This commit is contained in:
		| @@ -54,6 +54,16 @@ android { | ||||
|         checkReleaseBuilds false | ||||
|         abortOnError false | ||||
|     } | ||||
|  | ||||
|     compileOptions { | ||||
|         sourceCompatibility = 1.8 | ||||
|         targetCompatibility = 1.8 | ||||
|     } | ||||
|  | ||||
|     kotlinOptions { | ||||
|         jvmTarget = "1.8" | ||||
|         freeCompilerArgs = ["-XXLanguage:+NewInference"] | ||||
|     } | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| @@ -61,4 +71,8 @@ dependencies { | ||||
|     implementation 'com.facebook.stetho:stetho:1.5.0' | ||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' | ||||
|     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.Context | ||||
| import android.content.Intent | ||||
| import android.content.SharedPreferences | ||||
| import android.media.AudioAttributes | ||||
| import android.media.AudioManager | ||||
| import android.net.Uri | ||||
| @@ -15,6 +16,7 @@ import android.text.style.RelativeSizeSpan | ||||
| import android.widget.Toast | ||||
| import androidx.core.app.AlarmManagerCompat | ||||
| import androidx.core.app.NotificationCompat | ||||
| import androidx.preference.PreferenceManager | ||||
| import com.simplemobiletools.clock.R | ||||
| import com.simplemobiletools.clock.activities.ReminderActivity | ||||
| import com.simplemobiletools.clock.activities.SnoozeReminderActivity | ||||
| @@ -382,3 +384,5 @@ fun Context.checkAlarmsWithDeletedSoundUri(uri: String) { | ||||
|         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.NotificationChannel | ||||
| import android.app.NotificationManager | ||||
| import android.app.NotificationManager.IMPORTANCE_HIGH | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.graphics.Color | ||||
| @@ -12,11 +13,16 @@ import android.os.Build | ||||
| import android.os.Bundle | ||||
| import android.os.Handler | ||||
| import android.os.SystemClock | ||||
| import android.util.Log | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import androidx.core.app.NotificationCompat | ||||
| 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.activities.ReminderActivity | ||||
| 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.helpers.PICK_AUDIO_FILE_INTENT_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.extensions.* | ||||
| import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_ALARM | ||||
| import com.simplemobiletools.commons.helpers.isOreoPlus | ||||
| 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.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() { | ||||
|  | ||||
|     private val UPDATE_INTERVAL = 1000L | ||||
|     private val WAS_RUNNING = "was_running" | ||||
|     private val CURRENT_TICKS = "current_ticks" | ||||
|     private val TOTAL_TICKS = "total_ticks" | ||||
|  | ||||
|     private var isRunning = false | ||||
|     private var uptimeAtStart = 0L | ||||
|     private var initialSecs = 0 | ||||
|     private var totalTicks = 0 | ||||
|     private var currentTicks = 0 | ||||
|     private var updateHandler = Handler() | ||||
|     private var isForegrounded = true | ||||
|  | ||||
|     lateinit var view: ViewGroup | ||||
|  | ||||
|     @InternalCoroutinesApi | ||||
|     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 { | ||||
|             timer_time.setOnClickListener { | ||||
|                 togglePlayPause() | ||||
|                 val selectedDuration = config.timerSeconds | ||||
|                 enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong())) | ||||
|                 showNotification(selectedDuration.getFormattedDuration()) | ||||
|             } | ||||
|  | ||||
|             timer_play_pause.setOnClickListener { | ||||
|                 togglePlayPause() | ||||
|                 val selectedDuration = config.timerSeconds | ||||
|                 enqueueTimerWorker(TimeUnit.SECONDS.toMillis(selectedDuration.toLong())) | ||||
|                 showNotification(selectedDuration.getFormattedDuration()) | ||||
|             } | ||||
|  | ||||
|             timer_reset.setOnClickListener { | ||||
|                 context!!.hideTimerNotification() | ||||
|                 resetTimer() | ||||
|                 cancelTimerWorker() | ||||
|             } | ||||
|  | ||||
|             timer_initial_time.setOnClickListener { | ||||
|                 MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { | ||||
|                     val seconds = if (it <= 0) 10 else it | ||||
|                     config.timerSeconds = seconds | ||||
|                     timer_initial_time.text = seconds.getFormattedDuration() | ||||
|                     if (!isRunning) { | ||||
|                         resetTimer() | ||||
|                     } | ||||
|                 MyTimePickerDialogDialog(activity as SimpleActivity, config.timerSeconds) { seconds -> | ||||
|                     val timerSeconds = if (seconds <= 0) 10 else seconds | ||||
|                     config.timerSeconds = timerSeconds | ||||
|                     timer_initial_time.text = timerSeconds.getFormattedDuration() | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -81,28 +99,47 @@ class TimerFragment : Fragment() { | ||||
|  | ||||
|             timer_sound.setOnClickListener { | ||||
|                 SelectAlarmSoundDialog(activity as SimpleActivity, config.timerSoundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID, | ||||
|                         ALARM_SOUND_TYPE_ALARM, true, onAlarmPicked = { | ||||
|                     if (it != null) { | ||||
|                         updateAlarmSound(it) | ||||
|                     } | ||||
|                 }, onAlarmSoundDeleted = { | ||||
|                     if (config.timerSoundUri == it.uri) { | ||||
|                         val defaultAlarm = context.getDefaultAlarmSound(ALARM_SOUND_TYPE_ALARM) | ||||
|                         updateAlarmSound(defaultAlarm) | ||||
|                     } | ||||
|                     context.checkAlarmsWithDeletedSoundUri(it.uri) | ||||
|                 }) | ||||
|                     ALARM_SOUND_TYPE_ALARM, true, | ||||
|                     onAlarmPicked = { sound -> | ||||
|                         if (sound != null) { | ||||
|                             updateAlarmSound(sound) | ||||
|                         } | ||||
|                     }, | ||||
|                     onAlarmSoundDeleted = { sound -> | ||||
|                         if (config.timerSoundUri == sound.uri) { | ||||
|                             val defaultAlarm = context.getDefaultAlarmSound(ALARM_SOUND_TYPE_ALARM) | ||||
|                             updateAlarmSound(defaultAlarm) | ||||
|                         } | ||||
|  | ||||
|                         context.checkAlarmsWithDeletedSoundUri(sound.uri) | ||||
|                     }) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         initialSecs = config.timerSeconds | ||||
|         updateDisplayedText() | ||||
|         return view | ||||
|     } | ||||
|  | ||||
|     override fun onStart() { | ||||
|         super.onStart() | ||||
|         isForegrounded = true | ||||
|         WorkManager.getInstance(activity!!).getWorkInfoByIdLiveData(timerRequestId) | ||||
|             .observe(this, Observer { workInfo -> | ||||
|                 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() { | ||||
| @@ -110,28 +147,12 @@ class TimerFragment : Fragment() { | ||||
|         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) { | ||||
|         outState.apply { | ||||
|         super.onSaveInstanceState(outState.apply { | ||||
|             putBoolean(WAS_RUNNING, isRunning) | ||||
|             putInt(TOTAL_TICKS, totalTicks) | ||||
|             putInt(CURRENT_TICKS, currentTicks) | ||||
|         } | ||||
|         super.onSaveInstanceState(outState) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     override fun onViewStateRestored(savedInstanceState: Bundle?) { | ||||
| @@ -140,25 +161,21 @@ class TimerFragment : Fragment() { | ||||
|             isRunning = getBoolean(WAS_RUNNING, false) | ||||
|             totalTicks = getInt(TOTAL_TICKS, 0) | ||||
|             currentTicks = getInt(CURRENT_TICKS, 0) | ||||
|  | ||||
|             if (isRunning) { | ||||
|                 uptimeAtStart = SystemClock.uptimeMillis() - currentTicks * UPDATE_INTERVAL | ||||
|                 updateTimerState(false) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fun updateAlarmSound(alarmSound: AlarmSound) { | ||||
|         context!!.config.timerSoundTitle = alarmSound.title | ||||
|         context!!.config.timerSoundUri = alarmSound.uri | ||||
|         requiredActivity.config.timerSoundTitle = alarmSound.title | ||||
|         requiredActivity.config.timerSoundUri = alarmSound.uri | ||||
|         view.timer_sound.text = alarmSound.title | ||||
|     } | ||||
|  | ||||
|     private fun setupViews() { | ||||
|         val config = context!!.config | ||||
|         val config = requiredActivity.config | ||||
|         val textColor = config.textColor | ||||
|  | ||||
|         view.apply { | ||||
|             context!!.updateTextColors(timer_fragment) | ||||
|             requiredActivity.updateTextColors(timer_fragment) | ||||
|             timer_play_pause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, context!!.getAdjustedPrimaryColor()) | ||||
|             timer_reset.applyColorFilter(textColor) | ||||
|  | ||||
| @@ -173,84 +190,19 @@ class TimerFragment : Fragment() { | ||||
|         } | ||||
|  | ||||
|         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() { | ||||
|         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)) | ||||
|     } | ||||
|  | ||||
|     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) | ||||
|     private fun showNotification(formattedDuration: String) { | ||||
|         val channelId = "simple_alarm_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()) { | ||||
|             val importance = NotificationManager.IMPORTANCE_HIGH | ||||
|             NotificationChannel(channelId, label, importance).apply { | ||||
| @@ -260,29 +212,62 @@ class TimerFragment : Fragment() { | ||||
|         } | ||||
|  | ||||
|         val builder = NotificationCompat.Builder(context) | ||||
|                 .setContentTitle(label) | ||||
|                 .setContentText(formattedDuration) | ||||
|                 .setSmallIcon(R.drawable.ic_timer) | ||||
|                 .setContentIntent(context!!.getOpenTimerTabIntent()) | ||||
|                 .setPriority(Notification.PRIORITY_HIGH) | ||||
|                 .setSound(null) | ||||
|                 .setOngoing(true) | ||||
|                 .setAutoCancel(true) | ||||
|                 .setChannelId(channelId) | ||||
|             .setContentTitle(label) | ||||
|             .setContentText(formattedDuration) | ||||
|             .setSmallIcon(R.drawable.ic_timer) | ||||
|             .setContentIntent(context!!.getOpenTimerTabIntent()) | ||||
|             .setPriority(Notification.PRIORITY_HIGH) | ||||
|             .setSound(null) | ||||
|             .setOngoing(true) | ||||
|             .setAutoCancel(true) | ||||
|             .setChannelId(channelId) | ||||
|  | ||||
|         builder.setVisibility(Notification.VISIBILITY_PUBLIC) | ||||
|         builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) | ||||
|         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() | ||||
|         } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Pavol Franek
					Pavol Franek