투케이2K

127. (TWOK/UTIL) [Android/Java] C_FirebaseMessagingService : 파이어베이스 푸시 알림 서비스 클래스 - Firebase Push 본문

투케이2K 유틸파일

127. (TWOK/UTIL) [Android/Java] C_FirebaseMessagingService : 파이어베이스 푸시 알림 서비스 클래스 - Firebase Push

투케이2K 2024. 5. 15. 11:04
반응형

[설 명]

프로그램 : Android / Java

설 명 : C_FirebaseMessagingService : 파이어베이스 푸시 알림 서비스 클래스 - Firebase Push

 

[소스 코드]

 

package com.example.javaproject.C_Firebase;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.Log;

import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.example.javaproject.R;
import com.example.javaproject.S_FinalData;
import com.example.javaproject.S_Log;
import com.example.javaproject.S_Preference;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONObject;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class C_FirebaseMessagingService extends FirebaseMessagingService {


    /**
     * // --------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // --------------------------------------------------------------------------------------
     * 1. 파이어베이스 푸시 알림 서비스 클래스
     * // --------------------------------------------------------------------------------------
     * */





    /**
     * // --------------------------------------------------------------------------------------
     * TODO [빠른 로직 찾기 : 주석 로직 찾기]
     * // --------------------------------------------------------------------------------------
     * // [SEARCH FAST] : []
     * // --------------------------------------------------------------------------------------
     *
     * // --------------------------------------------------------------------------------------
     *
     * // --------------------------------------------------------------------------------------
     *
     * // --------------------------------------------------------------------------------------
     *
     * // --------------------------------------------------------------------------------------
     */




    // -----------------------------------------------------------------------------------------
    // TODO [서버에서 푸시알림을 보내는 형식 정의] : [레거시]
    // -----------------------------------------------------------------------------------------
    /*
    {
        "data" : {
                "title" : "Android Push Test", // [타이틀]
                "body"  : "안드로이드 푸시 테스트입니다.", // [내용]
                "sort"  : 2, // [진동, 알림 종류]
                "msgType" : 2, // [메시지 타입]
                "messageId" : "dsfe223" // [메시지 아이디]
        },
        "to":"d2fBYJVLSV6mgiyTh", // [토큰]
        "Android": { // [알림 중요도]
            "priority": "high"
        },
        "priority": 10
    }
    */
    // -----------------------------------------------------------------------------------------
    // TODO [서버에서 푸시알림을 보내는 형식 정의] : [V1]
    // -----------------------------------------------------------------------------------------
    /*
    {
        "message": {
            "token": "<기기 고유 푸시 토큰 값>",
            "notification": {
              "body": "Body of Your Notification in data",
              "title": "Title of Your Notification in data"
            }
        }
    }
    */
    // -----------------------------------------------------------------------------------------





    // -----------------------------------------------------------------------------------------
    // TODO [전역 변수 선언 부분]
    // -----------------------------------------------------------------------------------------
    private static final String ACTIVITY_NAME = "C_FirebaseMessagingService";
    private static final String TAG = C_FirebaseMessagingService.class.getSimpleName();

    String type; // [푸시 수시 받은 타입]
    String title; // [푸시 타이틀]
    String messagae; // [푸시 내용]





    // -----------------------------------------------------------------------------------------
    // TODO [파이어베이스 토큰 생성 확인]
    // -----------------------------------------------------------------------------------------
    @Override
    public void onNewToken(String s) {
        S_Log._W_(String.valueOf(ACTIVITY_NAME)+" >> onNewToken() :: 파이어베이스 푸시 알림 토큰 발급 확인", new String[]{
                String.valueOf(s)
        });

        // [프리퍼런스에 푸시 토큰 값 저장 수행 실시]
        S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_TOKEN, String.valueOf(s));
    }




    // -----------------------------------------------------------------------------------------

    // TODO [파이어베이스 푸시 알림 수신 처리 부분] : [노티피케이션 알림 표시]
    // -----------------------------------------------------------------------------------------
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        S_Log._W_(String.valueOf(ACTIVITY_NAME)+" >> onMessageReceived() :: 파이어베이스 푸시 알림 수신 확인", new String[]{
                "getFrom() :: "+String.valueOf(remoteMessage.getFrom()),
                "getData() :: "+String.valueOf(remoteMessage.getData()),
                "getNotification() :: "+String.valueOf(remoteMessage.getNotification())
        });


        // -----------------------------------------
        // [세부 수신 받은 메시지 내용 확인 실시] : [레거시 / V1 메시지 페이로드 전체 대응 파싱]
        // -----------------------------------------
        if(remoteMessage.getData() != null
                && remoteMessage.getData().isEmpty() == false
                && String.valueOf(remoteMessage.getData().get("title")) != null
                && String.valueOf(remoteMessage.getData().get("title")).length() > 0
                && String.valueOf(remoteMessage.getData().get("body")) != null
                && String.valueOf(remoteMessage.getData().get("body")).length() > 0) {

            type = "getData"; // [타입 저장]
            title = String.valueOf(remoteMessage.getData().get("title")); // [타이틀 저장]
            messagae = String.valueOf(remoteMessage.getData().get("body")); // [메시지 저장]
        }
        // -----------------------------------------
        else if(remoteMessage.getNotification() != null
                && remoteMessage.getNotification().getTitle().isEmpty() == false
                && remoteMessage.getNotification().getBody().isEmpty() == false
                && String.valueOf(remoteMessage.getNotification().getTitle()) != null
                && String.valueOf(remoteMessage.getNotification().getTitle()).length() > 0
                && String.valueOf(remoteMessage.getNotification().getBody()) != null
                && String.valueOf(remoteMessage.getNotification().getBody()).length() > 0){

            type = "getNotification"; // [타입 저장]
            title = String.valueOf(remoteMessage.getNotification().getTitle()); // [타이틀 저장]
            messagae = String.valueOf(remoteMessage.getNotification().getBody()); // [메시지 저장]
        }
        // -----------------------------------------
        else {
            type = "NONE"; // [타입 저장]
            title = ""; // [타이틀 저장]
            messagae = ""; // [메시지 저장]
        }
        // -----------------------------------------


        // -----------------------------------------
        // [오레오 버전 분기 처리]
        // -----------------------------------------
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // [오레오 버전 이상 노티피케이션 호출]

            startForegroundService();
        }
        else { // [오레오 이하 노티피케이션 호출]

            startBackgroundService();
        }
        // -----------------------------------------
    }




    // -----------------------------------------------------------------------------------------
    // TODO [오레오 버전 이상 알림 표시 처리] : [Android 8]
    // -----------------------------------------------------------------------------------------
    private void startForegroundService(){
        S_Log._W_(String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 노티피케이션 실행", new String[]{
                "type :: "+String.valueOf(type),
                "title :: "+String.valueOf(title),
                "message :: "+String.valueOf(messagae),
        });

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ // TODO [오레오 버전 이상 >> 채널 필요]

            int importance = NotificationManager.IMPORTANCE_HIGH; // [알림 중요도]
            int prior = NotificationCompat.PRIORITY_HIGH; // [알림 중요도]
            String Noti_Channel_ID = "Notification_Channel_ID"; // [알림 채널 아이디]
            String Noti_Channel_Group_ID = "Notification_Group_ID"; // [알림 채널 그룹 아이디]

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // [노티피케이션 알림 서비스 객체 생성]
            NotificationChannel notificationChannel = new NotificationChannel(Noti_Channel_ID, Noti_Channel_Group_ID, importance); // [알림 채널 설정]
            notificationChannel.setVibrationPattern(new long[]{ 0 }); // [알림 진동 발생안함 설정 > 동적으로 진동 메소드 발생 시킴]
            //notificationChannel.setVibrationPattern(new long[]{0, 300, 250, 300, 250, 300});
            notificationChannel.enableVibration(true); // [노티피케이션 진동 설정]
            //notificationChannel.setShowBadge(true); // 뱃지 카운트 실시 (디폴트 true)

            if (notificationManager.getNotificationChannel(Noti_Channel_ID) != null){ // [이미 만들어진 채널이 존재할 경우]
            }
            else {
                notificationManager.createNotificationChannel(notificationChannel); // [알림 채널 생성 실시]
            }

            notificationManager.createNotificationChannel(notificationChannel);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Noti_Channel_ID) // [NotificationCompat.Builder 객체 생성]
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.loading_bg)) // [메시지 박스에 아이콘 표시]
                    .setSmallIcon(R.drawable.white_app_default) // [타이틀 창 부분에 화이트 아이콘]
                    .setColor(ContextCompat.getColor(this, R.color.pushBgColor)) // [화이트 아이콘 색상 지정]
                    .setWhen(System.currentTimeMillis()) // [알림 표시 시간 설정]
                    .setShowWhen(true) // [푸시 알림 받은 시간 커스텀 설정 표시]
                    .setAutoCancel(true) // [알림 클릭 시 삭제 여부]
                    //.setOngoing(true) // [사용자가 알림 못지우게 설정 >> 클릭해야 메시지 읽음 상태]
                    .setPriority(prior) // [알림 중요도 설정]
                    .setContentTitle(title) // [알림 제목]
                    //.setNumber(Integer.parseInt(S_Preference.getString(getApplication(), "BadgeCount"))) // [뱃지 카운트 실시 (확인하지 않은 알림 갯수)]
                    .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL) // [뱃지 아이콘 타입 지정]
                    .setChannelId(Noti_Channel_ID) // [알림 채널 지정]

                    .setStyle(new NotificationCompat.BigTextStyle().bigText(messagae)) // TODO [다중 멀티 라인 적용 위함 : 내용이 길면 멀티라인 및 \n 개행 적용]
                    //.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmap).setSummaryText(messagae)) // TODO [사진 표시]

                    .setContentText(messagae); // [알림 내용 지정]

            builder.setContentIntent(null); // TODO [알림 개별 인텐트 적용] : [PendingIntent]
            builder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // [노티 알림 삭제 시 자동으로 푸시 뱃지 표시 지움]
            notificationManager.notify(1, builder.build()); // [아이디 값이 달라야 노티피케이션이 여러개 표시된다]
        }
    }




    // -----------------------------------------------------------------------------------------
    // TODO [오레오 버전 미만 알림 표시 처리] : [Android 7]
    // -----------------------------------------------------------------------------------------
    private void startBackgroundService(){
        S_Log._E_(String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 노티피케이션 실행", new String[]{
                "type :: "+String.valueOf(type),
                "title :: "+String.valueOf(title),
                "message :: "+String.valueOf(messagae),
        });

        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){ //TODO [오레오 버전 미만 >> 설정 실시]

            int importance = NotificationManager.IMPORTANCE_HIGH; // [알림 중요도]
            int prior = NotificationCompat.PRIORITY_HIGH; // [알림 중요도]
            String Noti_Channel_ID = "Notification_Channel_ID"; // [알림 채널 아이디]
            String Noti_Channel_Group_ID = "Notification_Group_ID"; // [알림 채널 그룹 아이디]

            NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Noti_Channel_ID) // [NotificationCompat.Builder 객체 생성]
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.loading_bg)) // [메시지 박스에 아이콘 표시]
                    .setSmallIcon(R.drawable.white_app_default) // [타이틀 창 부분에 화이트 아이콘]
                    .setColor(ContextCompat.getColor(this, R.color.pushBgColor)) // [화이트 아이콘 색상 지정]
                    .setWhen(System.currentTimeMillis()) // [알림 표시 시간 설정]
                    .setShowWhen(true) // [푸시 알림 받은 시간 커스텀 설정 표시]
                    .setAutoCancel(true) // [알림 클릭 시 삭제 여부]
                    //.setOngoing(true) // [사용자가 알림 못지우게 설정 >> 클릭해야 메시지 읽음 상태]
                    .setPriority(prior) // [알림 중요도 설정]
                    .setDefaults(Notification.DEFAULT_LIGHTS) // [알림 진동 발생안함 설정]
                    .setVibrate(new long[]{0L}) // [알림 진동 발생안함 설정]
                    .setContentTitle(title) // [알림 제목]
                    //.setNumber(Integer.parseInt(S_Preference.getString(getApplication(), "BadgeCount"))) // [뱃지 카운트 실시 (확인하지 않은 알림 갯수)]
                    .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL) // [뱃지 아이콘 타입 지정]

                    .setStyle(new NotificationCompat.BigTextStyle().bigText(messagae)) // TODO [다중 멀티 라인 적용 위함 : 내용이 길면 멀티라인 및 \n 개행 적용]
                    //.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmap).setSummaryText(messagae)) // TODO [사진 표시]

                    .setContentText(messagae); // [알림 내용 지정]

            builder.setContentIntent(null); // TODO [알림 개별 인텐트 적용] : [PendingIntent]
            builder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // [노티 알림 삭제 시 자동으로 푸시 뱃지 표시 지움]
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(1, builder.build()); // [아이디 값이 달라야 노티피케이션이 여러개 표시된다]
        }
    }


} // TODO [클래스 종료]

 

반응형
Comments