1. FileProvider

  • 앱에서 다른 앱으로 파일을 안전하게 제공하려면 파일에 보안 핸들을 콘텐츠 URI 형태로 제공하도록 앱을 구성해야 합니다.

적용방법

가. 아래와 같이 xml 파일 생성

프로젝트 > res > xml > mcore_provider_paths.xml

나. mcore_provider_paths.xml 에 아래 내용 추가

<?xml version="1.0" encoding="utf-8"?>
<paths>
        <external-path
            name="external"
            path="." />
        <external-files-path
            name="external_files"
            path="." />
        <cache-path
            name="cache"
            path="." />
        <external-cache-path
            name="external_cache"
            path="." />
        <files-path
            name="files"
            path="." />
        <root-path
            name="root"
            path="." />
</paths>

다. AndroidManifest.xml 에 아래와 같이 적용

support-v4 적용시

[AndroidManifest.xml] 파일에 적용

<application>

        <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                        android:name="android.support.FILE_PROVIDER_PATHS"
                        android:resource="@xml/mcore_provider_paths"/>
        </provider>
</application>

AndroidX 적용시

[AndroidManifest.xml] 파일에 적용

<application>

        <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                        android:name="android.support.FILE_PROVIDER_PATHS"
                        android:resource="@xml/mcore_provider_paths"/>
        </provider>
</application>

androidx 변환시 build.gradle 라이브러리 적용 (참고)

implementation fileTree(dir: 'mcoreLibs', include: '*.jar', excludes: ['android-support-v4.jar'])
implementation 'androidx.legacy:legacy-support-v4:1.0.0'

Note

${applicationId} 는 package name 을 의미하며, 빌드 오류시 프로젝트에서 사용하는 packageName 을 적용하면 된다. 예: android:authorities=”com.morpheus.mobile.provider”

mcore_provider_paths.xml 다운로드.

2. Proguard

MADP 적용방법

가. app module 의 gradle 파일 (build.gradle)

buildTypes {
        release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'morpheus_proguard-project.txt'
        }
}

나. 프로젝트 > morpheus_proguard-project.txt 생성

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

#To repackage classes on a single package
#-repackageclasses ''

#Uncomment if using annotations to keep them / generic type.
-keepattributes *Annotation*, EnclosingMethod, Signature

#안드로이드 support / apache / json 난독화를 진행하지 않는다.(모든 내용)
-keep class android.support.v4.** { *; }
-keep class com.google.** { *; }
-keep class org.apache.** { *; }
-keep class org.json.** { *; }
-keep class com.nhn.**{ *; }


#kakao 예외 처리
-keep class com.kakao.** { *; }
-keepattributes Signature
-keepclassmembers class * {
  public static <fields>;
  public *;
}
-dontwarn android.support.v4.**,org.slf4j.**,com.google.android.gms.**

#상기 선언된 내용에 대한 진행 중 발생하는 문제에 대해 경고하지 않는다.
-dontwarn android.support.v4.**
-dontwarn com.google.**
-dontwarn org.apache.**
-dontwarn m.client.android.library.core.bridge.**
-dontwarn m.client.android.library.core.managers.**
-dontwarn pub.devrel.easypermissions.**
-dontwarn m.client.android.library.core.control.**
-dontwarn m.client.android.library.core.utils.**
-dontwarn m.client.android.library.core.view.**
####No obfuscation
#-dontobfuscate

#morpheus push
-dontwarn m.client.push.library.**
-dontwarn mpush.eclipse.paho.**
-dontwarn mpush.eclipse.paho.client.mqttv3.internal.ssl.SecureSocketSslContextFactory

#android
-dontnote android.net.http.*
-dontnote org.apache.http.**
-dontnote org.json.**
-dontnote com.google.**


#Keep classes that are referenced on the AndroidManifest
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment



#라이센스 관련 정보가 들어가 있을때는 아래의 주석을 제거한다.
#-keep public class com.google.vending.licensing.ILicensingService
#-keep public class com.android.vending.licensing.ILicensingService

#To maintain custom components names that are used on layouts XML.
#Uncomment if having any problem with the approach below
#-keep public class custom.components.package.and.name.**

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
 -keepclassmembers public class * extends android.view.View {
  void set*(***);
  *** get*();
}

#To remove debug logs:
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** w(...);
}

#To avoid changing names of methods invoked on layout's onClick.
# Uncomment and add specific method names if using onClick on layouts
#-keepclassmembers class * {
# public void onClickButton(android.view.View);
#}

#Maintain java native methods
-keepclasseswithmembernames class * {
    native <methods>;
}

#keep android class using context
-keepclassmembers class * extends android.content.Context {
   public void *(android.view.View);
   public void *(android.view.MenuItem);
}

#To maintain custom components names that are used on layouts XML:
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

#Maintain enums
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#To keep parcelable classes (to serialize - deserialize objects to sent through Intents)
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

#Keep the R
-keepclassmembers class **.R$* {
    public static <fields>;
}

###### ADDITIONAL OPTIONS NOT USED NORMALLY

#To keep callback calls. Uncomment if using any
#http://proguard.sourceforge.net/index.html#/manual/examples.html#callback
#-keep class mypackage.MyCallbackClass {
#   void myCallbackMethod(java.lang.String);
#}

#Uncomment if using Serializable
-keepclassmembers class * implements java.io.Serializable {
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

#dynamic class loading에 관련된 클래스 들은 난독화를 진행하지 않는다.
-keep public class m.client.android.library.core.managers.WNInterfaceManager
-keep public class m.client.android.library.core.utils.ClassManager
-keep public class m.client.android.library.core.bridge.InterfaceJavascript
-keep public class m.client.android.library.core.common.MorpheusApplication

#callback 함수들을 사용하는 클래스들은 난독화를 진행하지 않는다.
-keep public class * extends m.client.android.library.core.networks.http.AsyncHttpNetwork {
        public protected *;
}

-keep public class * extends m.client.android.library.core.networks.socket.AsyncSocketNetwork {
        public protected *;
}

#native <-> script interface 함수들은 난독화 하지 않는다.
-keep public class * extends m.client.android.library.core.control.AbstractInterface {
        public protected *;
}

-keep class android.support.multidex.MultiDexApplication {
    <init>();
    void attachBaseContext(android.content.Context);
}

morpheus_proguard-project.txt 다운로드.

Plug-In QR 적용

가. morpheus_proguard-project.txt 에 아래 코드를 추가합니다.

-keep class net.sourceforge.zbar.** { *; }

PUSH 적용방법

가. app module 의 gradle 파일 (build.gradle)

buildTypes {
        release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'mpush_proguard.txt'
        }
}

나. 프로젝트 > mpush_proguard.txt 생성

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

#상기 선언된 내용에 대한 진행 중 발생하는 문제에 대해 경고하지 않는다.
-dontwarn android.support.v4.**
-dontwarn com.google.**
-dontwarn org.apache.**
-dontwarn m.client.push.library.**
-dontwarn mpush.eclipse.paho.**
-downwarn mpush.eclipse.paho.client.mqttv3.internal.ssl.SecureSocketSslContextFactory
-downwarn mpush.eclipse.paho.client.mqttv3.internal.ssl.SecureSocketSslContextFactory

#Keep classes that are referenced on the AndroidManifest
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment

mpush_proguard.txt 다운로드.

3. Apache Http Library

  • api level 28 이상부터 apache 라이브러리를 공식지원하지 않는다. 이에 apache 라이브러리를 적용하는 방법이다.

가. AndroidManifest.xml 에 아래 속성 추가

<application>
        <uses-library android:name="org.apache.http.legacy" android:required="false" />
</application>

나. build.gradle 에 useLibrary 추가

android {
        ...
        useLibrary 'org.apache.http.legacy'
}

4. Scope Storage

  • Android 10 (api level 29) 이상을 타겟팅하는 앱은 외부 저장소로 범위가 지정된 액세스 또는 범위 지정 저장소가 기본적으로 부여

가. 하위 호환성을 위해, 아래와 같이 처리한다.

<manifest ... >
        <!-- This attribute is "false" by default on apps targeting
   Android 10 or higher. -->
        <application android:requestLegacyExternalStorage="true" ... >
                ...
        </application>
</manifest>

5. MultiDex 적용하기

  • build.gradle 수정

    가. android defaultConfig 에 multiDexEnabled 를 true 로 선언

    android {
    
            defaultConfig {
                    minSdkVersion 16
                    targetSdkVersion 29
                    multiDexEnabled true
            }
    }
    

    나. dependencies 적용

    // androidx 기준 적용 시
    dependencies {
            def multidex_version = "2.0.1"
            implementation 'androidx.multidex:multidex:$multidex_version'
    }
    
    // 이전 버전
    dependencies {
            implementation 'com.android.support:multidex:1.0.3'
    }
    
  • ExtendApplication 수정

    가. attachBaseContext method 추가

    public class ExtendApplication extends MorpheusApplication {
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(this);
    
        }
    }
    

6. cleartextTrafficPermitted 오류 관련

Android의 경우, HTTPS 프로토콜만 사용하도록 되어 있으나, 라이브러리의 기능 중, HTTP 를 통한 일반 텍스트를 지원하는 기능을 사용하는 경우에 발생합니다.

가. 프로젝트 > res > xml > network_security_config.xml 파일 생성

나. 아래 코드를 생성된 파일에 적용

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">127.0.0.1</domain>
        </domain-config>
</network-security-config>

다. AndroidManifest.xml 의 application 에 networkSecurityConfig 속성 추가

<application
        android:networkSecurityConfig="@xml/network_security_config"
        ~~~ >

</application>

network_security_config.xml 다운로드.

Note

android 9 이상은, 보안상의 이유로 HTTP 통신을 차단합니다. 따라서 예외 처리를 하고자 하는 domain 은 위 포멧에서 <domain> 을 추가로 등록하여 사용합니다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">127.0.0.1</domain>
        </domain-config>
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">추가할 domain 정보 </domain>
        </domain-config>
</network-security-config>

예시 :

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">127.0.0.1</domain>
        </domain-config>
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">morpheus.co.kr</domain>
        </domain-config>
</network-security-config>

7. libMCrypt.so CPU TYPE 별 JNI 파일 다운로드

다운로드.