최근 기획하고 있는 앱에서 푸쉬알림 기능이 필요하여 구현한 내용을 공유합니다.

Firebase Cloud Messaging 라이브러리를 이용하여 개발했으며, 샘플 앱의 전체 소스코드는 아래의 링크를 통해 확인해주세요.

https://github.com/gogoadl/android-fcm-demo

 

GitHub - gogoadl/android-fcm-demo: android firebase cloud message sample

android firebase cloud message sample. Contribute to gogoadl/android-fcm-demo development by creating an account on GitHub.

github.com

푸쉬알림이란?

푸시 알림은 사용자가 스마트폰 또는 다른 디바이스에 설치된, 브랜드 앱에서 직접 수신하는 실시간 알림 입니다. 기업은 푸시 메시지를 사용하여 현재 브랜드와 상호작용하지 않는 고객의 관심을 유도할 수 있습니다.

 

Android 앱에서는 FCM (Firebase Cloud Messaging) 라이브러리를 통해 쉽게 푸쉬알림 기능을 구현할 수 있습니다. 지금부터 FCM의 기본적인 설정과 FCM을 통해 안드로이드 앱으로 푸쉬알림을 전송하는 기능을 구현해봅니다.

Firebase 콘솔 설정

먼저Firebase 콘솔로 이동하여 프로젝트를 생성해줍니다.

로그인

 

로그인 - Google 계정

이메일 또는 휴대전화

accounts.google.com

저는 아래처럼 프로젝트 이름을 설정했습니다.

애널리틱스 설정은 기본적으로 사용 설정이 권장됩니다. 저는 이대로 계속 버튼을 눌러 진행했습니다.

Google 애널리틱스 구성 역시 기본 설정으로 구성 후 프로젝트 만들기 버튼을 선택합니다.

프로젝트가 생성된 후 아래 안드로이드 로고 이미지를 선택하여 안드로이드 앱을 추가합니다.

이후 아래와 같은 창이 보이면 Android 패키지 이름 항목에 테스트용으로 생성한 앱의 패키지명을 추가해줍니다. 패키지명을 잘 모르시겠다면 Android 프로젝트의 AndroidManifest.xml 파일의 package 속성을 사용해주시면 됩니다. 앱 닉네임과 디버그 서명 인증서는 skip 합니다.

이후 앱 등록 시 아래와 같은 화면이 나옵니다. 설명에 따라 다운로드한 파일을 앱 모듈 루트 디렉토리에 위치시켜 줍니다.

FirebaseSDK 추가도 동일하게 상세한 설명을 참고하여 세팅을 완료합니다.

 

궁금한점이나 잘못된 부분이 있다면 댓글로 알려주시면 감사하겠습니다!

 

Reference

https://firebase.google.com/docs/cloud-messaging?hl=ko

 

Firebase 클라우드 메시징

Firebase 클라우드 메시징(FCM)은 무료로 메시지를 안정적으로 전송할 수 있는 크로스 플랫폼 메시징 솔루션입니다.

firebase.google.com

https://business.adobe.com/kr/glossary/push-notifications.html

 

푸시 알림이란 무엇입니까? | Adobe 용어 설명

푸시 알림은 스마트폰 또는 다른 디바이스에 설치된 앱에서 실시간으로 제공하는 알림입니다. 자세한 내용을 살펴보십시오.

business.adobe.com

 

BroadcastReceiver ?

Android 시스템 및 기타 Android 앱에서 브로드캐스트 메시지를 보내거나 받을 수 있습니다 . 이러한 브로드캐스트는 관심 있는 이벤트가 발생할 때 전송됩니다. 예를 들어 Android 시스템은 시스템이 부팅되거나 기기가 충전을 시작하는 등 다양한 시스템 이벤트가 발생할 때 브로드캐스트를 보냅니다. 예를 들어 앱은 사용자 지정 브로드캐스트를 전송하여 다른 앱에 관심이 있을 수 있는 항목(예: 일부 새 데이터가 다운로드됨)을 알릴 수도 있습니다.

BroadcastReceiver 등록 방법

// BroadcastReceiver class
public class MyBroadcastReceiver extends BroadcastReceiver {
        private static final String TAG = "MyBroadcastReceiver";
        @Override
        public void onReceive(Context context, Intent intent) {
            StringBuilder sb = new StringBuilder();
            sb.append("Action: " + intent.getAction() + "\\n");
            sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\\n");
            String log = sb.toString();
            Log.d(TAG, log);
            Toast.makeText(context, log, Toast.LENGTH_LONG).show();
        }
    }
// activity
BroadcastReceiver br = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(APP_SPECIFIC_BROADCAST);

registerReceiver(context, br, filter);

unregisterReceiver(br);

LocalBroadcastManager

[LocalBroadcastManager.sendBroadcast](<https://developer.android.com/reference/androidx/localbroadcastmanager/content/LocalBroadcastManager#sendBroadcast(android.content.Intent)>)메서드는 발신자와 동일한 앱에 있는 수신자에게 브로드캐스트를 보냅니다. 앱 간에 브로드캐스트를 보낼 필요가 없으면 로컬 브로드캐스트를 사용하세요. 구현이 훨씬 더 효율적이며(프로세스 간 통신이 필요하지 않음) 브로드캐스트를 수신하거나 보낼 수 있는 다른 앱과 관련된 보안 문제에 대해 걱정할 필요가 없습니다.

브로드캐스트 수신기를 내보내고 장치의 다른 앱에서 볼 수 있는지 여부를 선택합니다. 이 수신기가 시스템이나 다른 앱(귀하가 소유한 다른 앱 포함)에서 보낸 브로드캐스트를 수신하는 경우 android:exported="true"

<receiver android:name=".MyBroadcastReceiver" android:exported="true">

 

Reference

https://developer.android.com/guide/components/broadcasts?hl=ko 

 

브로드캐스트 개요  |  Android 개발자  |  Android Developers

브로드캐스트 개요 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Android 앱은 Android 시스템 및 기타 Android 앱에서 게시-구독 디자인 패턴과 유사한 브로드캐

developer.android.com

 

 

Android 장치에 블루투스 마우스 장치를 연결하면 화면에 마우스 커서가 표시됩니다.

이 커서를 Android 7.0 이상부터 커서를 숨기거나, 모양을 바꿀 수 있게 되었습니다.

필자의 경우 마우스 커서를 숨기는 기능에 사용했었는데, 이때 사용한 코드를 공유합니다.

블루투스 마우스 커서의 경우 setPointerIcon 메서드를 호출한 뷰 계층에서는 마우스 커서 모양이 변경되는것으로 보이며,

시스템 UI위에서는 기본 마우스 커서가 보이게 됩니다.

아래는 제가 사용했던 코드 일부를 공유합니다.
@Override
public boolean dispatchGenericMotionEvent(MotionEvent motionEvent) {
    int index = motionEvent.getActionIndex();

    if (motionEvent.getToolType(index) == MotionEvent.TOOL_TYPE_MOUSE) {
        if (rootLayout != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            PointerIcon pointerIcon = PointerIcon.getSystemIcon(this, -1);
            rootLayout.setPointerIcon(pointerIcon);
        }
    }
    return super.dispatchGenericMotionEvent(motionEvent);
}

 

SDK 외부 배포 시 발생한 오류이며 배포한 SDK의 proguard 옵션 설정으로 오류 해결 가능하다.

 

오류의 원인은 proguard 설정에서 패키지명, 클래스명이 난독화되면서 a.a.a.... 처럼 알파벳 순서대로 패키지명이 생성된다. 이 때 내가 배포한 SDK를 사용하는 유저가 사용하는 다른 라이브러리에서도 이러한 기본 난독화 패키지명을 사용할 경우 두 SDK의 패키지명, 클래스명이 모두 a.a... 등으로 표시되면서 클래스를 찾지 못하게 된다.

 

이 때 프로가드에서 flattenpackagehierarchy 옵션을 통해 기본 패키지명 앞에 식별가능한 prefix 패키지명을 붙일 수 있다.

-flattenpackagehierarchy "com.hyeonwoo.handsome"

이 프로가드 설정은 consumer-rule이 아닌 proguard-rule에 적용해야 한다.

 

Kakao Android SDK에서 해당 설정이 적용되지 않은것을 발견해 이슈 리포트를 했으나 내부에서 이슈 파악 후 수정된 버전을 배포준비중이라고 했다. 내가 도움이 되었다면 더 기뻤겠지만, 해당 이슈를 kakao 에서도 버그로 인식하는 것으로 봐서 올바른 수정사항이라고 어느정도 확신을 가질 수 있을 것 같다.

 

https://devtalk.kakao.com/t/android-sdk-com-kakao-sdk2-11-0/124909

 

Android SDK com.kakao.sdk:v2-friend:2.11.0에서 발생가능한 문제에 대해 문의드립니다

SDK 버전 : com.kakao.sdk:v2-friend:2.11.0 SDK Proguard 설정으로인해 발생가능한 문제가 있어보여 확인 부탁드립니다. External Libraries 에서 해당 라이브러리 jar 파일을 확인해봤는데요. 패키지명이 기본적으

devtalk.kakao.com

 

개요

안드로이드 스튜디오 IDE에서 쉽게 아이콘 이미지를 얻어오는 방법을 찾아서 포스팅합니다.  

저같은 경우 주로 사용되는 픽토그램 이미지를 https://material.io/ 사이트를 자주 이용했었는데요, IDE 내에서도 쉽게 이미지 리소스를 검색하고 프로젝트에 적용할 수 있는 좋은 방법이 있습니다.

 

Material Design

Build beautiful, usable products faster. Material Design is an adaptable system—backed by open-source code—that helps teams build high quality digital experiences.

material.io

 

먼저 안드로이드 스튜디오 상단 바의 Tools > Resource Manager 탭을 선택하여 하단의 이미지와 같이 Resource Manager 탭을 띄워줍니다.

 

이후 Resource Manager 탭 하단의 + 버튼을 선택하여 Vector Asset 탭을 선택해줍니다.

선택 시 아래와 같이 Asset Studio 라는 윈도우창이 뜨게됩니다.

Asset Type : Clip Art 타입을 선택해줍니다.

Name : 아이콘 이름을 설정합니다.

Clip Art :  이미지 선택 시 아래의 Select Icon 윈도우 창이 뜨면서 필요한 이미지를 선택할 수 있습니다.

Size : 이미지의 사이즈를 조정합니다.

Color : 원하는 색상으로 이미지를 변환 할 수 있습니다.

Opacity : 이미지의 투명도를 설정할 수 있습니다.

위와 같이 아이콘을 설정 및 필요한 이미지로 가공 후 Next 버튼을 눌러줍니다. 이후 저장 위치를 확인 후 Finish 버튼을 눌러줍니다.

 

이후 아래의 이미지처럼 저장한 이미지를 불러와서 사용할 수 있습니다.

간단하게 IDE 자체적으로 제공하는 기능으로 이미지 리소스를 다운로드 하는 방법을 알아봤습니다. 

같은 안드로이드 개발자 분들께 도움이 되었으면 좋겠습니다 ^0^

 

RDP 사용 중 갑자기 연결에 실패하는 현상이 발생하여 해결 방법을 공유합니다.

먼저 해당 오류코드로 검색하여 아래의 솔루션을 수행했는데도 문제가 발생하는 경우 도움이 될 것 같습니다.

1. 제어판\시스템 및 보안\Windows Defender 방화벽\허용되는 앱 경로에서

원격 데스크톱

원격 지원

두가지 옵션을 활성화

2. 원격 데스크톱 연결 허용

 

3. 공유기 설정에서 RDP 포트포워딩

 

제 경우 내부 IP 주소가 변경되면서  등록해놓은 규칙의 IP와 현재 PC의 IP와 달라지면서 연결에 실패했었습니다. 

IP를 현재 PC와 동기화 시켜준 후 문제없이 동작하는 것을 확인했습니다.

 

AAR 라이브러리 개요

아래는 Android Developers 공식 문서에 소개된 AAR 라이브러리에 대한 설명입니다.

 

Android 라이브러리는 구조적으로 Android 앱 모듈과 동일합니다. Android 라이브러리에는 소스 코드, 리소스 파일, Android 매니페스트를 비롯하여 앱을 빌드하는 데 필요한 모든 항목이 포함될 수 있습니다.

하지만, 이 라이브러리는 기기에서 실행되는 APK로 컴파일되는 대신 Android 앱 모듈의 종속 항목으로 사용할 수 있는 Android 보관 파일(AAR)로 컴파일됩니다. JAR 파일과 달리, AAR 파일은 Android 애플리케이션에 다음과 같은 기능을 제공합니다.

 

AAR 파일에는 Android 리소스 및 매니페스트 파일이 포함될 수 있습니다. 이 파일에서는 자바 클래스 및 메서드 외에 레이아웃 및 드로어블과 같은 공유 리소스를 번들로 구성할 수 있습니다.

AAR 파일은 앱 모듈의 C/C++ 코드에서 사용할 C/C++ 라이브러리를 포함할 수 있습니다.


라이브러리 모듈은 다음과 같은 상황에 유용합니다.

활동, 서비스, UI 레이아웃 등 일부 구성요소를 동일하게 사용하는 여러 앱을 빌드하는 경우

여러 APK 변형(예: 무료 및 유료 버전)에 포함되는 앱을 빌드하며 두 버전에서 모두 동일한 핵심 구성요소가 필요한 경우

 

AAR 라이브러리는 안드로이드 개발자라면 build.gradle 파일에서 implementation (또는 api) 키워드를 통해 의존성에 포함하여 자주 사용하게 되는데, 필자가 소개하고자 하는 내용은 흔히 사용되는 오픈소스 라이브러리가 아닌 좀더 private한? 라이브러리를 구성했던 방법에 대해서 말하고자 합니다.

 

아래의 사진처럼 우리는 다양한 AAR 라이브러리를 사용하고 있습니다!

 

AAR 라이브러리 모듈 생성

  1. File > New > New Module을 클릭합니다.

  1. Create New Module 창이 표시되면 Android Library, Next를 차례로 클릭합니다.
  2. 라이브러리에 이름을 지정하고 라이브러리의 코드를 위한 최소 SDK 버전을 선택한 후 Finish를 클릭합니다.

라이브러리가 생성되었다면, build.gradle 파일을 확인해보자.

기존 어플리케이션의 경우 어플리케이션으로 표시되는 것과 달리, 라이브러리로 표시되는 것을 확인할 수 있다.

 

//  어플리케이션을 라이브러리로 변환하여 사용하고 싶은 경우, 이 값을 위의 사진처럼 라이브러리로 변경하여 사용할 수 있다.
id 'com.android.application'

 

ExoPlayer2의 PlayerControlView가 일정시간이 지난 후 사라지는 현상이 있었다.

 

원인은 매우 간단했는데, 버그로 판단해서 버전도 변경해보고 여러가지 시도를 했었다.

 

xml 파일의 PlayerControllerView에 아래의 코드를 추가시켜준 후 문제가 발생하지 않았다.

 

        app:show_timeout="0"

 

Reference : https://stackoverflow.com/questions/51579006/exoplayer-show-playercontrolview-throughout-playback-of-audio-clip

VNC와 RDP

개요

팀 회의 도중 생소한 키워드를 정리하기 위해 글을 씁니다.

VNC vs RDP

VNC (Virtual Network Computing)

VNC는 RFB(Remote Frame Buffer)프로토콜 방식을 이용해 서버에서 보낸 화면 정보를 클라이언트에 설치된 그래픽 라이브러리를 이용해 그리는 방식이다.

  • 사용을 위해 RFB를 전송 가능한 프로그램, 전달 받는 프로그램 (server, client)가 필요하다.
  • 원격에서 화면을 보는 기능만 지원하며, 클라이언트 별로 세션을 가지지 못한다. (여러 PC에서 동시에 접속한다면 하나의 화면을 공유하게 된다.)
  • VNC는 주로 클라우드 상에서 동작하는 서버 VM을 동작하기 위해서 사용하는 프로토콜이다.

RDP (Remote Desktop Protocol)

  • 마이크로소프트에서 자체적으로 개발한 프로토콜이며 VNC와 다른점은 사전 설정에 따라 클라이언트 세션을 여러개 생성가능하다는점이다.
  • 과거에는 Windows 운영체제만 지원했지만, 현재 Linux, mac, Android 등 다양한 운영체제를 지원한다.

Reference : https://selfish-developer.com/entry/VNC%EC%99%80-RDP

ICMP (Internet Control Message Protocol)

ICMP는 TCP/IP에서 IP 패킷을 처리할 때 발생되는 문제를 알려주는 프로토콜이다.
IP에는 오로지 패킷을 목적지에 도달시키기 위한 내용들로만 구성되어 있다.
따라서 정상적으로 목적지 호스트에 도달하는 경우에는 IP에서 통신이 성공하고 종료되므로 별도의 기능은 없다.

  • 통신 유무 확인시 자주 사용되는 Windows의 ping 기능도 이 ICMP를 사용한다고 한다.
  • 통신이 실패했을 떄 애러 메세지를 통해 통신에 실패하는 원인을 짐작할 수 있다.

'TIL' 카테고리의 다른 글

Jenkins Container 접속 http 경로 변경하기  (0) 2024.02.28
함수 호출 규약(Calling Convention)과 마샬링(marshalling)  (1) 2023.10.17
JavaScript ES6 문법 정리  (0) 2021.10.17
2021.09.11  (0) 2021.09.11
2021.09.09  (0) 2021.09.10

개요

회사에서 서비스 개발 중 django server의 앞단에 nginx를 두자고 회의중에 말이 나왔었는데, 이 둘의 차이점을 좀 더 명확하게 정리하고파 포스팅 합니다.
포스팅 내용은 Youtube 우아한 테크 세미나의 알리님의 Web Server vs WAS를 참고했습니다.

Web Server란? (nginx, apache ..)

웹 브라우저(클라이언트)로 부터 HTTP 요청을 받아 HTML 문서와 같은 정적인 컨텐츠를 제공하는 프로그램

정적 컨텐츠?

  • 요청 인자값에 상관없이 달라지지 않는 컨텐츠(html, css, image ..)
  • 어느 사용자 요청이든 항상 동일한 컨텐츠

Web Server의 기능

  • 클라이언트로부터 HTTP 요청을 받을 수 있다.
  • 정적 컨텐츠(html, css, image ..)를 제공할 수 있다.
  • 동적 컨텐츠 요청 시 Web Application Server로 요청을 전달할 수 있다.

Web Application Server란? (spring, django, flask ..)

DB 조회나 다양한 로직 처리를 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 프로그램

동적 컨텐츠?

  • 요청 인자에 따라 바뀔 수 있는 컨텐츠

Web Application Server의 기능

  • 클라이언트로 부터 HTTP 요청을 받을 수 있다. (* 대부분의 WAS는 Web Server 내장!!)
  • 요청에 맞는 정적 컨텐츠(html, css, image)를 제공할 수 있다.
  • DB조회나 다양한 로직 처리를 통해 동적 컨텐츠를 제공할 수 있다.

Web Server를 함께 사용하면 좋은 점은?

Web Application Server는 대부분 Web Server를 내장하고 있으므로, WAS만 활용해도 모든 요청을 처리할 수 있는게 아닐까? 라고 생각 할 수 있다.
왜 Web Server를 사용하는지 알아보자.

  1. 책임 분할을 통한 서버 부하 방지
  • 정적 컨텐츠는 Web Server, 동적 컨텐츠는 Web Application Server 에서 처리함으로서 서버의 부하를 방지 할 수 있다.
  1. 여러 대의 WAS를 로드 밸런싱
    로드 밸런싱 : 서버에 가해지는 부하를 분산 해주는 기능
  • 서버의 트래픽이 증가하여 더이상 요청을 받아들일 수 없다면 서버를 증설하여 이를 해결 할 수 있을것이다. 이 때 Web Server에서 여러 서버에 요청을 분산 시킬 수 있다.
  1. 여러 대의 WAS Health Check
  • 서버가 어떠한 오류로 인하여 요청을 받아들일 수 없는 상태가 된다면 오류가 발생한 서버로는 요청에 대해서 올바른 응답을 보내줄 수 없을 것이다. 이 때 Web Server 에서 WAS의 상태를 확인하여 오류가 발생한 WAS에는 요청을 전달하지 않도록 할 수 있다.
  1. 보안
  • 리버스 프록시 기능을 사용하여 외부에 서버의 IP를 노출시키지 않을 수 있다.

정리

서비스의 확장성, 안정성을 고려한다면 앞 단에 Web Server를 두는것이 유리할 수 있다.

+ Recent posts