Skip to content

배토의 개발일지

나를위한 단편적 기억들의 기록

Menu
  • 안드로이드
  • 코틀린
  • Godot
  • 블렌더
  • git
  • 게임제작일지
  • 기타
Menu

DeskClock 코드분석 #2 : App과 Notificaiton 전환

Posted on 2023년 6월 8일 by batmask

메인 Activity인 DeskClock 에서 onStart() -onStop() 부분을 보면 isApplicationInForeground로 앱이 현재 포그라운드 상태인지 플래그를 변경해주고 있다.

override fun onStart() {
...
    DataModel.dataModel.isApplicationInForeground = true
}

override fun onStop() {

...
        DataModel.dataModel.isApplicationInForeground = false

...
}

DataModel 의 isApplicationInForegound를 보면, NotificationModel.isApplicationInForeground를 참조하고 있음을 알 수 있다. 그리고 값을 설정하는 경우, TimerModel의 updateNotification()을 불러준다.

var isApplicationInForeground: Boolean
    /**
        * @return `true` when the application is open in the foreground; `false` otherwise
        */
    get() {
        ...
        return mNotificationModel!!.isApplicationInForeground
    }
    /**
        * @param inForeground `true` to indicate the application is open in the foreground
        */
    set(inForeground) {
        if (mNotificationModel!!.isApplicationInForeground != inForeground) {
            mNotificationModel!!.isApplicationInForeground = inForeground

            // Refresh all notifications in response to a change in app open state.
            mTimerModel!!.updateNotification()
            mTimerModel!!.updateMissedNotification()
            ...
        }
    }

TimerModel의 updateNotification()을 살펴보면, TimerModel이 가지고 있는 타이머 목록인 mutableTimers에서 실행중이거나 일시정지된 타이머들을 unexpired 리스트에 추가한다. 즉, 현재 동작중인 타이머들을 가지고 NotificationBuilder.build()를 이용하여 Notification을 만들고 띄워주게 된다. 동일한 코드내에서, 동작중인 타이머가 없거나 앱이 포그라운드 상태이면 Notification을 cancel하여 없애준다.

fun updateNotification() {
    // Filter the timers to just include unexpired ones.
    val unexpired: MutableList<Timer> = mutableListOf()
    for (timer in mutableTimers) {
        if (timer.isRunning || timer.isPaused) {
            unexpired.add(timer)
        }
    }

    // If no unexpired timers exist, cancel the notification.
    if (unexpired.isEmpty()) {
        if(mNotificationBuilder.isChannelCreated(mNotificationManager)) {
            LogUtils.i("Cancelling Notifications when list is empty")
            mNotificationManager.cancel(mNotificationModel.unexpiredTimerNotificationId)
        }
        return
    }

    // Sort the unexpired timers to locate the next one scheduled to expire.
    unexpired.sortWith(Timer.EXPIRY_COMPARATOR)

    //Build and setup a channel for notifications
    LogUtils.i("Channel being setup!!!!")
    // Otherwise build and post a notification reflecting the latest unexpired timers.
    val notification: Notification =
            mNotificationBuilder.build(mContext, mNotificationModel, unexpired)
    val notificationId = mNotificationModel.unexpiredTimerNotificationId
    mNotificationBuilder.buildChannel(mContext, mNotificationManager)

    // Notifications should be hidden if the app is open.
    if (mNotificationModel.isApplicationInForeground) {
        if(mNotificationBuilder.isChannelCreated(mNotificationManager)) {
            LogUtils.i("Cancelling notifications when the app is in foreground")
            mNotificationManager.cancel(mNotificationModel.unexpiredTimerNotificationId)
        }
        return
    }
    
    mNotificationManager.notify(notificationId, notification)
}

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

최신 글

  • Blender : snap을 써서 다른 vertex에 정렬하기
  • KTor Client 기본 사용 정리
  • 게임 만들거다.
  • Using Koin with Android Compose

보관함

2023 6월
일 월 화 수 목 금 토
 123
45678910
11121314151617
18192021222324
252627282930  
« 10월   7월 »

메타

  • 로그인
  • 엔트리 피드
  • 댓글 피드
  • WordPress.org
©2025 배토의 개발일지 | Built using WordPress and Responsive Blogily theme by Superb