Note
최신 샘플 및 라이브러리는 아래 링크를 통해, 다운로드 받을 수 있습니다.
Morpheus 플랫폼에서 제공하는 푸시 서비스 중, UPNS 5.0 이하 버전을, UPNS 5.1로 변환하기 위한 문서이다.
Warning
google paly 정책변경으로, targetSDK26 이상 빌드 / 배포 필요
- 신규 앱 : 2018.08. 이후
- 기존 앱 : 2018.11. 이후
targetSDK 26 이상은 BackgroundService API 사용 제약으로, JobScheduler or JobDispatcher 가 적용되어야 함에 따라 5.1 마이그레이션이 필요함
가. 방법 1 (Android Studio 이용)
나. 방법 2 (모피어스 IDE 기능 이용)
가. use-permission 속성 추가
<settings>
<push>
<receiver>
<!-- 브로드캐스트 리시버에서 퍼미션 사용 여부를 설정 (Y/N) android 8.0 이상 필수 -->
<use-permission>Y</use-permission>
</receiver>
</push>
</settings>
가. GCM 속성 제거
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- for Gingerbread GSF backward compat -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="[패키지명]" />
</intent-filter>
</receiver>
<service android:name="m.client.push.library.service.GCMIntentService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name="m.client.push.library.service.GCMInstanceIDListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<permission android:name="[패키지명].permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="[패키지명].permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
나. FCM 속성 추가
<service android:name="m.client.push.library.service.FCMIntentService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Internal (not exported) receiver used by the app to start its own exported services
without risk of being spoofed. -->
<!-- FirebaseInstanceIdService performs security checks at runtime,
no need for explicit permissions despite exported="true" -->
<service android:name="m.client.push.library.service.FCMInstanceIDListenerService" android:exported="true">
<intent-filter >
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
다. UPNS 속성 [BackgroundService] 제거
<service android:name="m.client.push.library.service.UPNSService" android:exported="true" />
라. UPNS 속성 [Scheduler] 추가
<service android:name="m.client.push.library.service.UPNSJobService" android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>
<service android:name="m.client.push.library.service.UPNSConnectService"
android:exported="false"/>
마. MPUSH_PERMISSION 속성 추가
<permission android:name="${applicationId}.MPUSH_PERMISSION" android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.MPUSH_PERMISSION" />
바. FOREGROUND_SERVICE 속성 추가
<!-- 안드로이드 9.0 이상 필수 : targetSdkVersion = 28 이상인 경우 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
가. google-service.json 다운로드 방법 :
https://support.google.com/firebase/answer/7015592
https://console.firebase.google.com/u/0/
나. 적용 위치 : app/ 또는 module
모피어스 프로젝트의 경우, 프로젝트 root에 저장
dependencies 선언(적용 버전은 유동적임)
implementation 'com.google.firebase:firebase-messaging:23.0.3'
apply plugin 선언(build.gradle 최하단에 위치 해야 함)
apply plugin: 'com.google.gms.google-services'
Warning
Gradle은 예시이므로, 프로젝트 상황에 맞게 재구성 필요
buildscript {
repositories {
jcenter()
maven {url "https://maven.google.com"}
maven {url "https://jcenter.bintray.com"}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.google.gms:google-services:3.1.0'
classpath 'com.github.ksoichiro:gradle-eclipse-aar-plugin:+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.github.ksoichiro.eclipse.aar'
repositories {
jcenter()
maven {url "https://maven.google.com"}
maven {url "https://jcenter.bintray.com"}
}
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs {
srcDir 'libs'
}
}
instrumentTest.setRoot('tests')
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
defaultConfig {
multiDexEnabled true
}
dexOptions {
preDexLibraries = false
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
buildTypes {
release {
//minifyEnabled true
//proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
}
dependencies {
//구버전 중 빌드시 불 필요한 라이브러리는 exclude 처리 한다. [support-v4, gcm]
compile fileTree(dir: 'mcoreLibs', include: '*.jar', exclude: ['android-support-v4.jar', 'google-play-gcm.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
// fcm sdk (필수)
implementation ('com.google.firebase:firebase-messaging:15.0.2')
// JobScheduler sdk (필수)
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
}
apply plugin: 'com.google.gms.google-services'
Warning
Gradle 환경은 예시이므로, 프로젝트 상황에 맞게, 라이브러리 및 라이브러리 버전 재구성 필요
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
apply plugin: 'com.android.application'
repositories {
maven { url 'https://maven.google.com' }
}
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "kr.co.pushdemo"
minSdkVersion 14
targetSdkVersion 26
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
//구버전 중 빌드시 불 필요한 라이브러리는 exclude 처리 한다. [support-v4, gcm]
implementation files('libs/*.jar', exclude: ['android-support-v4.jar', 'google-play-gcm.jar'])
implementation 'com.android.support:support-v4:26.1.0'
// fcm sdk (필수)
implementation ('com.google.firebase:firebase-messaging:15.0.2')
// JobScheduler sdk (필수)
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
}
apply plugin: 'com.google.gms.google-services'
Warning
아래와 같이 Error가 발생하는 경우, dependencies 속성이 Gradle 버전과 맞지 않기 때문이므로, implementation 을 compile 로 변경한다.
Error : A problem occurred evaluating project ':app'. > Could not find method implementation() for arguments
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.push.democlient"
android:versionCode="1"
android:versionName="1.0.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- 안드로이드 8.0 이상 필수, 리시버 등록 시 권한 등록위해 선언 (필수), Manifest.xml 의 use-permission Y 선언 필요 -->
<permission android:name="com.push.democlient.permission.MPUSH_PERMISSION" android:protectionLevel="signature" />
<uses-permission android:name="com.push.democlient.permission.MPUSH_PERMISSION" />
<!-- 안드로이드 9.0 이상 필수 : targetSdkVersion = 28 이상인 경우 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.push.democlient.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="LoginActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar"></activity>
<activity android:name="SecretMessageActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar"></activity>
<activity android:name="PushMessageActivity" android:exported="true" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar"></activity>
<activity android:name="PushDetailActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar"></activity>
<activity android:name="PushListActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar"></activity>
<activity android:name="ShowPushPopup" android:taskAffinity="com.push.democlient.pushpopup" android:excludeFromRecents="true" android:launchMode="singleTask" android:windowSoftInputMode="adjustUnspecified|adjustPan" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<service
android:name="m.client.push.library.service.UPNSJobService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>
<service android:name="m.client.push.library.service.UPNSConnectService"
android:exported="false"/>
<receiver android:name="m.client.push.library.receiver.ServiceHandleReceiver">
<intent-filter>
<action android:name="com.push.democlient.START_PUSHSERVICE" />
<action android:name="com.push.democlient.STOP_PUSHSERVICE" />
<action android:name="com.push.democlient.RESTART_PUSHSERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
<service android:name="m.client.push.library.service.GCMIntentService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- FirebaseInstanceIdService performs security checks at runtime,
no need for explicit permissions despite exported="true" -->
<service android:name="com.google.firebase.iid.FirebaseInstanceIdService" android:exported="true">
<intent-filter android:priority="-500">
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<receiver android:name="com.push.democlient.receiver.MessageArrivedReceiver">
<intent-filter>
<action android:name="com.push.democlient.UPNS_MESSAGE_ARRIVED" />
<action android:name="com.push.democlient.GCM_MESSAGE_ARRIVED" />
</intent-filter>
</receiver>
<receiver android:name="m.client.push.library.receiver.GcmActionReceiver">
<intent-filter>
<action android:name="com.push.democlient.ACTION_GCM" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="m.client.push.library.receiver.UpnsActionReceiver">
<intent-filter>
<action android:name="com.push.democlient.ACTION_UPNS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<push>
<receiver>
<file-log>n</file-log>
<log>y</log>
<!-- 라이선스 발급시 별도로 부여 받기 바랍니다.-->
<security-indexes></security-indexes>
<!-- UPMC 서버 버전 -->
<version>5.0</version>
<!-- UPMC server url(필수 설정) -->
<server>http://xxx.xxx.148.97:8080</server>
<timeout>20000</timeout>
<!-- FCM설정 -->
<!-- FCM sender-id (push-type이 GCM/ FCM/ ALL일경우 필수설정) -->
<fcm-sender-id>xxxxxxx</fcm-sender-id>
<!-- 푸쉬타입(필수설정)
GCM:구글GCM / FCM(Public Push)
UPNS:유라클UPNS(Private Push) - 클라이언트 5.1 이상은 ALL 로 적용
ALL : FCM / UPNS 연동시
-->
<android-push-type>ALL</android-push-type>
<!-- 서비스 정책 ,
user : one user multidevice,
device : one user one device,
default : user -->
<policy>device</policy>
<!-- stb(셋탑)/mobile(모바일)/mobile_old(디바이스 아이디 이전 버전) -->
<device-type>mobile</device-type>
<!-- 브로드캐스트 리시버에서 퍼미션 사용 여부를 설정 (Y/N) -->
<use-permission>Y</use-permission>
</receiver>
<upns>
<!-- agent, inapp -->
<agent-service-type>inapp</agent-service-type>
<!-- UPNS RESTART ALARM INTERVAL (초단위) -->
<agent-restart-interval>120</agent-restart-interval>
<!-- auto/manual -->
<agent-receive-confirm>auto</agent-receive-confirm>
</upns>
</push>
</settings>