ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android/Java] 푸시 서비스
    Android/Java 2021. 12. 11. 14:06
    반응형

    [모든 포스팅은 개인적 공부를 위해 작성된 글입니다]

     

    <단말로 메시지 보내는 방법 3가지>

    1. SMS 사용

    - 장점 : 간단

    - 단점 : 비용 발생

    2. 앱과 서버와의 연결을 통한 알림

    - 앱에서 서버와의 연결 만들어 둔 후 풀링

    - 백그라운드 서비스 이용해 연결 유지해야 함

    - *폴링 : 일정 시간 간격을 두고 서버와의 연결이 끊어졌는지 확인

     - 폴링의 단점 : 단말의 HW 리소스, 전원 소모 증가 

    3. 구글 푸시 서비스(FCM) 사용

    - 구글 클라우드 서버 사용해 메시지 전송 방식을 최적화한 서비스

    - 앱에서 서버로 직접 연결할 필요x

    - 단말의 내부 연결 공유하여 메시지 수신하는 방식

     

    <FCM 푸시 메시지 처리 과정>

    1. 단말은 클라우드 서버로 등록하고 고유한 등록 ID(단말 구분하기 위한 ID) 발급 받음

    2. 등록 ID는 메시지 전송을 담당할 애플리케이션 서버로 전송되어 메시지 기다림

    3. 메시지 보내기 위해 애플리케이션 서버에 전송 요청

    4. 애플리케이션 서버는 클라우드 서버에 메시지를 전송하고 클라우드 서버가 단말기로 메시지 전송

     

    <푸시 메시지 전송 위해 기억해야 할 정보>

    1. 애플리케이션 서버에 저장된 단말의 등록 ID

    2. 애플리케이션 서버에서 클라우드 서버로 접속하기 위한 인증 정보

     - 아무나 접속하여 단말로 메시지 전송하면 안되므로 애플리케이션 서버가 'API 키'라는 고유한 값 포함하여 메시지 전송

     - 개발자가 만드는 애플리케이션을 FCM 사이트에 등록해야 사용할 수 있음

     

    * 구글 푸시 메시지의 주된 목적은 1:1보다는 1:N 메시지 전송(Multicast)임

     - 보내는 쪽에서 한 번만 전송해도 클라우드 서버에서 여러 단말로 동시에 메시지 전송 가능

     

    <푸시 메시지 보내기 설명>

    1. FCM 설정 페이지에서 프로젝트 만들기

     

    2. 앱에서 푸시 서비스 사용하기 위한 설정

     - build.gradle(project)의 dependenceis에 아래 내용 추가

    classpath 'com.google.gms:google-services:4.3.5'

     

     - build.gradle(:app)의 dependencies에 아래 내용 추가

    implementation 'com.google.firebase:firebase-messaging:17.3.4'

     - build.gralde(:app)의 가장 아래에 아래 내용 추가

    apply plugin: 'com.google.gms.google-services'//푸시 알림 사용하기 위해 추가한 부분

     

      - 만약 이 과정에서 오류가 생긴다면 com.google.gms:google-services의 버전 수정 필요

     

     - 메시지 송수신은 인터넷을 사용하므로 Manifest에 인터넷 사용 권한 추가 필요

    <uses-permission android:name="android.permission.INTERNET" />

     

    3. 메시지 수신을 위한 서비스 클래스 생성

     - app -> New -> Service -> Service

    public class MessagingService extends Service {
        public MessagingService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    }

     - 생성하면 위와 같은 코드가 생성되는데 Service를 FirebaseMessagingService로 변경하고 onBind() 메서드 삭제 후 onNewToken(), onMessageReceived() 메서드 추가

    public class MessagingService extends FirebaseMessagingService {
        public MessagingService() {
        }
    
        @Override
        public void onNewToken(String token) {
            super.onNewToken(token);
        }
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            super.onMessageReceived(remoteMessage);
        }
    }

     - FirebaseMessagingService 클래스

      - 서비스 클래스의 일종

      - 푸시 메시지 전단 받는 역할(구글 클라우드 서버에서 보내는 메시지 수신 가능)

     - onNewToken() 메서드

      - 해당 앱이 Firebase 서버에 등록되었을 때 호출되는 메서드

      - 파라미터로 전달되는 토큰 == 앱의 등록 ID

     - onMessageReceived() 메서드

      - 구글 클라우드 서버에 메시지가 도착하면 자동으로 호출되는 메서드

     

     - Manifest의 Service에 intent-filter 추가 필요

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

     

    *참고*

     - 등록 ID 가져오기

    FirebaseInstanceId.getInstance().getInstanceId();

     - 등록 ID 확인된 경우 실행되는 리스너

    FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, new OnSuccessListener<InstanceIdResult>() {
        @Override
        public void onSuccess(InstanceIdResult instanceIdResult) {
    
        }
    });

    4. 메시지 수신

     - onMessageReceived 메서드의 파라미터 RemoteMessage remoteMessage

      - 상대방이 클라우드 서버를 통해 보낸 푸시 메시지 데이터 확인 가능

      - 메시지 보낼 때 Contents에 Key 지정하므로 Key 통해 메시지 확인 가능

     - 송신자 확인

    String from = remoteMessage.getFrom();

     - 메시지 데이터 확인

    Map<String, String> data = remoteMessage.getData();
    String contents = data.get("Key값");

      - getData() 메서드의 반환형이 Map이므로 Map 사용

     

    5. 수신받은 메시지 액티비티로 보내기

    private void sendToActivity(Context context, String from, String contents){
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra("from", from);
        intent.putExtra("contents", contents);
    
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|
                Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
        
        context.startActivity(intent);
    }

     - 서비스에서 액티비티 띄울 때는 Intent에 FLAG 주어야 함

     - 해당 액티비티가 이미 메모리에 만들어져 있는 경우 해당 액티비티의 onNewIntent() 메서드로 데이터가 전달됨

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    6. 메시지 전송 앱 만들기

     - 메시지 전송을 위해 Volley 라이브러리 사용할 것이므로 build.gradle(:app)의 dependencies에 에 아래 내용 추가

     *참고*

      - 네트워크 라이브러리에는 Volley 외에도 HttpURLConnection, Retrofit 등이 있으며 앱 개발에는 주로 Retrofit가 사용됨

    implementation 'com.android.volley:volley:1.1.0'

     - Volley 라이브러리

      - RequestQueue 객체에 요청 객체(Request Object) 만들어 추가하면 자동으로 메시지 전송하는 방식으로 되어 있음

      - RequestQueue 객체 초기화를 위해 onCreate 내부에 아래 코드 추가

    if(requestQueue == null){
        requestQueue = Volley.newRequestQueue(getApplicationContext());
    }

     - 전송할 데이터는 JSONObject에 추가하고 메시지 수신 받을 단말의 등록 ID는 JSONArray에 추가

    JSONObject requestData = new JSONObject();
    
    try {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("contents", contents);
        requestData.put("data", jsonObject);
        
        JSONArray idArray = new JSONArray();
        idArray.put(0, 등록 ID);
        requestData.put("id", idArray);
    }
    catch (Exception e){
        e.printStackTrace();
    }

     

    ...계속 추가 예정

    반응형

    댓글

Designed by Tistory.