20230908 troubleshooting

기메단·2023년 9월 8일
0

TIL

목록 보기
38/44

Problem

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를 사용하여 해결~

다 쓰고나니 별거 없지만 앞으로도 트러블 슈팅에 관해서 자주 써야겠다라고 느낌.

0개의 댓글