Handle timer notifications

This commit is contained in:
Paul Akhamiogu 2021-09-02 20:27:07 +01:00
parent 9b421b3676
commit 9df105ae8d
11 changed files with 97 additions and 23 deletions

View File

@ -27,7 +27,7 @@ import org.greenrobot.eventbus.ThreadMode
class App : Application(), LifecycleObserver {
private var timers = mutableMapOf<Long, CountDownTimer>()
private var countDownTimers = mutableMapOf<Long, CountDownTimer>()
override fun onCreate() {
super.onCreate()
@ -62,7 +62,9 @@ class App : Application(), LifecycleObserver {
timerHelper.getTimers { timers ->
val runningTimers = timers.filter { it.state is TimerState.Running }
runningTimers.forEach { timer ->
EventBus.getDefault().post(TimerEvent.Start(timer.id!!, (timer.state as TimerState.Running).tick))
if (countDownTimers[timer.id] == null) {
EventBus.getDefault().post(TimerEvent.Start(timer.id!!, (timer.state as TimerState.Running).tick))
}
}
}
}
@ -71,7 +73,7 @@ class App : Application(), LifecycleObserver {
fun onMessageEvent(event: TimerEvent.Reset) {
Log.w(TAG, "onMessageEvent: $event")
updateTimerState(event.timerId, TimerState.Idle)
timers[event.timerId]?.cancel()
countDownTimers[event.timerId]?.cancel()
}
@Subscribe(threadMode = ThreadMode.MAIN)
@ -88,7 +90,7 @@ class App : Application(), LifecycleObserver {
EventBus.getDefault().post(TimerStopService)
}
}.start()
timers[event.timerId] = countDownTimer
countDownTimers[event.timerId] = countDownTimer
}
@Subscribe(threadMode = ThreadMode.MAIN)
@ -108,7 +110,7 @@ class App : Application(), LifecycleObserver {
Log.w(TAG, "onMessageEvent: $event")
timerHelper.getTimer(event.timerId) { timer ->
updateTimerState(event.timerId, TimerState.Paused(event.duration, (timer.state as TimerState.Running).tick))
timers[event.timerId]?.cancel()
countDownTimers[event.timerId]?.cancel()
}
}

View File

@ -3,6 +3,7 @@ package com.simplemobiletools.clock.activities
import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
@ -19,9 +20,11 @@ import com.simplemobiletools.commons.helpers.LICENSE_RTL
import com.simplemobiletools.commons.helpers.LICENSE_STETHO
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.FAQItem
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.main_tabs_holder
import kotlinx.android.synthetic.main.activity_main.view_pager
class MainActivity : SimpleActivity() {
private val TAG = "MainActivity"
private var storedTextColor = 0
private var storedBackgroundColor = 0
private var storedPrimaryColor = 0
@ -29,8 +32,8 @@ class MainActivity : SimpleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
intent.extras?.printAllItems("onCreate")
appLaunched(BuildConfig.APPLICATION_ID)
storeStateVariables()
initFragments()
@ -100,9 +103,17 @@ class MainActivity : SimpleActivity() {
}
override fun onNewIntent(intent: Intent) {
intent.extras?.printAllItems("onNewIntent")
if (intent.extras?.containsKey(OPEN_TAB) == true) {
view_pager.setCurrentItem(intent.getIntExtra(OPEN_TAB, TAB_CLOCK), false)
val tabToOpen = intent.getIntExtra(OPEN_TAB, TAB_CLOCK)
view_pager.setCurrentItem(tabToOpen, false)
if (tabToOpen == TAB_TIMER) {
val timerId = intent.getLongExtra(TIMER_ID, INVALID_TIMER_ID)
Log.e(TAG, "onNewIntent: TIMER ID: $timerId")
(view_pager.adapter as ViewPagerAdapter).updateTimerPosition(timerId)
}
}
super.onNewIntent(intent)
}
private fun storeStateVariables() {
@ -136,7 +147,8 @@ class MainActivity : SimpleActivity() {
private fun getViewPagerAdapter() = view_pager.adapter as? ViewPagerAdapter
private fun initFragments() {
view_pager.adapter = ViewPagerAdapter(supportFragmentManager)
val viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
view_pager.adapter = viewPagerAdapter
view_pager.onPageChangeListener {
main_tabs_holder.getTabAt(it)?.select()
invalidateOptionsMenu()
@ -144,6 +156,12 @@ class MainActivity : SimpleActivity() {
val tabToOpen = intent.getIntExtra(OPEN_TAB, config.lastUsedViewPagerPage)
intent.removeExtra(OPEN_TAB)
if (tabToOpen == TAB_TIMER) {
Log.e(TAG, "initFragments: TIMER")
val timerId = intent.getLongExtra(TIMER_ID, INVALID_TIMER_ID)
Log.e(TAG, "initFragments: TIMER ID: $timerId")
viewPagerAdapter.updateTimerPosition(timerId)
}
view_pager.currentItem = tabToOpen
view_pager.offscreenPageLimit = TABS_COUNT - 1
main_tabs_holder.onTabSelectionChanged(
@ -195,3 +213,9 @@ class MainActivity : SimpleActivity() {
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)
}
}
fun Bundle.printAllItems(where:String) {
for (key in keySet()) {
Log.e(where, "Item: key: $key - value: ${get(key)}")
}
}

View File

@ -1,9 +1,7 @@
package com.simplemobiletools.clock.activities
import android.content.Intent
import com.simplemobiletools.clock.helpers.OPEN_TAB
import com.simplemobiletools.clock.helpers.TAB_ALARM
import com.simplemobiletools.clock.helpers.TAB_CLOCK
import com.simplemobiletools.clock.helpers.*
import com.simplemobiletools.commons.activities.BaseSplashActivity
class SplashActivity : BaseSplashActivity() {
@ -18,6 +16,7 @@ class SplashActivity : BaseSplashActivity() {
intent.extras?.containsKey(OPEN_TAB) == true -> {
Intent(this, MainActivity::class.java).apply {
putExtra(OPEN_TAB, intent.getIntExtra(OPEN_TAB, TAB_CLOCK))
putExtra(TIMER_ID, intent.getLongExtra(TIMER_ID, INVALID_TIMER_ID))
startActivity(this)
}
}

View File

@ -134,7 +134,7 @@ class TimerAdapter(
fun updateAlarmSound(timer: Timer, alarmSound: AlarmSound) {
Log.w(TAG, "updateAlarmSound: $timer")
updateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri))
updateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri, channelId = null))
}
private fun updateTimer(timer: Timer, refresh: Boolean = true) {

View File

@ -1,5 +1,6 @@
package com.simplemobiletools.clock.adapters
import android.util.Log
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@ -53,4 +54,11 @@ class ViewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
fun updateTimerTabAlarmSound(alarmSound: AlarmSound) {
(fragments[TAB_TIMER] as? TimerFragment)?.updateAlarmSound(alarmSound)
}
private val TAG = "ViewPagerAdapter"
fun updateTimerPosition(timerId: Long) {
Log.e(TAG, "updateTimerPosition: $timerId")
(fragments[TAB_TIMER] as? TimerFragment)?.updatePosition(timerId)
}
}

View File

@ -13,6 +13,7 @@ import android.net.Uri
import android.os.PowerManager
import android.text.SpannableString
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.widget.Toast
import androidx.core.app.AlarmManagerCompat
import androidx.core.app.NotificationCompat
@ -20,6 +21,7 @@ import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.ReminderActivity
import com.simplemobiletools.clock.activities.SnoozeReminderActivity
import com.simplemobiletools.clock.activities.SplashActivity
import com.simplemobiletools.clock.activities.printAllItems
import com.simplemobiletools.clock.databases.AppDatabase
import com.simplemobiletools.clock.helpers.*
import com.simplemobiletools.clock.interfaces.TimerDao
@ -144,6 +146,7 @@ fun Context.getOpenTimerTabIntent(timerId: Long): PendingIntent {
val intent = getLaunchIntent() ?: Intent(this, SplashActivity::class.java)
intent.putExtra(OPEN_TAB, TAB_TIMER)
intent.putExtra(TIMER_ID, timerId)
intent.extras?.printAllItems("getOpenTimerTabIntent")
return PendingIntent.getActivity(this, TIMER_NOTIF_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
@ -260,7 +263,7 @@ fun Context.showAlarmNotification(alarm: Alarm) {
scheduleNextAlarm(alarm, false)
}
}
private const val TAG = "ALARMMMM"
@SuppressLint("NewApi")
fun Context.getTimerNotification(timer: Timer, pendingIntent: PendingIntent, addDeleteIntent: Boolean): Notification {
var soundUri = timer.soundUri
@ -270,9 +273,12 @@ fun Context.getTimerNotification(timer: Timer, pendingIntent: PendingIntent, add
grantReadUriPermission(soundUri)
}
Log.w(TAG, "getTimerNotification: timerSOUNDURI=${timer.soundUri}")
Log.w(TAG, "getTimerNotification: soundUri=${soundUri}")
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = config.timerChannelId ?: "simple_timer_channel_${soundUri}_${System.currentTimeMillis()}"
config.timerChannelId = channelId
val channelId = timer.channelId ?: "simple_timer_channel_${soundUri}_${System.currentTimeMillis()}"
timerHelper.insertOrUpdateTimer(timer.copy(channelId = channelId))
if (isOreoPlus()) {
try {

View File

@ -27,9 +27,10 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class TimerFragment : Fragment() {
private val INVALID_POSITION = -1
private lateinit var view: ViewGroup
private lateinit var timerAdapter: TimerAdapter
private var timerPositionToScrollTo = INVALID_POSITION
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -116,8 +117,13 @@ class TimerFragment : Fragment() {
activity?.timerHelper?.getTimers { timers ->
Log.d(TAG, "refreshTimers: $timers")
timerAdapter.submitList(timers) {
if (scrollToLatest) {
view.timer_view_pager.currentItem = 0
Log.e(TAG, "submitted list: timerPositionToScrollTo=$timerPositionToScrollTo")
if (timerPositionToScrollTo != INVALID_POSITION && timerAdapter.itemCount > timerPositionToScrollTo) {
Log.e(TAG, "scrolling to position=$timerPositionToScrollTo")
view.timer_view_pager.setCurrentItem(timerPositionToScrollTo, false)
timerPositionToScrollTo = INVALID_POSITION
} else if (scrollToLatest) {
view.timer_view_pager.setCurrentItem(0, false)
}
updateViews(timer_view_pager.currentItem)
}
@ -162,6 +168,25 @@ class TimerFragment : Fragment() {
}
}
fun updatePosition(timerId: Long) {
Log.e(TAG, "updatePosition TIMER: $timerId")
activity?.timerHelper?.getTimers { timers ->
val position = timers.indexOfFirst { it.id == timerId }
Log.e(TAG, "updatePosition POSITION: $position")
if (position != INVALID_POSITION) {
activity?.runOnUiThread {
if (timerAdapter.itemCount > position) {
Log.e(TAG, "updatePosition now: $position")
view.timer_view_pager.setCurrentItem(position, false)
} else {
Log.e(TAG, "updatePosition later: $position")
timerPositionToScrollTo = position
}
}
}
}
}
companion object {
private const val TAG = "TimerFragment"
}

View File

@ -45,7 +45,8 @@ const val TAB_CLOCK = 0
const val TAB_ALARM = 1
const val TAB_STOPWATCH = 2
const val TAB_TIMER = 3
const val TIMER_ID = "timer_position"
const val TIMER_ID = "timer_id"
const val INVALID_TIMER_ID = -1L
// stopwatch sorting
const val SORT_BY_LAP = 1

View File

@ -45,7 +45,8 @@ class TimerHelper(val context: Context) {
timerDao.insertOrUpdateTimer(
Timer(
id = null,
seconds = DEFAULT_TIME,
// seconds = DEFAULT_TIME,
seconds = 5,
TimerState.Idle,
false,
context.getDefaultAlarmSound(RingtoneManager.TYPE_ALARM).uri,

View File

@ -13,4 +13,5 @@ data class Timer(
val soundTitle: String,
val label: String,
val createdAt: Long,
val channelId: String? = null,
)

View File

@ -9,12 +9,14 @@ import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.extensions.getFormattedDuration
import com.simplemobiletools.clock.extensions.getOpenTimerTabIntent
import com.simplemobiletools.clock.extensions.timerHelper
import com.simplemobiletools.clock.helpers.INVALID_TIMER_ID
import com.simplemobiletools.clock.helpers.TIMER_RUNNING_NOTIF_ID
import com.simplemobiletools.clock.models.TimerEvent
import com.simplemobiletools.clock.models.TimerState
@ -39,7 +41,7 @@ class TimerService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
updateNotification()
startForeground(TIMER_RUNNING_NOTIF_ID, notification(getString(R.string.app_name), getString(R.string.timer_notification_msg), -1))
startForeground(TIMER_RUNNING_NOTIF_ID, notification(getString(R.string.app_name), getString(R.string.timer_notification_msg), INVALID_TIMER_ID))
return START_NOT_STICKY
}
@ -111,13 +113,18 @@ class TimerService : Service() {
.setAutoCancel(true)
.setChannelId(channelId)
if (firstRunningTimerId != -1L) {
if (firstRunningTimerId != INVALID_TIMER_ID) {
Log.e(TAG, "notification: Setting content intent for $firstRunningTimerId" )
builder.setContentIntent(this.getOpenTimerTabIntent(firstRunningTimerId))
}
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
return builder.build()
}
companion object {
private const val TAG = "TimerService"
}
}
@RequiresApi(Build.VERSION_CODES.O)