Notice
Recent Posts
Recent Comments
Link
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- errorhandling
- androidstudio
- 일본어문법
- 책리뷰
- rxjava
- suspend
- github
- n3문법
- CustomTab
- 진짜일본어
- KotlinInAction
- 책추천
- Android
- 진짜학습지후기
- posting
- 일본어기초
- Kotlin
- ai
- GIT
- pullrequest
- 학습지
- 진짜학습지
- webflux
- 코틀린
- jlpt
- 인공지능
- blog
- PR
- 안드로이드
- coroutine
Archives
코딩하는 개굴이
[안드로이드] Local Notification 매일 특정 시간에 보내기 본문
반응형
[안드로이드] Local Notification 매일 특정 시간에 보내기
Gradle 설정
dependencies {
//androidx
implementation 'androidx.core:core-ktx:1.7.0' // 노티피케이션을 위한 패키지
....
}
Manifest 설정
Manifest에 AlarmReceiver 를 등록한다.
안드로이드는 부팅이 끝나면 'BOOT_COMPLETED' 인 intent를 브로드캐스트 한다.
PendingIntent를 이용해 Notification을 사용할 경우, 재부팅 후에는 해당 설정이 증발한다. 따라서, 재부팅 후에도 PendingIntent 가 남아있도록 하려면, Manifest에 부팅 시, BroadCast 를 실행하도록 BOOT_COMPLETED 설정이 필요하다.
<application
android:name=".SampleApplication"
...
>
...
<receiver android:name=".AlarmReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
Application
Application 에 alarmManager 를 등록하였지만, MainActivity 등, 실제 사용하는 곳에서 선언하여도 무방하다.
internal var alarmManager: AlarmManager? = null
class SampleApplication : Application() {
...
MainActivity
MainActivity 에서 alarmManager를 할당한다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager?
}
AlarmReceiver
Oreo 이후에는 NotificationChannel 을 생성해야한다.
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import com.sample.sampleapp.presentation.MainActivity
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
createNotificationChannel(context)
deliverNotification(context)
}
private fun createNotificationChannel(context: Context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
CHANNEL_ID, // 채널의 아이디
CHANNEL_NAME, // 채널의 이름
NotificationManager.IMPORTANCE_HIGH
/*
1. IMPORTANCE_HIGH = 알림음이 울리고 헤드업 알림으로 표시
2. IMPORTANCE_DEFAULT = 알림음 울림
3. IMPORTANCE_LOW = 알림음 없음
4. IMPORTANCE_MIN = 알림음 없고 상태줄 표시 X
*/
)
notificationChannel.enableLights(true) // 불빛
notificationChannel.lightColor = R.color.accentNormal // 색상
notificationChannel.enableVibration(true) // 진동 여부
notificationChannel.description = context.getString(R.string.app_name) // 채널 정보
notificationManager?.createNotificationChannel(
notificationChannel)
}
}
private fun deliverNotification(context: Context){
val contentIntent = Intent(context, MainActivity::class.java)
val contentPendingIntent = PendingIntent.getActivity(
context,
NOTIFICATION_ID, // requestCode
contentIntent, // 알림 클릭 시 이동할 인텐트
PendingIntent.FLAG_UPDATE_CURRENT
/*
1. FLAG_UPDATE_CURRENT : 현재 PendingIntent를 유지하고, 대신 인텐트의 extra data는 새로 전달된 Intent로 교체
2. FLAG_CANCEL_CURRENT : 현재 인텐트가 이미 등록되어있다면 삭제, 다시 등록
3. FLAG_NO_CREATE : 이미 등록된 인텐트가 있다면, null
4. FLAG_ONE_SHOT : 한번 사용되면, 그 다음에 다시 사용하지 않음
*/
)
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground) // 아이콘
.setContentTitle("알람이개굴") // 제목
.setContentText("알람 내용이개굴") // 내용
.setContentIntent(contentPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setDefaults(NotificationCompat.DEFAULT_ALL)
notificationManager?.notify(NOTIFICATION_ID, builder.build())
}
companion object {
private const val NOTIFICATION_ID = 0
private const val CHANNEL_ID = "channel_id"
private const val CHANNEL_NAME = "ChannelName"
}
}
Set/Cancel Alarm
Cancel 할 경우와 Set 할 경우에 해당한다.
매일 일정 시각에 알람을 반복을 위해서는 alarmManager.setRepeating에서 AlarmManager.INTERVAL_DAY
를 설정한다.
private fun cancelAlarm() {
val receiverIntent = Intent(getApplication<Application>(), AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(getApplication<Application>(), 0, receiverIntent, 0)
alarmManager?.cancel(pendingIntent)
}
private fun setAlarm(hour: Int, minute: Int) {
//옵션값에 따라서, 푸시 설정이 되지 않을 수 있도록 함
if (!pushAvailable.value) return
//AlarmReceiver에 값 전달
val receiverIntent = Intent(getApplication<Application>(), AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(getApplication<Application>(), 0, receiverIntent, 0)
//alarm 등록 전, 이전 push cancel
alarmManager?.cancel(pendingIntent)
// Set the alarm to start at time and minute
val calendar: Calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minute)
set(Calendar.SECOND, 0)
}
if (calendar.time < Date()) { //설정한 시간에 따라, 알람이 설정이 안될 수 있으므로 달 첫번째 부터의 시간을 설정
calendar.add(Calendar.DAY_OF_MONTH, 1)
}
alarmManager?.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
}
참고 링크
- https://webnautes.tistory.com/665
- https://hanyeop.tistory.com/217
- https://always-21.tistory.com/4
- https://developer.android.com/training/scheduling/alarms?hl=ko#cancel
- https://dhanush-ramuk.medium.com/my-horrible-experience-with-androids-alarmmanager-96a9dfc14d9
- https://ddolcat.tistory.com/341
- https://stackoverflow.com/questions/33055129/how-to-show-a-notification-everyday-at-a-certain-time-even-when-the-app-is-closes
반응형
'안드로이드' 카테고리의 다른 글
[안드로이드] Fastlane과 GitHub Action을 이용한 자동 배포 시스템 구축하기 - Fastlane 배포 설정 (1) (0) | 2022.05.01 |
---|---|
[안드로이드] Could not connect to remote process. Aborting debug session. 해결법 (0) | 2022.03.09 |
[안드로이드] Fastlane으로 Firebase에 Android 앱 배포하기 (0) | 2021.03.21 |
[안드로이드] Firebase 적용하기 (0) | 2021.03.13 |
[안드로이드] 의존성 주입 (DI) 란? (0) | 2021.03.13 |
Comments