mirror of
https://github.com/SimpleMobileTools/Simple-Clock.git
synced 2025-06-05 22:19:17 +02:00
start a new foreground service when the stopwatch is active and the app is moved to the background
This commit is contained in:
@ -12,9 +12,13 @@ import androidx.lifecycle.OnLifecycleEvent
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import com.facebook.stetho.Stetho
|
||||
import com.simplemobiletools.clock.extensions.*
|
||||
import com.simplemobiletools.clock.helpers.Stopwatch
|
||||
import com.simplemobiletools.clock.helpers.Stopwatch.State
|
||||
import com.simplemobiletools.clock.models.TimerEvent
|
||||
import com.simplemobiletools.clock.models.TimerState
|
||||
import com.simplemobiletools.clock.services.StopwatchStopService
|
||||
import com.simplemobiletools.clock.services.TimerStopService
|
||||
import com.simplemobiletools.clock.services.startStopwatchService
|
||||
import com.simplemobiletools.clock.services.startTimerService
|
||||
import com.simplemobiletools.commons.extensions.checkUseEnglish
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -49,6 +53,9 @@ class App : Application(), LifecycleObserver {
|
||||
startTimerService(this)
|
||||
}
|
||||
}
|
||||
if (Stopwatch.state == State.RUNNING) {
|
||||
startStopwatchService(this)
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
@ -62,6 +69,9 @@ class App : Application(), LifecycleObserver {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Stopwatch.state == State.RUNNING) {
|
||||
EventBus.getDefault().post(StopwatchStopService)
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
|
@ -159,6 +159,12 @@ fun Context.getOpenTimerTabIntent(timerId: Int): PendingIntent {
|
||||
return PendingIntent.getActivity(this, timerId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
fun Context.getOpenStopwatchTabIntent(): PendingIntent {
|
||||
val intent = getLaunchIntent() ?: Intent(this, SplashActivity::class.java)
|
||||
intent.putExtra(OPEN_TAB, TAB_STOPWATCH)
|
||||
return PendingIntent.getActivity(this, OPEN_STOPWATCH_TAB_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
fun Context.getAlarmIntent(alarm: Alarm): PendingIntent {
|
||||
val intent = Intent(this, AlarmReceiver::class.java)
|
||||
intent.putExtra(ALARM_ID, alarm.id)
|
||||
|
@ -34,10 +34,12 @@ const val DEFAULT_MAX_TIMER_REMINDER_SECS = 60
|
||||
const val PICK_AUDIO_FILE_INTENT_ID = 9994
|
||||
const val REMINDER_ACTIVITY_INTENT_ID = 9995
|
||||
const val OPEN_ALARMS_TAB_INTENT_ID = 9996
|
||||
const val OPEN_STOPWATCH_TAB_INTENT_ID = 9993
|
||||
const val UPDATE_WIDGET_INTENT_ID = 9997
|
||||
const val OPEN_APP_INTENT_ID = 9998
|
||||
const val ALARM_NOTIF_ID = 9998
|
||||
const val TIMER_RUNNING_NOTIF_ID = 10000
|
||||
const val STOPWATCH_RUNNING_NOTIF_ID = 10001
|
||||
|
||||
const val OPEN_TAB = "open_tab"
|
||||
const val TAB_CLOCK = 0
|
||||
|
@ -0,0 +1,116 @@
|
||||
package com.simplemobiletools.clock.services
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.simplemobiletools.clock.R
|
||||
import com.simplemobiletools.clock.extensions.getFormattedDuration
|
||||
import com.simplemobiletools.clock.extensions.getOpenStopwatchTabIntent
|
||||
import com.simplemobiletools.clock.helpers.STOPWATCH_RUNNING_NOTIF_ID
|
||||
import com.simplemobiletools.clock.helpers.Stopwatch
|
||||
import com.simplemobiletools.clock.helpers.Stopwatch.State
|
||||
import com.simplemobiletools.clock.helpers.Stopwatch.UpdateListener
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class StopwatchService : Service() {
|
||||
|
||||
private val bus = EventBus.getDefault()
|
||||
private lateinit var notificationManager: NotificationManager
|
||||
private lateinit var notificationBuilder: NotificationCompat.Builder
|
||||
private var isStopping = false
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
bus.register(this)
|
||||
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationBuilder = getServiceNotificationBuilder(
|
||||
getString(R.string.app_name),
|
||||
getString(R.string.stopwatch)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
super.onStartCommand(intent, flags, startId)
|
||||
isStopping = false
|
||||
startForeground(
|
||||
STOPWATCH_RUNNING_NOTIF_ID,
|
||||
notificationBuilder.build()
|
||||
)
|
||||
Stopwatch.addUpdateListener(updateListener)
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
bus.unregister(this)
|
||||
Stopwatch.removeUpdateListener(updateListener)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onMessageEvent(event: StopwatchStopService) {
|
||||
isStopping = true
|
||||
stopForeground(true)
|
||||
}
|
||||
|
||||
private fun getServiceNotificationBuilder(
|
||||
title: String,
|
||||
contentText: String
|
||||
): NotificationCompat.Builder {
|
||||
val channelId = "simple_alarm_stopwatch"
|
||||
val label = getString(R.string.stopwatch)
|
||||
val importance = NotificationManager.IMPORTANCE_DEFAULT
|
||||
NotificationChannel(channelId, label, importance).apply {
|
||||
setSound(null, null)
|
||||
notificationManager.createNotificationChannel(this)
|
||||
}
|
||||
return NotificationCompat.Builder(this, channelId)
|
||||
.setContentTitle(title)
|
||||
.setContentText(contentText)
|
||||
.setSmallIcon(R.drawable.ic_stopwatch_vector)
|
||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||
.setSound(null)
|
||||
.setOngoing(true)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(getOpenStopwatchTabIntent())
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
}
|
||||
|
||||
private fun updateNotification(totalTime: Long) {
|
||||
val formattedDuration = totalTime.getFormattedDuration()
|
||||
notificationBuilder.setContentTitle(formattedDuration)
|
||||
.setContentText(getString(R.string.stopwatch))
|
||||
notificationManager.notify(
|
||||
STOPWATCH_RUNNING_NOTIF_ID,
|
||||
notificationBuilder.build()
|
||||
)
|
||||
}
|
||||
|
||||
private val updateListener = object : UpdateListener {
|
||||
override fun onUpdate(totalTime: Long, lapTime: Long, useLongerMSFormat: Boolean) {
|
||||
if (!isStopping) {
|
||||
updateNotification(totalTime)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(state: State) {
|
||||
if (state == State.STOPPED) {
|
||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun startStopwatchService(context: Context) {
|
||||
ContextCompat.startForegroundService(context, Intent(context, StopwatchService::class.java))
|
||||
}
|
||||
|
||||
object StopwatchStopService
|
Reference in New Issue
Block a user