이번 사이드 프로젝트로 잠금화면 앱을 만들어보면서, 알림을 잠금화면에 띄우는 기능을 만들어야했습니다.
안드로이드에서는 어떻게 알림을 가져올 수 있을까요?
NotificationListenerService
다행히 알림이 왔을때 시스템에서 호출받을 수 있는 서비스클래스가 존재합니다. 바로 NotificationListenerService입니다.
NotificationListenerService는 Service를 상속하고 있어서 사용을 위해서 Mainfest.xml에 등록해주는 과정이 필요합니다.
<service
android:name="com.knocklock.presentation.lockscreen.LockScreenNotificationListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
위와 같이 Mainfest.xml에서 service를 등록하고 intent-filter에 NotificationListenerService를 포함합니다.
또한 BIND_NOTIFICATION_LISTENER_SERVICE 권한을 부여해주는데, 이 권한은 앱에서 임의로 권한을 획득할 수 없고, 사용자가 설정에서 부여해줘야합니다.
따라서 다음과 같은 코드가 필요합니다.
// MainActivity
private fun permissionGranted() : Boolean{
val sets: Set<String> = NotificationManagerCompat.getEnabledListenerPackages(this)
return sets.contains(packageName)
}
NotificationManagerCompat.getEnabledListenerPackages(context: Context)는 알림 접근이 허용된 목록을 불러옵니다.
목록에는 알림 접근이 허용된 패키지들의 이름이 들어가고 있는데, 현재 실행하고 있는 앱이 존재하지 않는다면,false를 반환하여 권한을 설정할 수 있도록 설정 창으로 이동해줍니다.
if(!permissionGranted()){
val intent = Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"
)
startActivity(intent)
}
알림 접근 허용에서 허용 안된 현재 애플리케이션의 권한을 허용으로 바꿔주면서 이제 알림을 수신할 수 있습니다.
NotificationListenerService 구현
지금까지 사전작업이였다면 이제 Notification에서 내용물을 가져와 보겠습니다.
class LockScreenNotificationListener : NotificaionListenerService(){
override fun onNotificationPosted(sbn : StatusBarNotification?){
super.onNotificationPosted(sbn)
}
override fun onNotificationRemoved(sbn : StatusBarNotification?){
super.onNotificationPosted(sbn)
}
}
NotificationListenerService 클래스는 위의 두가지 메소드를 필수로 구현해야합니다.
각각 알림이 생성될때, 제거될 때 호출됩니다.
override fun onNotificationPosted(sbn: StatusBarNotification?) {
super.onNotificationPosted(sbn)
val packageName = sbn?.packageName
if (sbn != null && !TextUtils.isEmpty(packageName)) {
val notification: Notification = sbn.notification
val extras = notification.extras
val title = extras.getString(Notification.EXTRA_TITLE)
val text = extras.getString(Notification.EXTRA_TEXT)
val subText = extras.getString(Notification.EXTRA_SUB_TEXT)
val smallIcon = notification.smallIcon
val largeIcon = notification.getLargeIcon()
}
}
StatusBarNotification에서 notification을 얻을 수 있습니다.
notification의 extras에서는 알림의 제목, 텍스트, 서브 텍스트, 아이콘등을 얻을 수 있습니다.
또한 조건문에 필터를 추가해서 특정한 앱의 notification만을 수신할 수도 있습니다.
실제로 카카오톡 메시지가 오면 위의 그림과 같습니다. subText는 그룹 채팅방일 때 , 그룹채팅방이름으로 설정이 됩니다.
Tip!
저는 알림을 수신을 테스트하기 위해서, 알림이 가장 많이 올 수 있는 대화가 많은 오픈 채팅방에 들어가서 알림을 수신하고는 했었습니다. 하지만 터미널을 통해서 Notification을 생성할 수 있는 방법이 있습니다!
adb shell cmd notification post -S bigtext -t 'Title' 'Tag' 'Multiline text'
adb 명령어를 이용해서, Title과 내용(Multiline text)를 지정해서 Notification을 생성하면, 위에서 생성한 Listener를 통해서 내용을 가져올 수 있습니다.
이 방법을 통해서, 알림을 생성하고 디버깅을 할 수 있습니다.
Notification을 수신하면, 내부 RoomDatabase에 저장하고, 이를 관찰하여 View에 띄우는 동작입니다. 이렇게 알림 수신 테스트를 쉽게 할 수 있습니다.
마무리
지금까지 알림을 수신하는 방법을 알아보았는데요. 이미 구현된 클래스가 존재하여서 쉽게 구현을 해볼 수 있었습니다. 알림 수신을 완료헀으니.. 이제 잠금화면을 구현하는데 힘을 쏟아야할꺼 같습니다.!
'Android' 카테고리의 다른 글
Activity (0) | 2023.02.22 |
---|---|
Android에서 잠금화면 만들어보자 (0) | 2023.01.19 |
LiveData를 뜯어보자 (0) | 2022.11.23 |
Coroutine이 무엇일까요? (0) | 2022.11.10 |
Adapter Memory Leak (0) | 2022.05.31 |