ReactNative - [android] 알림 배지 수정

nueiin·2024년 2월 23일

React Native

목록 보기
6/7

1. 서론

알림 창에 표시된 알림을 보여주고, 알림 수신 시 채팅방마다 최근에 수신한 한 개의 메시지에 대한 알림만 보여주기 때문에 앱 알림 뱃지 갯수와 실제 알림 갯수가 달라서 수정이 필요했다.

2. 해결

2.1 android

notifee에서 안드로이드 앱 뱃지의 알림 개수를 수정해주는 메소드가 없었기에 구현이 필요했다.
다른 모듈들도 최신에 업데이트가 진행된 것들은 없었어서 선택권이 없었다. (대부분 6년 전이 마지막 업데이트..)
ios와 마찬가지로 알림이 올 때마다 채팅리스트와 토픽리스트의 알림 개수를 구해서 더해준 후, 안드로이드 알림 배지 설정을 바꿔준다.
❗ 주의 setNumber로 알림 개수만 바꿔주고싶었으나, 알림 개수를 바꾸려면 기기에 알림을 전송해주어야만 바꿀 수 있다고 한다.
따라서, 가장 최신의 알림 id를 이용하여 알림 정보를 그대로 업데이트를 해주면 된다.


// ReactWrapperModule.java
package com.example.nueiin;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;

import com.facebook.react.bridge.ReactMethod;
import android.widget.Toast;

import android.os.Build;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.content.Context;

import android.service.notification.StatusBarNotification;

import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableNativeArray;

public class ReactWrapperModule extends ReactContextBaseJavaModule {
    
    private static final String PRIMARY_CHANNEL_ID = "채널 id";
    private NotificationManagerCompat mNotificationManager;
    private final ReactApplicationContext reactContext;
    
    ReactWrapperModule(ReactApplicationContext context) {
        super(context);
        this.reactContext = context;
        createNotificationChannel();
    }

    @NonNull
    @Override
    public String getName() {
        return "ReactWrapperModule";
    }

    @ReactMethod
    public void showToast(String message) {
        Toast.makeText(reactContext, message, Toast.LENGTH_SHORT).show();
    }

    @ReactMethod
    public void setCount(int number) {
        WritableArray info = getInfo();
        
        int id = info.getInt(0);
        String title = info.getString(1);
        String text = info.getString(2);

        NotificationCompat.Builder notifyBuilder = getNotificationBuilder(number, title, text);
        mNotificationManager.notify(id, notifyBuilder.build());
    }

	// statusbar에 표시되어있는 알림 중 최신 알림의 정보 가져오기
    public WritableArray getInfo() {
        NotificationManager notificationManager = (NotificationManager) reactContext.getSystemService(Context.NOTIFICATION_SERVICE);
        StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications();

        int id = activeNotifications[0].getId();
        String title = activeNotifications[0].getNotification().extras.getCharSequence(NotificationCompat.EXTRA_TITLE).toString();
        String text = activeNotifications[0].getNotification().extras.getCharSequence(NotificationCompat.EXTRA_TEXT).toString();

        WritableArray resultArray = new WritableNativeArray();
        resultArray.pushInt(id);
        resultArray.pushString(title);
        resultArray.pushString(text);

        return resultArray;
    }

	// 알림을 만들어주는 메소드
    private NotificationCompat.Builder getNotificationBuilder(int number, String title, String text) {
        NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(reactContext, PRIMARY_CHANNEL_ID)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setColor(0xFF5E9441)
                .setSilent(true)	// 배너를 띄우지 않고 업데이트를 해주기 위함
                .setNumber(number);
        return notifyBuilder;
    }

    // Notification Channel을 생성하는 메소드
    private void createNotificationChannel() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                PRIMARY_CHANNEL_ID,
                "채널이름",
                NotificationManager.IMPORTANCE_HIGH
            );
            NotificationManager notificationManager = reactContext.getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
            mNotificationManager = NotificationManagerCompat.from(reactContext);
        }
    }

}

// ReactWrapperPackage.java
package com.example.nueiin;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class ReactWrapperPackage implements ReactPackage {
    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactApplicationContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new ReactWrapperModule(reactApplicationContext));
        
        return modules;
    }

    @NonNull
    @Override
    public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactApplicationContext) {
        return Collections.emptyList();
    }
}

// MainApplication.java

...

import com.advantapp.aiworks.rnchat.ReactWrapperPackage;	// 추가

public class MainApplication extends Application implements ReactApplication {

      ...

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new ReactWrapperPackage());	// 추가
          return packages;
        }

        ...

 
}

예시
import { NativeModules } from 'react-native';	// 추가

...

  const { ReactWrapperModule } = NativeModules;
  ReactWrapperModule.setCount(count);

...

참고

https://notifee.app/react-native/docs/android/appearance#badges
https://developer.android.com/develop/ui/views/notifications/badges?hl=ko#java

profile
풀스택 개발자

0개의 댓글