Android Platform 은 사용자에게 좀 더 안전한 환경을 제공하고자 단문 통신인 http 를 지양(!)하고자했습니다.

그래서, Android 6.0(M) 에서부터 AndroidManifest.xml 파일에 android:useClearTextTraffic 이란 attribute 를 제공하기 시작,

이 attribute 를 false 로 선택할 경우, App 내부에서 http 단문 통신을 하고자 할 경우, Platform 에서 트래픽을 막았습니다.

물론, 이 속성은 Api level = 28 (Android 8.0(P)) 까지 기본적으로 false 입니다.

<application android:usesCleartextTraffic="true"/>

 

이 값으로는 약간 부족하다고 생각했었는지, Android 7.0(N, 24) 에서는 android:networkSecurityConfig 라는 attribute 를 추가했습니다. 이 속성 값에는 cleartextTrafficPermitted 를 기술한 xml 파일(아래 코드 참조)을 값으로 추가할 수 있습니다. 이 xml 파일에는 이전보다는 좀 더 자세한 사항들을 기술할 수 있습니다. 예를 들어, 아래 예제처럼 도메인 단위의 http 트래픽을 허용할 것인지 아닌지를 기술할 수 있습니다.

<application
	android:networkSecurityConfig="@xml/network_security_config"/>
<?xml version="1.0" encoding="utf-8"?> 
<network-security-config> 
	<base-config cleartextTrafficPermitted="false"/> 
	<domain-config cleartextTrafficPermitted="true">         
		<domain includeSubdomains="true">develop-branch.tistory.com</domain>        
	</domain-config> 
</network-security-config>

 

 

여기서 주의할 점은 <base-config> 를 설정하지 않을 경우 기본 값을 따르며, android:useClearTextTraffic 보다 android:networkSecurityConfig 를 더 우선한다는 점입니다. 쉽게 얘기하면, android:useClearTextTraffic=false 로 지정하더라도 android:networkSecurityConfig xml 값이 지정되어 있다면, xml 에 기술된 값을 우선시 한다는 것입니다.

 

아래 표는 AndroidManifest.xml 에서 android:useClearTextTraffic=[값없음,true,false] 일 때, android:networkSecurityConfig 파일에서 cleartextTrafficPermitted=[값없음,true,false] 값에 대해 각각 NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted() 값을 보여주고 있다.

 

networkSecurityConfig :

xml 파일 지정하지 않음

networkSecurityConfig :

xml 파일 지정함

   

cleartextTrafficPermitted = 값없음

cleartextTrafficPermitted = true

cleartextTrafficPermitted = false

useClearTextTraffic = 값없음

true (Default)

true (Default)

true

false

useClearTextTraffic = true

true

true (Default)

true

false

useClearTextTraffic = false

false

true (Default)

true

false

물론, 이 값은 AndroidManifest.xml 파일에서 targetSdkVersion < 28 로 설정한 경우입니다.

targetSdkVersion >= 28 이라면, true (Default) 가 false (Default) 로 바뀝니다.

 

* 코드 상에서 이 값을 확인하는 방법은 크게 두 가지입니다.

A)

context.packageManager.getApplicationInfo("com.example").flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC

B)

NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()

 

A) 안은 일반적으로 AndroidManifest 에 기술된 값을 얻을 때 사용하는 방법이며, B) 안은 Api Level 23 에서 정의된 클래스를 이용한 것입니다.

B) 는 A) 를 포함하고 있고, 코드도 간결하기 때문에, B) 를 사용하는 것이 좋습니다.

추가로 A) 안은 API Level 23 이하에서도 사용가능한 방법이기 때문에, Build.VERSION.SDK_INT 로 제한하지 않을 경우, 오동작할 수 있습니다. 물론, 위의 내용은 일반적인 HTTP 통신인 경우(URL, UrlConnection 같은 객체를 사용하는 경우)입니다.

 

WebView 에서는 위와 조금 다르게 동작합니다. https://developer.android.com/reference/android/security/NetworkSecurityPolicy 을 참고하면, 아래와 같은 노트를 확인할 수 있습니다.

isCleartextTrafficPermitted
...
NOTE: WebView honors this flag for applications targeting API level 26 and up.

말인 즉슨,  WebView 에서는  targetSdkVersion이 26 보다 같거나 큰 경우에만, 동작한다는 것이다.

위에서 언급한 useClearTextTraffic 이나 networkSecurityConfig 값을 false 로 설정하더라도 targetSdkVersion 이 26 보다 낮을 경우, WebView 에서는 HTTP 단문 통신이 가능하다는 것이다.

 

엄밀히 말하면, 이는 Android 7.0, 24 에서 기본 적용된 Chrome WebKit 53.0 이상 버전에서 적용되는 사항입니다.

Android 6.0, 23 에서 적용된 Chrome WebKit 44.0 버전에서는 적용되지 않습니다.

즉, Android 6.0, 23, 의 기본 Chrome WebKit 44.0 을 업데이트 하지 않은 상황이라면, 어떤 설정을 적용하더라도 WebView 에서 HTTP 통신이 가능합니다.

 

종합하면 WebView 의 경우, targetSdkVersion>=26 으로 설정하고, Chrome WebKit 53.0 이상 버전을 사용한다면, (일반적으로 Android 7.0 24 이상의 단말), isCleartextTrafficPermitted 설정이 적용될 수 있습니다.

'Android' 카테고리의 다른 글

Android targetSdkVersion=30, queryIntentActivities() 문제  (0) 2022.01.10
Gson - Android Proguard 문제  (0) 2020.11.12
Android Studio - Database Inspector  (0) 2020.11.04
Android AlertDialog Style 변경  (0) 2020.08.05
Android Custom Lint  (0) 2020.07.28