APMS android SDK Guide

문서 이력관리

일자 변경 내용 작성자
2017.08.30 Studio용 User Guide 작성 임희강
2017.11.10 GCM -> FCM 으로 변경 임희강
2018.06.11 8.0 대응으로인해 apms.properties 수정 임희강
2018.07.18 8.0 대응, noti_o_badge,JobService 추가 손보광
2018.09.03 9.0 대응, MQTT 안정화 적용 손보광

첨부파일

파일명 설명
apms_sdk_base.jar APMS 라이브러리
org.eclipse.paho.client.mqttv3-1.2.0.jar Private Server 접속 라이브러리
volley_20160608.jar APMS API 호출 시 사용하는 통신 라이브러리

1. 라이브러리 적용 방법

1.1 Android Studio

  1. Android Studio 의 해당 프로젝트에서 New -> New Module 을 선택합니다.

  2. 선택후 다음과 같은 창이 뜨면 Import.JAR/.AAR Packge 를 선택한뒤 Next를 클릭합니다.

  3. 전달해드린 라이브러리(.jar) 파일들을 선택하고 Finish를 선택하여 라이브러리를 추가하여 줍니다.

  1. 완료 후 다음과 같이 생성한 파일 이름으로 Module이 생성이 되게 됩니다.

  2. File -> Project Structure 를 선택합니다.

  1. 해당 Project 선택 후 Dependencies 탭을 선택합니다.

  2. 좌측 하단에 있는 + 버튼 후 Module dependency를 선택합니다.

  3. 등록 했던 Module를 선택합니다. OK 버튼을 눌러 완료 합니다.

2. Google play service 설정

2.1 Google Play Service 설치

  1. Android SDK Manager 를 실행합니다.

  1. SDK Tools Tab에 Google Play services 를 선택하여 설치 합니다.

2.2 Google Play Service / firebase 설정

  1. File -> Project Structure 를 선택합니다.

  1. Dependencies -> + -> Library dependency 를 선택하여 다음 Library를 선택해 줍니다.

    com.google.firebase:firebase-messaging
  2. 해당 프로젝트에 있는 build.gradle 파일을 오픈해서 dependencies 부분에classpath 'com.google.gms:google-services:3.0.0'를 추가하여 중입니다.

     buildscript {
        ...
        dependencies {
             ....
            classpath 'com.google.gms:google-services:3.0.0'
        }
    }
  3. app/build.gradle 파일을 오픈해서 제일 하단에 apply plugin: 'com.google.gms.google-services를 추가합니다.

     apply plugin: 'com.google.gms.google-services'
  4. 그 후 오른쪽 상단에 뜨는 Sync Now를 클릭하여서 Build를 완료합니다.

  5. FCM을 받기위해 Firebase Console 등록시 다운로드 받았던 google-services.json 파일을 app 폴더 아래로 복사를 합니다.

3. AndroidManifest.xml 설정

3.1 Permission 추가

<!-- push -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.VIBRATE" />
<!-- push -->

<!-- network -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- network -->

<!-- push -->
<permission android:name="com.humuson.app.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.humuson.app.permission.C2D_MESSAGE" />
...

3.2 FCM receiver / service 추가


<service
    android:name="com.apms.sdk.push.GetFCMInstanceID"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

<service
    android:name="com.apms.sdk.push.FCMPushService"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

3.3 Push receiver 추가

<receiver
    android:name="com.apms.sdk.push.PushReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <action android:name="org.mosquitto.android.mqtt.MSGRECVD"/>
        <category android:name="$(project_package)"/>
    </intent-filter>
</receiver>
<receiver
    android:name="com.apms.sdk.push.PushReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <action android:name="org.mosquitto.android.mqtt.MSGRECVD"/>
        <category android:name="com.humuson.app"/>
    </intent-filter>
</receiver>

3.4 PushPopupActivity 추가

<!-- apms push popup activity -->
<activity
    android:name="${push_popup_activity}"
    android:theme="@style/push_popup_theme"
    android:excludeFromRecents="true"
    android:exported="false"
    android:screenOrientation="portrait"
    android:configChanges="orientation" />
    <!-- apms push popup activity -->
    <activity
        android:name="com.custom.push.CusomPushPopupActivity"
        android:theme="@style/push_popup_theme"
        android:excludeFromRecents="true"
        android:exported="false"
        android:screenOrientation="portrait"
        android:configChanges="orientation" />
    push_popup_activity=com.custom.push.CusomPushPopupActivity

3.5 PushNotiReceiver 추가

<!-- apms push clickNotiReceiver -->
<receiver android:name="${noti_receiver_class}" >
    <intent-filter>
        <action android:name="${noti_receiver}" />
    </intent-filter>
</receiver>
<!-- apms push clickNotiReceiver -->
    <receiver android:name="com.custom.push.CustomNotiReceiverClass" >
        <intent-filter>
            <action android:name="com.custom.push.notifiaction" />
        </intent-filter>
    </receiver>
    noti_receiver=com.custom.push.notifiaction
    noti_receiver_class=com.custom.push.CustomNotiReceiverClass

3.6 Private Server Service 추가

<!-- APMS Private RestartReceiver -->
<receiver android:name="com.apms.sdk.push.mqtt.RestartReceiver">
    <intent-filter>
        <action android:name="MQTT.START"/>
        <action android:name="MQTT.FORCE_START"/>
    </intent-filter>
</receiver>

<!-- Private PUSH Service -->
<service
    android:name="com.apms.sdk.push.mqtt.MQTTService"
    android:enabled="true"
    android:exported="true"
    android:label="PushService"
    android:process="${process_name}" />

    <!-- Private PUSH Service -->
    <service
        android:name="com.apms.sdk.push.mqtt.MQTTService"
        android:enabled="true"
        android:exported="true"
        android:label="PushService"
        android:process="com.apms.sdk.HumusonpushService" />

3.7 Data Sender service 및 receiver 추가

<!-- APMS Data Sender Service -->
<service
    android:name="com.apms.sdk.service.DataSenderService"
    android:enabled="true"
    android:exported="true"
    android:label="SenderService"
    android:process="${process_name}" />

<!-- APMS Data Sender receiver -->
<receiver android:name="com.apms.sdk.service.SenderSeviceReceiver" >
    <intent-filter>
        <action android:name="SENDER.START" />
        <action android:name="SENDER.STOP" />
    </intent-filter>
</receiver>

3.8 Notification 설정 값 추가

<meta-data android:name="APMS_NOTI_CONTENT" android:value="${noti_content}" />
 <meta-data android:name="APMS_NOTI_CONTENT" android:value="두손가락을 이용해 아래로 당겨주세요." />
 <meta-data android:name="APMS_NOTI_CONTENT" android:value="@string/finger_event" />

3.9 Notification Icon 설정 값 추가

<meta-data android:name="APMS_SET_ICON" android:resource="@drawable/${icon_file_name}" />
<meta-data android:name="APMS_SET_LARGE_ICON" android:resource="@drawable/${icon_file_name}" />

3.10 Notification Icon Backgroud Color 지정.

<meta-data android:name="APMS_NOTI_BACK" android:value="\ #000000" />

3.11 Push Alram Sound 설정 값 추가

<meta-data android:name="APMS_SET_NOTI_SOUND" android:resource="@raw/${ring_file_name}"/>

4. Style 추가

<!-- push popup theme -->
<style name="push_popup_theme" parent="android:Theme.Light">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

5. apms.properties 파일 설정

####################### APMS #######################
# APMS App Key & API Server Url Setting
# GCM발송을 위한 앱의 projectId로 GCM의 pushToken을 가져오는데 사용됩니다.
gcm_project_id=${Google_Project_Number}

# APMS Admin Web에서 앱 생성 시 발급되는 key입니다.
app_key=${App_key}

# APMS Msg-Api Url을 의미합니다.
api_server_url=${Msg_Api_Url}

# Private Server Setting
# mqtt의 사용여부를 의미합니다. ("Y":사용, "N":사용하지 않음)
mqtt_flag=${mqtt_flag}

# private server와 연동 시 필요한 server url을 의미합니다.
# 반드시 다음과 같이 protocol, url, port를 전부 입력해주셔야 합니다. (사용하지 않을시에는 공백처리)
mqtt_server_url_ssl=${mqtt_ssl_url}
mqtt_server_url_tcp=${mqtt_tcp_url}

# Android 8.0에만 적용되는 사항으로 MQTT 포그라운드 서비스 이용시간을 의미합니다. 단위는 ms로 최소 60000(1분)값을 권장합니다
mqtt_wakeup_time=60000

# private server와의 keep alive time을 의미합니다. 단위는 초(second)입니다.
# (KeepAlive Total Time : Keep alive time + Ramdom Time(2~4min))
mqtt_server_keepalive=${mqtt_keepalive}

# DEBUG MODE
# Logcat 관련 설정 입니다.
debug_tag=APMS
debug_flag=Y

# Service에 대한 로그를 파일로 저장 유무를 설정합니다.
debug_log_falg=Y

# APMS SETTING
# Push 수신시 화면 On/Off를 의미 합니다.
screen_wakeup_flag=Y

# Notification Summary 기능 사용 여부 (Android 7.0이상부터 사용 가능합니다.)
noti_group_flag=Y

# Push 수신시 화면에 보여지는 시간을 의미 합니다. (단위 : ms)
push_popup_showing_time=9999999

# Push 노출을 앱 사용중에만 노출 할 것인지(디폴트값) 아니면
# 다른앱을 사용중에만 빼고 노출 할 것인지 설정값입니다. (default = N)
push_popup_showing_flag=N

# Push수신시 동작할 class name을 의미합니다. 
(SDK에서 푸시 수신시 사용하는 PushReceiver와 다르며 사용하지 않으시려면 빈칸으로 두시면 됩니다. 직접 구현하셔야 합니다)
push_receiver_class=${push_receiver_class}

# Push수신 시 출력되는 상단의 Notification을 터치 했을 때, 동작할 intent action을 의미합니다.
noti_receiver=${noti_receiver}
# Push수신 시 출력되는 상단의 Notification을 터치 했을 때, 동작할 class name을 의미합니다.
noti_receiver_class=${noti_receiver_class}

# Push수신 시 출력될 Popup Activity의 className을 의미합니다.
# (Default Class : "com.apms.sdk.push.PushPopupActivity")
push_popup_activity=${push_popup_activity}

# Text Notification 생성시 BigText Mode 사용 여부 (사용 : Y , 미사용 : N)
big_text_mode=Y

####################### TAS #######################
# TAS API Url및 Image 파일 이름을 설정합니다.
# TAS에서 발급받은 채널키
tas_channel_key=${App_key}

# 트래킹 서버 URL
tas_server_url=https://img-amc.tason.com
tas_image_name=/amc.gif

# Android 8.0 이상에서 뱃지 카운트 자동 생성 사용 여부 (사용 : Y , 미사용 : N)
noti_o_badge=N

6. Notification Bar Touch에 대한 BroadcastReceiver 작성

6.1 CustomNotiReceiverClass

    package com.custom.push;

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;

    public class CustomNotiReceiverClass extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // notification 터치 시에 “push notiMsg:${notiMsg}” 라는 텍스트를 Toast로 출력합니다.
            Toast.makeText(contetx, "push notiMsg:" + intent.getStringExtra(APMS.KEY_NOTI_MSG),
                Toast.LENGTH_SHORT).show();
        }
    }

6.2. Push Data

intent.getStringExtra(APMS.KEY_MSG_ID) // "i" - 메세지 ID
intent.getStringExtra(APMS.KEY_NOTI_TITLE) // "notiTitle" - notification에 출력될 타이틀
intent.getStringExtra(APMS.KEY_NOTI_MSG) // "notiMsg" - notification에 출력될 메시지 내용
intent.getStringExtra(APMS.KEY_NOTI_IMG) // "notiImg" - notification에 출력될 이미지 URL
intent.getStringExtra(APMS.KEY_MSG) // "message" - (리치) 푸시 내용
intent.getStringExtra(APMS.KEY_SOUND) // "sound" - 푸시 수신 시 출력될 사운드
intent.getStringExtra(APMS.KEY_MSG_TYPE) // "t" - 메시지 타입 : H – html, T – Text, L – Link
intent.getStringExtra(APMS.KEY_POPUP_FLAG) // Popup 창을 제어하는 Flag
intent.getStringExtra(APMS.KEY_DATA) // "d" - 추가 데이터
PushMsg pushMsg = new PushMsg(intent.getExtras());
pushMsg.msgId // 메세지 ID
pushMsg.notiTitle // notification에 출력될 타이틀
pushMsg.notiMsg // notification에 출력될 메시지 내용
pushMsg.notiImg // notification에 출력될 이미지 URL
pushMsg.message // (리치) 푸시 내용
pushMsg.sound // 푸시 수신 시 출력될 사운드
pushMsg.msgType // 메시지 타입 : H – html, T – Text, L – Link
pushMsg.popupFlag // Popup 창을 뛰울지 말지 결정 Flag (Y & N)
pushMsg.data // 추가 데이터

7. Source 코드 상에서 Permission 확인 구문 추가

// Device 가 6.0 이상일 경우
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
    // 확인할 Permission 들을 추가할 ArrayList
    ArrayList<String> strArrPermission = new ArrayList<String>();
    // READ_PHONE_STATE 퍼미션이 존재 하지 않을 경우 퍼미션 추가 팝업을 띄위기 위해 ArrayList 에 추가
    int permissionCheck = ContextCompat.checkSelfPermission([context],
                            Manifest.permission.READ_PHONE_STATE);
    // 만약 해당 퍼미션이 없을 경우 ArrayList에 확인할 퍼미션을 추가합니다.
    if (permissionCheck == PackageManager.PERMISSION_DENIED) {
        CLog.i("READ_PHONE_STATE PERMISSION_DENIED");
        strArrPermission.add(Manifest.permission.READ_PHONE_STATE);
        strArrPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }
    // ACCESS_FINE_LOCATION 퍼미션이 존재 하지 않을 경우 퍼미션 추가 팝업을 띄위기 위해 ArrayList 에 추가
    permissionCheck = ContextCompat.checkSelfPermission([context],
                        Manifest.permission.ACCESS_FINE_LOCATION);
    // 만약 해당 퍼미션이 없을 경우 ArrayList에 확인할 퍼미션을 추가합니다.
    if (permissionCheck == PackageManager.PERMISSION_DENIED) {
        CLog.i("ACCESS_FINE_LOCATION PERMISSION_DENIED");
        strArrPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);
    }
    //ACCESS_COARSE_LOCATION 퍼미션이 존재 하지 않을 경우 퍼미션 추가 팝업을 띄위기 위해 ArrayList 에 추가
    permissionCheck = ContextCompat.checkSelfPermission([context],
                        Manifest.permission.ACCESS_COARSE_LOCATION);
    // 만약 해당 퍼미션이 없을 경우 ArrayList에 확인할 퍼미션을 추가합니다.
    if (permissionCheck == PackageManager.PERMISSION_DENIED) {
        CLog.i("ACCESS_COARSE_LOCATION PERMISSION_DENIED");
        strArrPermission.add(Manifest.permission.ACCESS_COARSE_LOCATION);
    }
    // ACCESS_NETWORK_STATE 퍼미션이 존재 하지 않을 경우 퍼미션 추가 팝업을 띄위기 위해 ArrayList 에 추가
    permissionCheck = ContextCompat.checkSelfPermission([context],
                        Manifest.permission.ACCESS_NETWORK_STATE);
    // 만약 해당 퍼미션이 없을 경우 ArrayList에 확인할 퍼미션을 추가합니다.
    if (permissionCheck == PackageManager.PERMISSION_DENIED) {
        CLog.i("ACCESS_NETWORK_STATE PERMISSION_DENIED");
        strArrPermission.add(Manifest.permission.ACCESS_NETWORK_STATE);
    }

    // Permission 팝업을 띄위기 위한 String array 를 만들어 퍼미션 요청을 수행합니다.
    if (strArrPermission.size() > 0) {
        String[] strPermission = new String[strArrPermission.size()];
        for (int i=0; i<strArrPermission.size(); i++) {
            strPermission[i] = strArrPermission.get(i);
        }
        ActivityCompat.requestPermissions((Activity) this, strPermission, 0);
    }
}

8. 삼성 스마트 절전 앱 대응 방안.