20230905 PendingIntent

기메단·2023년 9월 5일
0

TIL

목록 보기
35/44

PendingIntent

PendingIntent

Intent를 가지고 있는 클래스로서 다른 앱이 프로세슬르 점유하고 있을 때 실행 시킬 수 있다.
Notification, 런처 위젯, AlarmManager에서의 Intent 작업 수행 시 사용한다. 

어제 만든 다이얼에서 각 시간에 맞춰 알림을 보내고, 알림 클릭 시 다시 앱으로 돌아올 수 있게 할 것이다.
우선 pendingIntent을 설명하자면,

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())
activity를 시작하는 intent : PendingIntent.getActivity(context, Int, Intent, flag)
falg의 종류 :

FLAG_CANCEL_CURRENT : 이전 생성되어 있는 것을 생성하기 전에 
					 취소하고 새롭게 생성하는 FLAG
    
FLAG_IMMUTABLE : 생성된 인텐트를 변경할 수 없음을 나타내는 FLAG

FLAG_MUTTABLE : 생성된 인텐트가 변경 가능함을 나타내는 FLAG
    
FLAG_ONE_SHOT : 이 Intent는 일회성으로 생성하는 FLAG

FLAG_NO_CREATE : 생성된 Intent가 아직 존재하지 않는 경우 
				생성하는 대신 null을 반환하는 FLAG

FLAG_UPDATE_CURRENT : 생성된 Intent 이미 존재하면 이를 유지하되 추가 데이터를 
					새 Intent에 있는 것으로 대체하는 FLAG

DiaglogFragment


class AddContactDialogFragment : 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.cancelBtn.setOnClickListener {
           dismiss()
       }

       binding.saveBtn.setOnClickListener {

           // EditText창에 입력된 텍스트를 가져옴
           val name = binding.NameEdit.text.toString()
           val phoneNumber = binding.NumberEdit.text.toString()
           val email = binding.EmailEdit.text.toString()
           val alarm = 0

           // ContactManagerImpl 클래스의 싱글톤 객체를 가져옴
           val contactManagerImpl: ContactManagerImpl = ContactManagerImpl.getInstance()
           // 가져온 객체를 이용해서 새로운 데이터 생성
           contactManagerImpl.createContact(name, phoneNumber, email, alarm)
           dismiss()
       }

		// off 버튼의 값은 0 
       binding.offbtn.setOnClickListener {
           setButtonState(binding.offbtn)
           alarmNumber = 0
       }
       
		// 5분 버튼의 값은 1 
       binding.fivebtn.setOnClickListener {
           setButtonState(binding.fivebtn)
           alarmNumber = 1
       }

		// 10분 버튼의 값은 2 
       binding.tenBtn.setOnClickListener {
           setButtonState(binding.tenBtn)
           alarmNumber = 2
       }

		// 30분 버튼의 값은 3
       binding.thirtyBtn.setOnClickListener {
           setButtonState(binding.thirtyBtn)
           alarmNumber = 3
       }

       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()
               }
           }
           dismiss()
       }
   }

   fun notification() {
       val manager = binding.root.context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
       val builder: NotificationCompat.Builder
       // Edit 텍스트에 작성되는 이름을 가지고 옴.
       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())
   }

1개의 댓글

comment-user-thumbnail
2023년 9월 6일

와.. 코드가 날이 가면 갈수록 점점 더 깔끔해지시는 것 같아요😃

답글 달기