사내 프로젝트에서 FCM을 활용하여 Push 알림을 보내고,
PendingIntent로 알림 클릭에 대한 동작을 구현하던 중 공부했던 내용을 포스팅한다.
문제 상황
Notification의 PendingIntent를 활용할 때, 가장 머리가 아팠던 부분은
기기에서 앱의 현재 상태에 따라서 각기 다른 Intent가 동작되어야 한다는 것이었다.
고려해야 할 상태는 대략적으로 다음과 같았다.
✅ 앱이 구동 중이 아닐 때
✅ 앱이 구동 중일 때 + 현재 사용자에게 보여지는 화면에 따라 다른 동작을 실행
- 최상위 액티비티를 파악
- 프래그먼트를 다룬다면, 현재 화면에 띄워진 프래그먼트 파악
문제 해결 방법
✅ 앱이 구동 중인지 아닌지를 구분하는 방법
val process = RunningAppProcessInfo()
ActivityManager.getMyMemoryState(process)
Log.d(TAG, "FCM 수신 시 앱 상태값 : ${process.importance}")
RunningAppProcessInfo, ActivityManager 클래스를 이용하여 확인할 수 있었다.
지난 포스팅에서 세팅했던대로 기기에 FCM을 송신하고,
수신 대기 상태에서 RunningAppProcessInfo 클래스의 importance 로그를 찍어본다.
총 3개의 상황을 테스트했으며 순서는 다음과 같다.
1. 앱을 사용 중일 때 : 100
2. 기기의 홈 버튼을 눌러서 앱 밖으로 이동했을 때 (앱 종료 X) : 300
3. 앱을 종료했을 때 : 300
앱을 종료했던, 안 했던 일단 사용자가 앱을 벗어나면 300이라는 값이 출력되는 것을 알 수 있다.
그리고 이 값은 ActivityManager에서 확인할 수 있었다.
ActivityManager.class
300은 Service 상태이고, 100은 Foreground 상태라는 것을 알 수 있다.
그렇기에 위 상수를 사용하여 다음과 같이 처리해줄 수 있었다.
val process = RunningAppProcessInfo()
ActivityManager.getMyMemoryState(process)
when (process.importance) {
RunningAppProcessInfo.IMPORTANCE_SERVICE -> // 앱 사용 중 X
RunningAppProcessInfo.IMPORTANCE_FOREGROUND -> // 앱 사용 중 O
...
}
✅ 앱이 구동 중일 때, 화면에 보여지는 액티비티를 확인하는 방법
val manager = application.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
Log.d(TAG, "FCM 수신 시 현재 액티비티 (패키지명 포함) : ${manager.appTasks[0].taskInfo.topActivity?.className}")
Log.d(TAG, "FCM 수신 시 현재 액티비티 (패키지명 제외) : ${manager.appTasks[0].taskInfo.topActivity?.shortClassName}")
이전 예제와 비슷하게, ActivityManager 클래스를 사용한다.
앱을 실행 후 메인 액티비티에서 FCM을 수신할 때 로그를 찍어보았다.
className과 shortClassName 2가지를 출력했다.
각자 편한 방법으로 다음과 같이 응용해주면 된다.
when (manager.appTasks[0].taskInfo.topActivity?.className) {
"abled.oscar.test.activity.MainActivity" -> {}
else -> {}
}
현재 최상위 액티비티를 조건으로 동작을 분류할 수 있다.
✅ 현재 화면에 띄워진 프래그먼트를 확인하는 방법
supportFragmentManager.fragments[0].javaClass.simpleName
supportFragmentManager를 사용하여 최상위 프래그먼트를 확인할 수 있다.
간단하게 2개의 프래그먼트를 만들어서 replace() 후 확인해보자.
버튼을 누르면 해당 프래그먼트로 전환되게끔 세팅해주고,
FragmentOnAttachListener를 사용해서 프래그먼트가 전환되면 현재 프래그먼트를 출력했다.
supportFragmentManager.addFragmentOnAttachListener { fragmentManager, fragment ->
Log.d(TAG, "프래그먼트 변경됨 : ${fragment.javaClass.simpleName}")
}
결과)
현재 표시되는 프래그먼트를 확인할 수 있다.
대략적인 앱의 상태를 확인하는 방법을 간단히 알아보았다.
정말 예외 처리할 게 너무 많은 것 같다..