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”
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); }
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
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>