본문 바로가기
안드로이드

[Android] FCM foreground notification

by Banlim 2020. 12. 2.

[삽질의 기록]

 

Android에서 Firebase Messaging Service를 이용하여 Push notificiation 기능을 구현했다.

앱이 현재 실행 중인 상태가 아닐 때에는 디바이스의 상태표시줄에 푸시 알림이 잘 동작했다.

하지만, 앱이 실행 중인 상태에서 FCM 기능을 사용하고 싶었다.

 

보통 Application은 누군가가 댓글을 남긴다거나, 좋아요를 누르면 해당 게시글을 올린 사람에게 푸시 알림을 보낼 수 있다. 카카오톡도 마찬가지로 상대방으로부터 메시지가 오면 메시지가 왔다는 푸시알림과 어느 채팅방에 메시지가 왔는지 빨간색 동그라미 나타내어 메시지가 왔다는 표시를 한다.

 

이처럼, Firebase를 사용하여 알림이 오면 해당 버튼 이미지에 빨간색 동그라미를 나타내는, 즉 알림메시지를 감지하는 것을 앱 실행중에 사용하기 위해 다음과 같은 작업을 진행했다.

 

우선, 앱 실행 중에 FCM을 사용하기 위해 AndroidManifest 파일에 다음과 같은 코드를 삽입한다. 

아래 코드는 FCM을 Foreground에서도 사용할 수 있도록 만들어주는 코드이다.

 

AndroidManifest.xml

<service
   android:name=".MyFirebaseMessagingService"
   android:exported="true">
   <intent-filter>
       <action android:name="com.google.firebase.MESSAGING_EVENT" />
   </intent-filter>
</service>

 

다음으로, FirebaseMessagingService class를 상속받는 새로운 class를 생성한다.

해당 class를 상속받으면, onMessageReceived라는 함수를 override 할 수 있다.

이 함수 내에 remoteMessage.getNotification()null을 반환하지 않으면, 푸시 알림이 왔다는 뜻이다.

null을 반환하지 않을 때 새로운 Intent를 생성한 후, Action을 "com.package.notification"으로 세팅한다.

이후 intent를 broadcast로 보낸다.

 

ForegroundFCMService.java

public class ForegroundFCMService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if(remoteMessage.getNotification() != null){
            Intent intent = new Intent();
            intent.setAction("com.package.notification");
            sendBroadcast(intent);
        }
        else{
            Log.d(TAG, "getNotification null");
        }
    }

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
    }
}

 

이렇게 notification intent를 broadcast를 통해 보내면 그걸 받을 activity가 있어야 한다.

나의 Application의 경우 알림이 오면 이전에 지정한 아이콘 위에 빨간색 동그라미를 표시하는 기능을 구현하려고 했었으며, 이 아이콘이 MainActiviy에 위치했다.

따라서 MainActiviy에 아래와 같은 함수를 구현한다.

 

MainActivity.java

private BroadcastReceiver receiver;

private void startRegisterReceiver(){
   if(!mIsReceiverRegistered){
    	if(receiver == null){
            receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
            	notify_icon.setVisibility(View.VISIBLE);
            }
        };
    }
    registerReceiver(receiver, new IntentFilter("com.package.notification"));
    mIsReceiverRegistered = true;
    }
}

private void finishRegisterReceiver(){
    if(mIsReceiverRegistered){
    	unregisterReceiver(receiver);
        receiver = null;
        mIsReceiverRegistered = false;
    }
}

private void pauseRegisterReceiver(){
    if(mIsReceiverRegistered){
    	mIsReceiverRegistered = false;
    }
}

startRegisterReceiver() 함수에서는 현재 등록되어있는 receiver가 없으면, 새로운 BroadcastReceiver를 생성하고, override된 onReceive() 함수에 빨간색 동그라미 표시하라는 코드를 작성했다.

broadcastReceiver를 생성한 후, registerReceiver() 메소드를 사용하여 receiver를 등록한다.

여기서, 특정 액션인 notification에 대한 것에 관심이 있으므로, intentFilter 메소드로 notification임을 알려준다.

 

finishRegisterReceiver() 함수에서는 등록했던 receiver를 등록 해제하는 기능을 수행한다.

 

pauseRegisterReceiver() 함수에서는 등록했던 receiver를 등록 해제하지 않고, MainActivity가 아닌 다른 Activity를 실행중일 때, 알림이 올 경우를 생각하여 구현했다.

 

이렇게 3가지의 메소드를 구현한 후 이 메소드를 다음 코드와 같이 삽입한다.

 

MainActivity.java

@Override
protected void onResume(){
    super.onResume();
    startRegisterReceiver();
}

@Override
protected void onPause(){
    super.onPause();
    pauseRegisterReceiver();
}

@Override
protected void onDestroy(){
    super.onDestory();
    finishRegisterReceiver();
}

@Override
protected void onStart(){
    super.onStart();
    startRegisterReceiver();
}

 

이렇게 기능을 구현하면 FCM을 Foreground에서 푸시 알림이 오면 카카오톡과 흡사하게 빨간색 동그라미로 노티를 표현할 수 있게 된다.