[android] notification 누를 경우 fragment로 이동하기.

이유정·2022년 6월 29일
0

사용 방법 _ fcm에서 푸시알림을 처리하면서 notification 구현 시 이동 장소를 setContentIntent(pendingIntent)로 담는데, 이때 해당 intent에 putExtra로 플래그 값을 담아주고 이를 가지고 액티비티에서 판별해 프래그먼트로 이동시키기로 했다.

즉 push를 통해 mainActivity로 이동한 경우, 플래그 값을 보고 -> B fragment로 이동할지 말지를 결정하는 방식이다. (기본값은 A fragment)

이때, intent 관련하여 스택 문제를 해결하고자 했는데, 이미 앱의 메모리에 mainActivity가 쌓여있을 경우, 동일한 액티비티가 여러개 쌓이게 됨으로 이를 처리하기위해 manifest_launchMode에 값을 singleTask로 설정해주었다.

 <activity
            android:name=".ui.main.MainActivity"
            android:screenOrientation="portrait"
            android:exported="false"
            android:launchMode="singleTask"/>

android developer에서는 singleTask를 아래와 같이 설명하고 있다.

시스템이 새 작업을 생성하고 새 작업의 루트에 있는 활동을 인스턴스화합니다. 그러나 활동의 인스턴스가 이미 별도의 작업에 있다면 시스템은 새 인스턴스를 생성하지 않고 onNewIntent() 메서드를 호출하여 인텐트를 기존 인스턴스로 라우팅합니다. 활동의 인스턴스가 한 번에 하나만 존재할 수 있습니다.

즉 엑티비티 인스턴스가 이미 스택에 쌓여있을 경우 _ 중복으로 쌓이는 것을 방지하기 위해 기존의 액티비티를 다시 호출하되, onNewIntent()로 호출한다는 뜻이다.

그리고 onNewIntent에서는 아래와 같이 transaction_ replace를 이용해 이동했다.

override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        if (intent != null) {
            val push = intent.getBooleanExtra("pushPlan", false)
            if (push) {
            	//fragment로 이동
                supportFragmentManager.beginTransaction()
                    .replace(R.id.fcv_main, calFragment)
                    .addToBackStack(null)
                    .commit()
            }
        }
    }

이 경우 문제점이 하나 있었는데, 바로 앱의 메모리에 mainActivity 인스턴스가 있어야 onNewIntent를 호출하지, 아닐 경우 onCreate가 호출되어 onNewIntent에 처리해둔 로직을 거치지 않아 프래그먼트로 이동을 못한다는 것이었다.

때문에 onNewIntent의 내용을 함수로 빼두고 onNewIntent와 onCreate에서 각각 불러주어 처리하기로 하였다.

onCreate(대충 생략,,,){
	,,,
	isPushIntent(null)
}

onNewIntent(intent : Intent?){
	,,,
	isPushIntent(intent)
}

private fun isPushIntent(pushIntent : Intent?){

        val push = pushIntent?.getBooleanExtra("pushPlan", false) ?: let {
            intent.getBooleanExtra("pushPlan", false)
        }

		if (push) {
        	,,,
            
           supportFragmentManager.beginTransaction()
                .replace(R.id.fcv_main, calFragment)
                .addToBackStack(null)
                .commit()
        }
    }

플래그 값이 push는 onNewIntent로 들어올 경우, 매개변수인 pushIntent에서 값을 가져오고, onCreate로 들어온 경우는 activity를 시작한 intent에서 값을 가져온다

이럼 앱의 메모리 스택에 mainActivity가 있든 없든 fragment 호출 가능하다.

사실 이게 좋은 방법인지는 잘 모르겠다. navDeepLinkBuilder를 이용해 notification에 담는 pendingIntent 자체를 구성할 경우, pendingIntent에 앱의 특정위치를 담아 이동시킬 수 있다고 하는데, 현재 내가 개발 중인 앱의 경우 navigation을 구현해 탐색그래프를 그려두지 않았기 때문에 위와 같은 방법을 사용했다.

-> 나중에 더 좋은 방법을 찾아보기로.... && 글도 나중에 다듬기로...

profile
개인 공부 블로그

0개의 댓글