김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 원격저장소
  • ㄱ
  • KMU_WINK
  • GitHubDesktop
  • Remote저장소
  • 깃허브데스크탑
  • 로컬저장소
  • local저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제
•App/안드로이드 with Kotlin

[안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제

2022. 4. 3. 03:06

 

# 결과물 미리보기

TimePicker를 통해서 알람 시간을 설정할 수 있다. 알람 시간을 끝내면 등록된 알람이 메인화면에 뜨게되고, 알람 켜기를 누르면 알람이 작동한다. 해당시간이 되면 아래 와 같이 푸시알림이 온다. 단 엄청 정확한 시간에는 오지 않는다. 안드로이드는 자원 리소스의 낭비를 줄이기 위해서 AlarmManger의 경우 몇가지 제약을 걸어뒀는데 그 덕에 매초마다 확인하지 않는다. 실제로 테스트해본 결과 약 1분가량이 늦게 푸시알림이 왔다.

 

# 구현 순서

  1. [시간재설정] 버튼의 로직을 우선 구현했다.
    • TimePickerDialog를 통하여 TimePicker를 여는 행위를 정해줬다.
    • 시간을 등록하면 내가 정의한 TimeModel이 생성되고 SharedPreference로 저장된다.
    • 현재 등록 돼 있던 pendingIntent를 cancel시킨다.
  2. [알람 끄기] 버튼을 구현한다
    • 버튼에 tag에 모델을 저장시켜놨다가 가져온다, 가져오는 과정에서 as를 통해 확인 과정을 거친다
    • 가져온 모델을 newmodel로 만든 후 isOn을 반전시켜준 후 정의한 viewRender함수를 실행시킨다
    • 알람 등록과 알람끄기를 각각 정의한다
  3. BroadcastReceiver를 상속받은 AlarmReciver를 정의하여 onReceive일때 알림을 띄어주는 행동 정의

 

 

# 알게된 것

  • as
  • alarmManger
  • pendingIntent
  • tag

 

## as

이번에 강의를 들으면서 as 몇번 사용했다. 일단 추측으로는 as (오브젝트)로 사용하면 해당 객체로 바꾼다는 의미인거 같은데, 첫번째 코드에서는 it.tag가 TimeModel객체이면 TimeModel로 사용하고 아니면 return의 맥락으로 사용했다. 그래서 찾아 보았다.

// tag가 TimeModel이면 model변수에 저장 ( 객체의 형을 비교해봄)
val model = it.tag as? TimeModel ?: return@setOnClickListener
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

as는 TypeCasting즉 형변화를 해주는 것이었다. as 뒤에 지정한 Type(형)으로 변환시킨다. 그러나 지정한 Type으로 형변화를 할 수없다면 ClassCastException에러가 발생한다. 이걸 방지하기 위해서 as? 키워드를 사용한다. 그러면 형변화를 할 수 없을 시 null을 반환시킨다. 이걸 이용해서 첫번째처럼 형검사를 하고, null이라면 ?: 뒷구문이 실행 돼 return되는 것이다.

  • as -> 형변환, 실패시 ClassCastException에러
  • as? -> 형변환, 실패시 null 반환

 

### 함께 찾아본 is

자바에서 instanceof()와 같다고 한다. 데이터 형이 같은지 확인한다.

val num : Int = 100

if ( num is Int)  // True or False

### 함께 찾아본 Any

Any는 어떤 객체도 될 수 있다.

var a: Any = 100
a = 10F
a = "Hello, world!!"

 

## tag

onOffButton.tag = model
onOffButton.setOnClickListener { it ->
	val model = it.tag as? TimeModel ?: return@setOnClickListener
}

tag는 뭐 특별한게 없었다. tag는 Object타입이라 어떤 객체든지 담을 수 있다. 그렇기 때문에 model태그를 tag에 부착해줬다가 떼서 사용하는 것 같다. 또는 문자열도 되고 다 되는거 같았다.

 

## alarmManger

val calendar = Calendar.getInstance().apply {
    set(Calendar.HOUR_OF_DAY, newModel.hour)
    set(Calendar.MINUTE, newModel.minute)
}

val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(this, AlarmReciver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this,1000,intent,PendingIntent.FLAG_UPDATE_CURRENT)

alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.timeInMillis,AlarmManager.INTERVAL_DAY,pendingIntent)

Calendar를 통해서 내가 설정한 시간대를 가진 객체를 만들어 calendar변수에 저장시킨다. 이 변수에는 알람이 울린 시간정보가 들어있다.

alarmManager를 만들고 setInexactRepeating을 통해 해당시간에 알람이 울리게 하며, pendingIntent로 전달시킨다. Intent가 아닌 pendingIntent인 이유는 바로 Intent하지 않고 지정한 시간대에 Intent되기 때문이다. 공식문서랑 블로그를 뒤져봤는데 확 와닿지가 않긴하지만, 이렇게 이해하고 넘어갔다. 

알람이 시작되면 리시버로 전달되는 pendingIntent가 내가 정의했던 onReceive가 실행되며 알람을 보여주는 것 같다.

manifest에 리시버로 내가 생성한 알람리시버를 설정해줘야한다.

 

## pendingIntent <👩‍💻공부 필요👩‍💻>

매우 잘 정리해주셨다. 특정 시점에 intent를 실행하는 것인데, 그 특정시간대에는 다른 앱에서 Intent가 실행되고 있을 수 있다. 예를 들어 알림은 내가 다른앱을 사용중에 눌러서 들어가게 되는데 이런 경우를 처리하기 위함인것 같다. 이건 내가 확실히 이해 못했으니 정확한 정보는 아니다

 

[Android] PendingIntent 개념 익히기

'그냥 인텐트랑 뭐가 다른거지..' 하셨던 여러분들을 위해

velog.io

 

 

# 유용하게 사용 한 것

  • DataClass를 정의 한 후 property의 get()을 재정의하여 사용한 것
data class TimeModel(
    val hour: Int,
    val minute : Int,
    var isOn : Boolean = false
){
    val getStringHourMinute : String
        get(){
            return "$hour:$minute"
        }

    val getOnOffString : String
        get() {
            return (if (isOn) "알람 끄기" else "알람 켜기")
        }


    val timeText : String
        get(){
            val h = "%02d".format(if(hour<12) hour else hour -12)
            val m = "%02d".format(minute)

            return "$h:$m"
        }

    val ampmText: String
        get(){
            return if(hour < 12) "AM" else "PM"
        }

}

data class사용하면서 어떻게 써야하지라는 생각 많이 들었는데 이번에 써보면서 정말 정말 좋고 편리하다는 생각이 들었다!

 

# 느낀 점

 이번에는 정말로 거의 내 손으로 코드를 짰는데, 아쉽게도 pendingIntent, alarmManager가 잘 이해가 안됐다. 그래서 아쉬웠다. notification띄우는것도 저번에 했던거라서 이해 잘 갔는데.. 

 intent의 개념에 대해서 좀 깊게 공부해볼 필요가 있는거 같다.

context도 마찬가지이다.

with, run 이런것도 많이쓰는데 사실 큰 차이를 잘 모르겠다 ㅠ

 


 

반복 알람 예약  |  Android 개발자  |  Android Developers

반복 알람 예약 알람(AlarmManager 클래스 기반)을 사용하면 애플리케이션이 사용되지 않을 때 시간 기반 작업을 실행할 수 있습니다. 예를 들어, 알람을 사용하여 일기예보를 다운로드하는 것과 같

developer.android.com

 

저작자표시 (새창열림)

'•App > 안드로이드 with Kotlin' 카테고리의 다른 글

[안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#2, 어댑터에 버튼 구현하기, 인탠트로 모델 보내기, 안드로이드 Room DB 사용하기, Thread와 thread 차이  (2) 2022.04.07
[안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#1, retrofit,gson, DTO, glide, viewBinding, inflate, layoutinflate, RecyclerView  (0) 2022.04.04
[안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류  (0) 2022.03.31
[안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀, imeOptions  (0) 2022.03.28
[안드로이드&코틀린] 녹음기 만들기, Enum, set(value), run{...}, companion object, MediaRecorder, MediaPlayer, 커스텀 View 만들기  (0) 2022.03.25
    '•App/안드로이드 with Kotlin' 카테고리의 다른 글
    • [안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#2, 어댑터에 버튼 구현하기, 인탠트로 모델 보내기, 안드로이드 Room DB 사용하기, Thread와 thread 차이
    • [안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#1, retrofit,gson, DTO, glide, viewBinding, inflate, layoutinflate, RecyclerView
    • [안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류
    • [안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀, imeOptions
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바