일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프래그먼트
- 막내의막무가내 프로그래밍
- 막내의 막무가내
- 막내의막무가내 플러터 flutter
- 2022년 6월 일상
- 막내의막무가내 안드로이드
- 막무가내
- 부스트코스에이스
- 막내의막무가내 플러터
- 막내의막무가내 안드로이드 코틀린
- 주택가 잠실새내
- 주엽역 생활맥주
- 안드로이드 sunflower
- 안드로이드 Sunflower 스터디
- 막내의막무가내 SQL
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 코볼 COBOL
- flutter network call
- 막내의막무가내
- 막내의 막무가내 알고리즘
- 막내의막무가내 코틀린
- Fragment
- 막내의막무가내 알고리즘
- 프로그래머스 알고리즘
- 막내의막무가내 rxjava
- 안드로이드
- 막내의막무가내 안드로이드 에러 해결
- 부스트코스
- 막내의막무가내 일상
- 막내의막무가내 목표 및 회고
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] 안드로이드 AlarmManager 와 WorkManager 사용하여 10분전 알림 만들기 본문
[안드로이드] 안드로이드 AlarmManager 와 WorkManager 사용하여 10분전 알림 만들기
막무가내막내 2020. 9. 2. 13:43
[2021-04-14 업데이트]
안녕하세요 AlarmManager 와 WorkManager 를 최근 프로젝트에서 사용해보았는데 간략하게 정리해보는 포스팅을 하려고합니다. ㅎㅎ
먼저 위 프로젝트에서 해당 코드들을 볼 수 있습니다.
[참고]
https://developer.android.com/guide/background?hl=ko
백그라운드 작업 처리시 안드로이드 개발자 문서에 적혀있듯이 다음과 같은 트리로 개발하면 됩니다.
즉시 실행해야한다 ? -> 코루틴, WorkManager
정확한 시간에 실행해야한다? -> AlaramManager
지연된 작업(Deferred)으로 실행해야한다? -> WorkManager
먼저 둘의 큰 차이점은 AlarmManager 는 정확한 시간을 지킨다는 것이고 WorkManager 는 Deffered 하다는 것인데 둘의 특성이 둘 다 필요해서 함께 사용해봤습니다. (주로 AlarmManager 는 말그대로 알람에, WorkManager 는 반드시 실행되거나 오래걸리는작업 등을 백그라운드에서 작업하기 위해 사용합니다. 예를 들면 이미지 업로드 등)
[ Dependency ]
// Work Manager
implementation "androidx.work:work-runtime-ktx:2.4.0"
[ 권한 ]
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
[ Manifest service 등록 ]
<service
android:name=".service.fcm.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver android:name=".service.notification.NotificationBroadcastReceiver" />
[ 알람매니저를 사용한 노티피케이션 등록 부분 ]
RTC_WAKEUP - 지정된 시간에 기기의 절전 모드를 해제하여 대기 중인 인텐트를 실행합니다
setsetAndAllowWhileIdle() - 도즈모드에서도 알림이 울릴 수 있게한다.
한 가지 주의할 점은 안드로이드의 배터리정책에 의해 9분간에 하나의 알림만 울릴 수 있다는 제한 사항이 있습니다.
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val alarmIntent =
Intent(context, NotificationBroadcastReceiver::class.java).let { intent ->
intent.putExtra(EXTRA_NOTIFICATION_TITLE, title)
intent.putExtra(EXTRA_NOTIFICATION_MESSAGE, message)
PendingIntent.getBroadcast(context, 0, intent, 0)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmMgr.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
원래타임스탬프 - TimeUnit.MINUTES.toMillis(10),// 10분전알림
alarmIntent
)
} else {
alarmMgr.setExact(
AlarmManager.RTC_WAKEUP,
원래타임스탬프 - TimeUnit.MINUTES.toMillis(10),// 10분전알림
alarmIntent
)
}
추가로 API 버전에 따라 다음 권한요청이 필요할 수 있습니다.
[ NotificationBroadcastReceiver ] - AlarmManager 부분
위 코드의 알람매니저 노티피케이션 전송을 수신할BroadcastReceiver 입니다. 받은 후 WorkManager 를 통해 알람을 등록합니다.
package com.mtjin.nomoneytrip.fcm
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.work.BackoffPolicy
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.mtjin.nomoneytrip.utils.EXTRA_NOTIFICATION_MESSAGE
import com.mtjin.nomoneytrip.utils.EXTRA_NOTIFICATION_TITLE
import java.util.concurrent.TimeUnit
class NotificationBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
intent?.let {
val title = it.getStringExtra(EXTRA_NOTIFICATION_TITLE).toString()
val message = it.getStringExtra(EXTRA_NOTIFICATION_MESSAGE).toString()
// Create Notification Data
val notificationData = Data.Builder()
.putString(EXTRA_NOTIFICATION_TITLE, title)
.putString(EXTRA_NOTIFICATION_MESSAGE, message)
.build()
// WorkManager 사용
val workRequest =
OneTimeWorkRequestBuilder<ScheduledWorker>()
.setInputData(notificationData)
.setBackoffCriteria(BackoffPolicy.LINEAR, 30000, TimeUnit.MILLISECONDS)
.build()
val workManager = WorkManager.getInstance(context)
workManager.enqueue(workRequest)
}
}
}
[ ScheduledWorker ] - WorkManager 부분
Worker 를 상속하여 WorkManager 를 만들어줍니다. 파라미터를 전달받을 수 도 있고 백그라운드로 작업이 진행됩니다.
package com.mtjin.nomoneytrip.fcm
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.mtjin.nomoneytrip.utils.EXTRA_NOTIFICATION_MESSAGE
import com.mtjin.nomoneytrip.utils.EXTRA_NOTIFICATION_TITLE
import com.mtjin.nomoneytrip.utils.NotificationUtil
class ScheduledWorker(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {
override fun doWork(): Result {
// Get Notification Data
val title = inputData.getString(EXTRA_NOTIFICATION_TITLE).toString()
val message = inputData.getString(EXTRA_NOTIFICATION_MESSAGE).toString()
// FCM 전송
NotificationUtil(applicationContext).showNotification(
title,
message
)
return Result.success()
}
}
WorkManager 관련 설명은 다음 링크에서 추가로 보실 수 있습니다. (이 포스팅에서는 생략을 했습니다.)
youngest-programming.tistory.com/361
댓글과 공감은 큰 힘이 됩니다. 감사합니다 !!
[개인 기록 샘플]
Remote쪽에서 예약전날 알림과 예약종료날 리뷰알림 관련 코드입니다.
리모트 쪽에서 이 함수를 통해 바로 WorkManager로는 예약종료날 리뷰알림을 AlarmManager + WorkManager 로는 예약전날 알림을 구현합니다.
override fun sendNotification(reservation: Reservation, product: Product) {
val title = product.title
val message = convertTimeToFcmMessage(
date = reservation.startDateTimestamp,
time = product.checkIn
)
val startScheduledTime = reservation.startDateTimestamp
val endScheduledTime = reservation.endDateTimestamp
val timeDiff = endScheduledTime + TimeUnit.HOURS.toMillis(18) - System.currentTimeMillis()
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val startAlarmIntent =
Intent(context, NotificationBroadcastReceiver::class.java).let { intent ->
intent.putExtra(EXTRA_NOTIFICATION_TITLE, title)
intent.putExtra(EXTRA_NOTIFICATION_MESSAGE, message)
intent.putExtra(EXTRA_NOTIFICATION_MESSAGE, message)
PendingIntent.getBroadcast(context, 0, intent, 0)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmMgr.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
startScheduledTime - TimeUnit.HOURS.toMillis(11),// 전날알림(13시)
startAlarmIntent
)
} else {
alarmMgr.setExact(
AlarmManager.RTC_WAKEUP,
startScheduledTime - TimeUnit.HOURS.toMillis(11),// 전날알림(13시)
startAlarmIntent
)
}
//종료날 리뷰요청
val notificationData = Data.Builder()
.putString(EXTRA_NOTIFICATION_TITLE, title)
.putString(EXTRA_NOTIFICATION_MESSAGE, "여행은 어떠셨나요? 리뷰를 남겨주세요 :)")
.build()
val workRequest =
OneTimeWorkRequestBuilder<ScheduledWorker>()
.setInputData(notificationData)
.setInitialDelay(timeDiff, TimeUnit.MILLISECONDS) // 18시 알림
.setBackoffCriteria(BackoffPolicy.LINEAR, 30000, TimeUnit.MILLISECONDS)
.build()
val workManager = WorkManager.getInstance(context)
workManager.enqueue(workRequest)
}
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
[안드로이드] Android Tmap 사용법 간략 정리(feat 지도위치, 마커, 길찾기) (0) | 2020.09.07 |
---|---|
[안드로이드] 새로운 저장소 Jetpack DataStore (feat. Sharedpreferences 를 대체) (2) | 2020.09.03 |
[안드로이드] 안드로이드 이중 어댑터(이중 리사이클러뷰) 구현 메모 (feat. 데이터바인딩) (0) | 2020.08.31 |
[안드로이드] 한국관광공사 API Service key error 처리 (SERVICE KEY IS NOT REGISTERED ERROR) (0) | 2020.08.30 |
[안드로이드] 데이터바인딩 xml onclick 한글 파라미터 오류 해결 (2) | 2020.08.29 |