투케이2K

33. (TWOK/UTIL) [Android/Java] C_FirebaseMessagingService - 파이어베이스 푸시 토큰 및 알림 관리 본문

투케이2K 유틸파일

33. (TWOK/UTIL) [Android/Java] C_FirebaseMessagingService - 파이어베이스 푸시 토큰 및 알림 관리

투케이2K 2022. 4. 12. 11:13

[설 명]

프로그램 : Android / Java

설 명 : 파이어베이스 푸시 토큰 및 알림 관리

 

[파이어베이스 푸시 알림 처리 로직 과정]

1. 앱 아이콘 png 파일 화이트 아이콘 생성 필요

2. 파이어베이스 콘솔에서 프로젝트 생성 및 등록 필요

https://blog.naver.com/kkh0977/222416467313

 

170. (AndroidStudio/android/java) 파이어베이스 콘솔 프로젝트 추가 및 google services json 파일 추가 방법

/* ==============...

blog.naver.com

 

3. 안드로이드 프로젝트 실행 >> google services json 파일 프로젝트에 추가 실시

4. 안드로이드 build.gradle 파일에서 푸시 사용 의존성 등록 필요

- build.gradle (Project)

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.4.10'
    repositories {
        google()
        mavenCentral()
        jcenter()

        maven {
            url "https://maven.google.com"
        }

        maven { url "https://www.jitpack.io" }
    }
    dependencies {
        //classpath "com.android.tools.build:gradle:7.0.3"
        classpath "com.android.tools.build:gradle:4.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        // [파이어베이스 푸시]
        classpath 'com.google.gms:google-services:4.3.10'
    }
}



allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()

        maven {
            url "https://maven.google.com"
        }

        maven { url "https://www.jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

- build.gradle (Module)

 
// [플러그인 적용 실시]
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android'


// [프로젝트 추가 설정]
allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}


// [애플리케이션 지정 실시]
android {
    //compileSdk 31 // 컴파일 버전
    compileSdkVersion 30 // 컴파일 버전
    defaultConfig {
        // ----------------------------
        applicationId "com.test.app" // 앱 아이디
        // ----------------------------
        //minSdk 21 // 최소 빌드 버전
        //targetSdk 31 // 타겟 빌드 버전
        // ----------------------------
        minSdkVersion 21 // 최소 빌드 버전
        targetSdkVersion 30 // 타겟 빌드 버전
        // ----------------------------
        versionName "1.0.6" // TODO 앱 버전 이름 [마켓 관리]
        // ----------------------------
        versionCode 8 // 앱 버전 코드 [마켓 관리]
        // ----------------------------

        multiDexEnabled true
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // [힙 사이즈 설정 실시]
        dexOptions {
            incremental true
            javaMaxHeapSize "8g"
        }
    }



    // TODO [프로젝트 빌드 설정]
    buildTypes {
        release {
            //debuggable true
            minifyEnabled false // [true 프로가드 사용 / false 프로가드 사용안함]
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // [프로가드 설정 파일 지정]
        }
        debug {
            //debuggable true
            minifyEnabled true // [true 프로가드 사용 / false 프로가드 사용안함]
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // [프로가드 설정 파일 지정]
        }
    }


    // [컴파일 버전 명시]
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }


    testOptions {
        execution 'ANDROIDX_TEST_ORCHESTRATOR'
    }


    useLibrary ('org.apache.http.legacy')
}

dependencies {
    // [안드로이드 X 관련 의존성 부여 실시]
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"



    
    // [AppCompat implements 에러 추가]
    implementation "androidx.activity:activity-ktx:1.2.0-alpha03"
    implementation "com.android.support:multidex:2.0.1"



    // [파이어베이스 푸시]
    //implementation platform('com.google.firebase:firebase-bom:29.0.0')
    //implementation 'com.google.firebase:firebase-analytics'
    //implementation 'com.google.firebase:firebase-messaging:23.0.0'
    implementation 'com.google.firebase:firebase-messaging:20.2.0'
    implementation 'com.google.firebase:firebase-core:16.0.8'



    // [파이어베이스 리모트 최신 앱 버전 확인]
    implementation 'com.google.firebase:firebase-config:19.1.4'
    implementation 'com.google.firebase:firebase-analytics:17.4.3'
}

5. AndroidManifest.xml 파일에 파이어베이스 푸시 서비스 등록

        <!-- 메타 데이터 : 파이어베이스 푸시 : 화이트 아이콘 -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/app_icon_white" />

        <!-- 메타 데이터 : 파이어베이스 푸시 : 푸시 배경 색상 -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/customColor" />

        <!-- 서비스 : 파이어베이스 서버로부터 정상 응답을 받기 위해 : android:exported="true" -->
        <service
            android:name=".C_FirebaseMessagingService"
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

6. 파이어베이스 서비스 자바 소스 코드 작성 실시

7. 파이어베이스 콘솔에 등록 된 서버 key + http 발송 방식을 사용해 푸시 발송 테스트 수행 실시

https://blog.naver.com/kkh0977/222441002456

 

176. (AndroidStudio/android/java) Talend API Tester (http 통신 테스터) 사용해 파이어베이스 푸시 (push) 알림

[ 개발 환경 설정 ] 개발 툴 : AndroidStudio 개발 언어 : java [사전 작업 사항] [소스 코드] [Talend ...

blog.naver.com

8. 정상 발송되지 않는 경우 : 상단 Tools 메뉴 >> Firebase >> Cloud Messaging 에서 파이어베이스 연결 상태 확인

 

 


[소스 코드]

 

package com.example.testapp;

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.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. 파이어베이스 푸시 알림 리모트 서비스 클래스
     * 2. 포그라운드 및 백그라운드 푸시 알림 표시
     * 3. 포그라운드 상태에서 브로드캐스트 알림 전달
     * 4. 파이어베이스 푸시 토큰 저장 및 관리
     * 5. 푸시 알림 : 무음, 진동, 소리 제어 실시
     * // -----------------------------------------
     * */





    // TODO [빠른 로직 찾기 : 주석 로직 찾기]
    /**
     * // -----------------------------------------
     * // [SEARCH FAST] : [푸시 알림 메시지 확인]
     * // [SEARCH FAST] : [오레오 버전 분기 처리]
     * // -----------------------------------------
     */





    // TODO [서버에서 푸시알림을 보내는 형식 정의]
    /*
    {
        "data" : {
                "title" : "Android Push Test", // [타이틀]
                "body"  : "안드로이드 푸시 테스트입니다.", // [내용]
                "sort"  : 2, // [진동, 알림 종류]
                "msgType" : 2, // [메시지 타입]
                "messageId" : "dsfe223" // [메시지 아이디]
        },
        "to":"d2fBYJVLSV6mgiyTh", // [토큰]
        "Android": { // [알림 중요도]
            "priority": "high"
        },
        "priority": 10
    }
    */





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

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

    int sort = 2; // [무음, 진동, 소리 여부 설정 : 디폴트 = 소리]
    int msgType = 0; // [메시지 타입]
    String messageId = ""; // [메시지 아이디]
    int notiId = 0; // [푸시 알림 아이디 값]





    // TODO [파이어베이스 토큰 생성 확인]
    @Override
    public void onNewToken(String s) {
        Log.i("---","---");
        Log.w("//===========//","================================================");
        Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> onNewToken() :: 파이어베이스 푸시 알림 토큰 확인 실시]");
        Log.w("//===========//","================================================");
        Log.i("---","---");


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





    // TODO [파이어베이스 푸시 알림 수신 처리 부분]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        ///*
        Log.i("---","---");
        Log.d("//===========//","================================================");
        Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> onMessageReceived() :: [전체] 파이어베이스 푸시 알림 수신 확인]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[getFrom() :: "+String.valueOf(remoteMessage.getFrom())+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[getData() :: "+String.valueOf(remoteMessage.getData())+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[getNotification() :: "+String.valueOf(remoteMessage.getNotification())+"]");
        Log.d("//===========//","================================================");
        Log.i("---","---");
        // */

        // -----------------------------------------
        // [세부 수신 받은 메시지 내용 확인 실시]
        // -----------------------------------------
        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")); // [메시지 저장]


            // [알림 중요도 설정 값 받음]
            /*
            if (remoteMessage.getData().containsKey("sort")) { // [푸시 알림 설정]
                try {
                    sort = Integer.parseInt(remoteMessage.getData().get("sort"));
                }
                catch (Exception e){
                    e.printStackTrace();
                }
                // [프리퍼런스에 저장된 푸시 알림 설정 여부 확인]
                String checkPushType = S_Preference.getString(getApplication(), S_FinalData.PRE_PUSH_SORT);
                if (checkPushType != null && checkPushType.length()>0 && !checkPushType.equals("") && !checkPushType.contains("null")){ // [프리퍼런스 값이 널이 아닌 경우]
                    if (checkPushType.equals("0") || checkPushType.equals("1") || checkPushType.equals("2")){ // [정상 값을 포함한 경우]
                        try {
                            sort = Integer.parseInt(checkPushType); // [정상적인 푸시 타입이 저장된 경우 설정]
                        }
                        catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    else { // [예외 값을 포함한 경우]

                        // [프리퍼런스에 데이터 저장]
                        S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(sort));
                        S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(sort));
                    }
                }
                else { // [프리퍼런스 값이 널인 경우]

                    // [프리퍼런스에 데이터 저장]
                    S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(sort));
                    S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(sort));
                }
            }
            else {
                // [푸시 알림 : 기본 값 : 소리 + 진동]
                // [전역 변수 쪽에서 기본값 설정 지정]
            }
            // [메시지 타입 받음]
            if (remoteMessage.getData().containsKey("msgType")) { // [메시지 타입]
                try {
                    msgType = Integer.parseInt(remoteMessage.getData().get("msgType"));
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
            // [메시지 아이디 받음]
            if (remoteMessage.getData().containsKey("messageId")) { // [메시지 아이디]
                messageId = String.valueOf(remoteMessage.getData().get("messageId"));
            }
            // */
        }
        // -----------------------------------------
        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 = ""; // [메시지 저장]
            sort = 2; // [푸시 알림 설정 여부]
            msgType = 0; // [메시지 타입]
            messageId = ""; // [메시지 아이디]
        }
        // -----------------------------------------
        // [노티피케이션 푸시 알림 다중 표시 위한 아이디 값 체크 실시]
        String idCheck = String.valueOf(S_Preference.getString(getApplication(), S_FinalData.PRE_PUSH_SORT));
        if (idCheck != null && idCheck.length()>0 && !idCheck.equals("") && !idCheck.contains("null")){
            notiId = Integer.parseInt(idCheck);
            if (notiId >= 5) { // [max 아이디 값일 경우]
                notiId = 0;
            }
            notiId = notiId + 1;

            // [프리퍼런스에 푸시 아이디값 저장 실시]
            S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(notiId));
            S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(notiId));
        }
        else {
            notiId = 1;

            // [프리퍼런스에 푸시 아이디값 저장 실시]
            S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(notiId));
            S_Preference.setString(getApplication(), S_FinalData.PRE_PUSH_SORT, String.valueOf(notiId));
        }

        // -----------------------------------------
        // [SEARCH FAST] : [푸시 알림 메시지 확인]
        /*
        Log.i("---","---");
        Log.w("//===========//","================================================");
        Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> onMessageReceived() :: [파싱] 파이어베이스 푸시 알림 수신 확인]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[type :: "+String.valueOf(type)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[title :: "+String.valueOf(title)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[message :: "+String.valueOf(messagae)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[sort :: "+String.valueOf(sort)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[notiId :: "+String.valueOf(notiId)+"]");
        Log.w("//===========//","================================================");
        Log.i("---","---");
        // */
        // -----------------------------------------
        // [포그라운드 브로드 캐스트 알림으로 전달할 데이터 결합 실시]
        JSONObject sendRecive = null;
        try {
            sendRecive = new JSONObject();
            sendRecive.put("title", title); // [푸시 타이틀]
            sendRecive.put("message", messagae); // [푸시 내용]
            sendRecive.put("msgType", msgType); // [메시지 타입]
            sendRecive.put("messageId", messageId); // [메시지 아이디]
        }
        catch (Exception e){
            e.printStackTrace();
        }
        // -----------------------------------------
        // [포그라운드 브로드 캐스트 알림 전달 실시]
        /*
        try {
            if (sendRecive != null){
                Intent intent = new Intent(S_FinalData.NOTI_RECEIVE_PUSH_MESSAGE);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                intent.putExtra("message", sendRecive.toString());
                LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        // */
        // -----------------------------------------
        // [SEARCH FAST] : [오레오 버전 분기 처리]
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // [오레오 버전 이상 노티피케이션 호출]

            // [0 == 무음 / 1 == 진동 / 2 == 소리 / 3 == 진동 및 소리]
            startForegroundService(sort);
        }
        else { // [오레오 이하 노티피케이션 호출]

            // [0 == 무음 / 1 == 진동 / 2 == 소리 / 3 == 진동 및 소리]
            startBackgroundService(sort); // [진동/소리]
        }
        // -----------------------------------------
    }





    // TODO [오레오버전 이상 알림 표시 처리]
    private void startForegroundService(int flag){
        // /*
        Log.i("---","---");
        Log.w("//===========//","================================================");
        Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 노티피케이션 실행]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[title :: "+String.valueOf(title)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[message :: "+String.valueOf(messagae)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[sort :: "+String.valueOf(flag)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[notiId :: "+String.valueOf(notiId)+"]");
        Log.w("//===========//","================================================");
        Log.i("---","---");
        // */


        // -----------------------------------------
        // [노티피케이션 알림 클릭 시 인텐트 설정 정의]
        Intent intent = null;
        PendingIntent pendingIntent = null;
        ///*
        try {
            // -----------------------------------------
            // [메인 실행 중인 경우 >> 백그라운드에서 포그라운드 전환] / [메인 실행 중이 아닌 경우 >> 인트로 화면 설정]
            String checkMain = S_Preference.getString(getApplication(), S_FinalData.PRE_ROOT_ACTIVITY);
            if (checkMain != null && checkMain.length()>0 && !checkMain.equals("") && !checkMain.contains("null")) { // [실행 중인 경우]
                intent = new Intent(getApplication(), P_PushAlert.class);
                intent.putExtra("id", String.valueOf(notiId)); // [푸시 알림 화면에서 푸시 아이디 값 지우기 위해 데이터 전달]
            }
            // -----------------------------------------
            else { // [실행 중이 아닌 경우]
                intent = new Intent(getApplication(), A_Intro.class);
                intent.putExtra("id", String.valueOf(notiId)); // [푸시 알림 화면에서 푸시 아이디 값 지우기 위해 데이터 전달]
            }
            // -----------------------------------------
            // [추가 인텐트 설정 실시]
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags (Intent.FLAG_ACTIVITY_NO_ANIMATION);

            // TODO [안드로이드 타겟 31 이상 분기 처리]
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ // [타겟 31 이상]
                pendingIntent = PendingIntent.getActivity(getApplication(), 1, intent,PendingIntent.FLAG_IMMUTABLE);
            }
            else { // [타겟 31 미만]
                pendingIntent = PendingIntent.getActivity(getApplication(), 1, intent,PendingIntent.FLAG_CANCEL_CURRENT);
            }
            // -----------------------------------------
        }
        catch (Exception e){
            e.printStackTrace();
        }
        // */


        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ // TODO [오레오 버전 이상 >> 채널 필요]
            int importance; // [알림 중요도]
            int prior; // [알림 중요도]
            String Noti_Channel_ID = ""; // [알림 채널 아이디]
            String Noti_Channel_Group_ID = ""; // [알림 채널 그룹 아이디]
            // -----------------------------------------
            if (flag == 0 || flag == 1) {
                // [0 == [무음] / 1 == [진동]]
                importance = NotificationManager.IMPORTANCE_LOW; // [알림 중요도 설정 (알림음 없이 설정 >> 알림바도 내려오지 않음)]
                prior = NotificationCompat.PRIORITY_LOW;
                Noti_Channel_ID = "Low_Noti_Setting"; // [알림 채널 아이디]
                Noti_Channel_Group_ID = "Low_Group_Setting"; // [알림 채널 그룹 아이디]
            }
            // -----------------------------------------
            else {
                // [2 = [소리 / 진동]]
                importance = NotificationManager.IMPORTANCE_HIGH; // [알림 중요도 설정 (알림바 표시)]
                prior = NotificationCompat.PRIORITY_HIGH;
                Noti_Channel_ID = "Hight_Noti_Setting"; // [알림 채널 아이디]
                Noti_Channel_Group_ID = "Hight_Group_Setting"; // [알림 채널 그룹 아이디]
            }
            // -----------------------------------------
            Log.i("---","---");
            Log.w("//===========//","================================================");
            Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 채널 명칭 확인]");
            Log.i("","\n"+"--------------------------------");
            Log.i("","\n"+"[Noti_Channel_ID :: "+String.valueOf(Noti_Channel_ID)+"]");
            Log.i("","\n"+"--------------------------------");
            Log.i("","\n"+"[Noti_Channel_Group_ID :: "+String.valueOf(Noti_Channel_Group_ID)+"]");
            Log.w("//===========//","================================================");
            Log.i("---","---");

            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){ // [이미 만들어진 채널이 존재할 경우]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 채널 상태 확인]");
                Log.i("","\n"+"[상 태 :: "+"채널이 이미 존재합니다"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
            }
            else {
                Log.i("---","---");
                Log.e("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 채널 상태 확인]");
                Log.i("","\n"+"[상 태 :: "+"채널이 없어서 만듭니다"+"]");
                Log.e("//===========//","================================================");
                Log.i("---","---");
                notificationManager.createNotificationChannel(notificationChannel); // [알림 채널 생성 실시]
            }
            notificationManager.createNotificationChannel(notificationChannel);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Noti_Channel_ID) // [NotificationCompat.Builder 객체 생성]
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.app_icon)) // [메시지 박스에 아이콘 표시]
                    .setSmallIcon(R.drawable.app_icon_white) // [타이틀 창 부분에 화이트 아이콘]
                    .setColor(ContextCompat.getColor(this, R.color.customColor)) // [화이트 아이콘 색상 지정]
                    .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(pendingIntent); // TODO [알림 개별 인텐트 적용]
            builder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // [노티 알림 삭제 시 자동으로 푸시 뱃지 표시 지움]
            notificationManager.notify(notiId, builder.build()); // [아이디값이 달라야 노티피케이션이 여러개 표시된다]
            // -----------------------------------------
            if(flag == 0){ // [무음]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"무음"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
            }
            // -----------------------------------------
            else if(flag == 1){ // [진동]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
            }
            // -----------------------------------------
            else if(flag == 2){ // [소리 + 진동]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"소리 + 진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
                PushCallSound(); // [알림 소리 재생 실시]
                // [앱 소리 설정 시 자동으로 소리남] [중요도는 HIGHT]
            }
            // -----------------------------------------
            else {
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startForegroundService() :: 오레오 버전 [이상] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"기본 >> 소리 + 진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
                PushCallSound(); // [알림 소리 재생 실시]
                // [앱 소리 설정 시 자동으로 소리남] [중요도는 HIGHT]
            }
            // -----------------------------------------
        }
    }





    // TODO [오레오버전 미만 알림 표시 처리]
    private void startBackgroundService(int flag){
        // /*
        Log.i("---","---");
        Log.w("//===========//","================================================");
        Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 노티피케이션 실행]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[title :: "+String.valueOf(title)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[message :: "+String.valueOf(messagae)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[sort :: "+String.valueOf(flag)+"]");
        Log.i("","\n"+"--------------------------------");
        Log.i("","\n"+"[notiId :: "+String.valueOf(notiId)+"]");
        Log.w("//===========//","================================================");
        Log.i("---","---");
        // */


        // -----------------------------------------
        // [노티피케이션 알림 클릭 시 인텐트 설정 정의]
        Intent intent = null;
        PendingIntent pendingIntent = null;
        ///*
        try {
            // -----------------------------------------
            // [메인 실행 중인 경우 >> 백그라운드에서 포그라운드 전환] / [메인 실행 중이 아닌 경우 >> 인트로 화면 설정]
            String checkMain = S_Preference.getString(getApplication(), S_FinalData.PRE_ROOT_ACTIVITY);
            if (checkMain != null && checkMain.length()>0 && !checkMain.equals("") && !checkMain.contains("null")) { // [실행 중인 경우]
                intent = new Intent(getApplication(), P_PushAlert.class);
                intent.putExtra("id", String.valueOf(notiId)); // [푸시 알림 화면에서 푸시 아이디 값 지우기 위해 데이터 전달]
            }
            // -----------------------------------------
            else { // [실행 중이 아닌 경우]
                intent = new Intent(getApplication(), A_Intro.class);
                intent.putExtra("id", String.valueOf(notiId)); // [푸시 알림 화면에서 푸시 아이디 값 지우기 위해 데이터 전달]
            }
            // -----------------------------------------
            // [추가 인텐트 설정 실시]
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags (Intent.FLAG_ACTIVITY_NO_ANIMATION);

            // TODO [안드로이드 타겟 31 이상 분기 처리]
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ // [타겟 31 이상]
                pendingIntent = PendingIntent.getActivity(getApplication(), 1, intent,PendingIntent.FLAG_IMMUTABLE);
            }
            else { // [타겟 31 미만]
                pendingIntent = PendingIntent.getActivity(getApplication(), 1, intent,PendingIntent.FLAG_CANCEL_CURRENT);
            }
            // -----------------------------------------
        }
        catch (Exception e){
            e.printStackTrace();
        }
        // */


        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){ //TODO [오레오 버전 미만 >> 설정 실시]
            int prior; // [알림 중요도]
            String Noti_Channel_ID = ""; // [알림 채널]
            // -----------------------------------------
            if (flag == 0 || flag == 1) {
                // [0 == [무음] / 1 == [진동]]
                prior = NotificationCompat.PRIORITY_LOW;
                Noti_Channel_ID = "Low_Noti_Setting"; // [알림 채널 아이디]
            }
            // -----------------------------------------
            else {
                // [2 = [소리 / 진동]]
                prior = NotificationCompat.PRIORITY_HIGH;
                Noti_Channel_ID = "Hight_Noti_Setting"; // [알림 채널 아이디]
            }
            // -----------------------------------------
            Log.i("---","---");
            Log.w("//===========//","================================================");
            Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 채널 명칭 확인]");
            Log.i("","\n"+"[Noti_Channel_ID :: "+String.valueOf(Noti_Channel_ID)+"]");
            Log.w("//===========//","================================================");
            Log.i("---","---");

            NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), Noti_Channel_ID) // [NotificationCompat.Builder 객체 생성]
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.app_icon)) // [메시지 박스에 아이콘 표시]
                    .setSmallIcon(R.drawable.app_icon_white) // [타이틀 창 부분에 화이트 아이콘]
                    .setColor(ContextCompat.getColor(this, R.color.customColor)) // [화이트 아이콘 색상 지정]
                    .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(pendingIntent); // TODO [알림 개별 인텐트 적용]
            builder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // [노티 알림 삭제 시 자동으로 푸시 뱃지 표시 지움]
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(notiId, builder.build()); // [아이디값이 달라야 노티피케이션이 여러개 표시된다]
            // -----------------------------------------
            if(flag == 0){ // [무음]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"무음"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
            }
            // -----------------------------------------
            else if(flag == 1){ // [진동]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
            }
            // -----------------------------------------
            else if(flag == 2){ // [소리 + 진동]
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"소리 + 진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
                PushCallSound(); // [알림 소리 재생 실시]
            }
            // -----------------------------------------
            else {
                Log.i("---","---");
                Log.w("//===========//","================================================");
                Log.i("","\n"+"["+String.valueOf(ACTIVITY_NAME)+" >> startBackgroundService() :: 오레오 버전 [미만] 앱 실행 상태 확인]");
                Log.i("","\n"+"[STATE :: "+"기본 >> 소리 + 진동"+"]");
                Log.w("//===========//","================================================");
                Log.i("---","---");
                PushCallDisplay(); // [화면 강제로 깨우기 실시]
                PushCallVibrator(); // [진동 수행 실시]
                PushCallSound(); // [알림 소리 재생 실시]
            }
            // -----------------------------------------
        }
    }





    // TODO [화면 강제로 기상 실시 메소드]
    public void PushCallDisplay(){

        /**
         * // -----------------------------------------
         * [PushCallDisplay 메소드 설명]
         * // -----------------------------------------
         * 1. 모바일 디스플레이 화면 강제 기상 깨우기 수행 메소드
         * // -----------------------------------------
         * 2. 필요 퍼미션 :
         *   - <uses-permission android:name="android.permission.WAKE_LOCK"/>
         * // -----------------------------------------
         * */

        try {
            PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
            //wakelock.acquire(5000);
            wakelock.acquire(); // [화면 즉시 켜기]
            wakelock.release(); // [WakeLock 해제]
        }
        catch (Exception e){
            //e.printStackTrace();
        }
    }





    // TODO [모바일 진동 강제 발생 메소드]
    Handler mHandler = new Handler(Looper.getMainLooper());
    public void PushCallVibrator(){

        /**
         * // -----------------------------------------
         * [PushCallVibrator 메소드 설명]
         * // -----------------------------------------
         * 1. 모바일 진동 발생 수행 메소드
         * // -----------------------------------------
         * 2. 필요 퍼미션 :
         *   - <uses-permission android:name="android.permission.VIBRATE" />
         * // -----------------------------------------
         * */

        try {
            // Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
            // vibrator.vibrate(1000); // [miliSecond, 지정한 시간동안 진동]
            Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            long[] pattern = {100, 1000, 100, 1000};
            //long[] pattern = {0};
            if (mVibrator != null) {
                AudioAttributes audioAttributes = new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_ALARM) //key
                        .build();
                mVibrator.vibrate(pattern, 0, audioAttributes);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mVibrator.cancel(); // 진동 취소 실시
                    }
                }, 1000); //1초뒤 실행 (작업 예약)
            }
        }
        catch (Exception e){
            //e.printStackTrace();
        }
    }





    // TODO [모바일 알림음 강제 발생 메소드]
    public void PushCallSound(){

        /**
         * // -----------------------------------------
         * [PushCallSound 메소드 설명]
         * // -----------------------------------------
         * 1. 모바일 기본 알림음 수행 메소드
         * // -----------------------------------------
         * */

        try {
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(),defaultSoundUri);
            ringtone.play(); // [사운드 재생]
        }
        catch (Exception e){
            //e.printStackTrace();
        }
    }


} // TODO [클래스 종료]

 

반응형
Comments