class AddContactDialogFragment(private val contactListFragment: ContactListFragment) : DialogFragment() {
private lateinit var binding: FragmentAddContactDialogBinding
private var alarmNumber: Int = 0
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAddContactDialogBinding.inflate(inflater, container, false)
return binding.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.saveBtn.setOnClickListener {
if (alarmNumber != 0) {
GlobalScope.launch {
when (alarmNumber) {
1 -> delay(5 * 1000)
2 -> delay(10 * 60 * 1000)
3 -> delay(30 * 60 * 1000)
}
notification()
}
}
val name = binding.NameEdit.text.toString()
val phoneNumber = binding.NumberEdit.text.toString()
val email = binding.EmailEdit.text.toString()
val contactManagerImpl: ContactManagerImpl = ContactManagerImpl.getInstance()
contactManagerImpl.createContact(name, phoneNumber, email, alarmNumber)
val updateContactList = contactManagerImpl.getContactList()
contactListFragment.adapter.setContactList(updateContactList)
dismiss()
}
}
fun notification() {
// 에러 - val manager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val builder: NotificationCompat.Builder
val name = binding.NameEdit.text.toString()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "one_channel"
val channelNAme = "My channer one"
val channel = NotificationChannel(
channelId,
channelNAme,
NotificationManager.IMPORTANCE_DEFAULT
).apply {
description = "My Channel One Description"
setShowBadge(true)
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM).build()
setSound(uri, audioAttributes)
enableVibration(true)
}
manager.createNotificationChannel(channel)
// 에러 - builder = NotificationCompat.Builder(this, channelId)
} else {
// 에러 - builder = NotificationCompat.Builder(this)
}
// 에러 - val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
// 에러 - val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
builder.run {
setSmallIcon(R.drawable.ic_launcher_foreground)
setWhen(System.currentTimeMillis())
setContentTitle("새로운 알림입니다.")
setContentText("$name 님에게 연락할 시간입니다.")
setContentIntent(pendingIntent)
setAutoCancel(true)
}
manager.notify(11, builder.build())
}
}
이렇게 다이얼로그 채널 생성과 pendingIntent, Intent를 사용해서 알림 메시지를 클릭하면 앱으로 갈 수 있도록 코드를 짜는 중, 에러가 발생했다. 에러난 코드는 전부 주석으로 처리했다.
에러를 해결하기 위해 머리를 싸매다가 결국은 같은 조 팀장님의 도움으로 해결했지만, 왜 되는지는 몰라서 오늘 코드를 복기하면서 다시 알아봤다.
fun notification() {
// val manager = binding.root.context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val builder: NotificationCompat.Builder
val name = binding.NameEdit.text.toString()
// SDK 26 version 이상
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "one_channel"
val channelNAme = "My channer one"
val channel = NotificationChannel(
channelId,
channelNAme,
NotificationManager.IMPORTANCE_DEFAULT
).apply {
description = "My Channel One Description"
setShowBadge(true)
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM).build()
setSound(uri, audioAttributes)
enableVibration(true)
}
manager.createNotificationChannel(channel)
// builder = NotificationCompat.Builder(binding.root.context, channelId)
} else {
// builder = NotificationCompat.Builder(binding.root.context)
}
// val intent = Intent(binding.root.context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
// val pendingIntent = PendingIntent.getActivity(binding.root.context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
builder.run {
setSmallIcon(R.drawable.ic_launcher_foreground)
setWhen(System.currentTimeMillis())
setContentTitle("새로운 알림입니다.")
setContentText("$name 님에게 연락할 시간입니다.")
setContentIntent(pendingIntent)
setAutoCancel(true)
}
manager.notify(11, builder.build())
}
우선은 수정된 코드고 똑같이 주석처리 해줬다. this -> binding.root.context 로 바꿔줬다. 우선 에러난 코드는 공통점이 있는데, this라는 키워드에서 발생했다. this는 현재 컨텍스트를 나타내는 키워드이고, 주로 현재 컨텍스트는 어떤 클래스나 액티비티의 메서드 안에서 사용된다.
binding.root 는 현재 프래그먼트의 view, context는 현재 컨텍스트를 나타낸다.
똑같은 거 아닌감.
생성자는 컨텍스트 형식을 필요로 하는데 this의 컨텍스트 형식이 달라서 발생한 오류다. 아니 this도 현재 컨텍스트라메?
알고보니 this는 클래스 내부에서 메서드나 프로퍼티를 호출할 때 현재 객체를 가리킨다. 하지만 확장 함수에선 확장 대상 객체를 가르키므로 지금 내가 작성한 코드에선 클래스 자체(AddContactDialogFragment)를 참조하고 있다는 걸 알게 되었다. 그래서 binding.root.context를 사용하여 해결~
다 쓰고나니 별거 없지만 앞으로도 트러블 슈팅에 관해서 자주 써야겠다라고 느낌.